Reputation: 12920
I have a Makefile that looks similar to this condensed version:
.PHONY: all
CC = gcc -O3 -fPIC
SRC = $(shell find src -type f -name '*.c')
OBJ = $(addprefix build/, $(notdir $(SRC:.c=.o))
TGT = build/prog
all: $(TGT)
$(TGT): $(OBJ)
$(CC) $+ -o $@
build/%.o: src/a/%.c
$(CC) -c $+ -o $@
build/%.o: src/b/%.c
$(CC) -c $+ -o $@
build/%.o: src/c/d/%.c
$(CC) -c $+ -o $@
I would like to combine the build/%.o
rules into one rule because the real makefile has like twenty of these for various paths in the src
directory. But whatever I tried nothing works. I'm sure there must be a solution, please enlighten me how this can be done.
Upvotes: 1
Views: 211
Reputation: 12879
As stated in the comment you can make use of GNU make's vpath
directive...
.PHONY: all
CC = gcc -O3 -fPIC
SRC = $(shell find src -type f -name '*.c')
OBJ = $(addprefix build/, $(notdir $(SRC:.c=.o))
TGT = build/prog
all: $(TGT)
$(TGT): $(OBJ)
$(CC) $+ -o $@
# Use vpath to give make a colon (or space) separated list
# of directories in which to look for .c files.
#
vpath %.c src/a:src/b:src/c/d
build/%.o: %.c
$(CC) -c $+ -o $@
Since you're using find
to locate the source files you could go a step further and use the results of that find
to generate the vpath
...
.PHONY: all
CC = gcc -O3 -fPIC
SRC = $(shell find src -type f -name '*.c')
OBJ = $(addprefix build/, $(notdir $(SRC:.c=.o))
TGT = build/prog
all: $(TGT)
$(TGT): $(OBJ)
$(CC) $+ -o $@
# Use vpath to give make a colon (or space) separated list
# of directories in which to look for .c files. Make use of
# the $(SRC) variable to generate the list of paths automatically.
#
SRC_DIRS := $(sort $(dir $(SRC)))
vpath %.c $(SRC_DIRS)
build/%.o: %.c
$(CC) -c $+ -o $@
Upvotes: 2