如何构建具有相似名称的多个目标?

时间:2017-03-08 03:19:25

标签: c unix makefile gnu-make gnu

所以我和下面的问题完全相同,但没有人回答。

Pattern matching Makefile with multiple executable targets

我正在尝试构建一系列小测试文件,每个文件都有一个“test * .c”模式来测试我的库。

我想编写一个makefile,它可以同时为每个测试文件构建可执行文件(每个名称:test1,test2,test3..etc。)。但是,我不知道如何实现这一目标。 到目前为止我所拥有的是:

SRC := $(shell find *.c)
ALL_PROG := $(patsubst %.c, %, *.c)
.PHONY: all

all: $(ALL_PROG)

$(ALL_PROG): $(SRC)
    -gcc $< -o $@

这是一次糟糕的尝试,因为目标会将所有.c文件作为依赖项,从而导致循环依赖。

使用shell脚本可以非常轻松地完成工作,但我想知道是否有办法完成同样的工作。

提前致谢。

2 个答案:

答案 0 :(得分:1)

使用$(ALL_PROG): %: %.c代替$(ALL_PROG): $(SRC)

以下是我可能与GNU make一起使用的Makefile示例:

CC      := gcc
CFLAGS  := -Wall -O2
LDFLAGS := -lm
PROGS   := $(patsubst %.c, %, $(wildcard *.c))

.PHONY: all clean test $(patsubst %, test@%, $(PROGS))

all: $(PROGS)

clean:
    rm -f $(PROGS)

$(PROGS): %: %.c
    $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@

$(patsubst %, test@%, $(PROGS)): test@%: %
    ./$^

test: $(patsubst %, test@%, $(PROGS))

像往常一样,请注意缩进应使用 Tab 而不是空格; stackoverflow.com上使用的编辑器会自动将它们转换为空格。

PROGS变量将包含目录中所有*.c个文件的名称。

.PHONY:指令告诉Make哪些目标不引用实际文件。 $(patsubst %, test@%, $(PROGS))扩展为可执行文件名列表,每个名称前面加test@:如果目录包含文件foo.cbar.c,则会扩展为test@foo test@bar

$(PROGS): %: %.c食谱将每个.c文件编译为相应的二进制文件。

$(patsubst %, test@%, $(PROGS)): test@%: %配方为每个二进制文件创建一个测试目标。如果我们有文件foo.cbar.c,则此规则会扩展为test@foo test@bar: test@%: %。这意味着对于test@footest@bar目标,相应的test@%目标需要%二进制文件。 ./$^又扩展为./%,因此扩展为二进制名称。 (如果您不希望Make显示正在运行的命令,请使用@./$^。如果您不关心测试是否失败,请使用-./$^

如果我们testtest@foo,则test@bar食谱会扩展为foo.c bar.c;即所有可能的测试目标。

您可以运行make clean test重新编译目录中的所有.c文件,然后执行它们。

如果您只担心特定的测试计划,例如foo.c,则可以运行make test@foo,如果foo.cfoo更新,则会重新编译该程序。

答案 1 :(得分:0)

你可以做到这一点。我正在更新一个构建多个目标的简单make文件。您可以根据需要进行修改。

TEST1       = test1.exe
TEST2       = test2.exe

### Executable Program Files ###

all : $(TEST1) $(TEST2)

$(TEST1) : test1.c
    gcc -o $(TEST1) test1.c 

$(TEST2) : test2.c
    gcc -o $(TEST2) test2.c