hochl
hochl

Reputation: 12920

Compile C source files from tree into build directory with make

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

Answers (1)

G.M.
G.M.

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

Related Questions