So I have the exact same question as the one below, but no one has answered it.
Pattern matching Makefile with multiple executable targets
I am trying to build a series of small test files each have a pattern of "test*.c" to test my library.
I wanted to write a makefile that builds executables for every one of the test files all at once (each name: test1, test2, test3..etc.). However, I am not sure how to achieve that. What I have so far is the following:
SRC := $(shell find *.c)
ALL_PROG := $(patsubst %.c, %, *.c)
.PHONY: all
all: $(ALL_PROG)
$(ALL_PROG): $(SRC)
-gcc $< -o $@
This is a bad attempt because the targets take all .c files as dependency, which caused circular dependency.
Using shell script can get the job done very easily, but I am wondering if there's a way to do the same job.
Thanks in advance.
Use
$(ALL_PROG): %: %.c
instead of$(ALL_PROG): $(SRC)
.Here is an example Makefile I might use with GNU
make
:As usual, note that the indentation should use a Tab rather than spaces; the editor used here on stackoverflow.com auto-converts them to spaces.
The
PROGS
variable will contain the names of all*.c
files in the directory.The
.PHONY:
directive tells Make which targets do not refer to actual files. The$(patsubst %, test@%, $(PROGS))
expands to the list of executable names, with each name prepended withtest@
: if the directory contains filesfoo.c
andbar.c
, this expands totest@foo test@bar
.The
$(PROGS): %: %.c
recipe compiles each .c file to the corresponding binary.The
$(patsubst %, test@%, $(PROGS)): test@%: %
recipe creates a test target for each binary. If we have filesfoo.c
andbar.c
, then this rule expands totest@foo test@bar: test@%: %
. This means that for bothtest@foo
andtest@bar
targets, the correspondingtest@%
target requires the%
binary. The./$^
in turn expands to./%
, and thus the binary name. (If you don't want Make to show the command being run, use@./$^
. If you don't care if a test fails, use-./$^
.)The
test
recipe expands totest@foo
test@bar
if we havefoo.c
andbar.c
; i.e. all possible test targets.You can run
make clean test
to recompile all .c files in the directory, and execute them.If you are only worried about a specific test program, say
foo.c
, you can runmake test@foo
, which will recompile the program iffoo.c
is newer thanfoo
.You can do that. I am updating a simple make file which builds multiple targets. You can modify it as your requirement.