如何建立多个具有相似名称的目标? [英] How to build multiple targets with similar name?
问题描述
所以我有一个与下面的问题完全相同的问题,但是没有人回答.
So I have the exact same question as the one below, but no one has answered it.
我正在尝试构建一系列小的测试文件,每个文件都有一个"test * .c"模式来测试我的库.
I am trying to build a series of small test files each have a pattern of "test*.c" to test my library.
我想编写一个makefile,一次为每个测试文件(每个名称:test1,test2,test3..etc.)构建可执行文件.但是,我不确定如何实现这一目标. 到目前为止,我有以下内容:
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 $@
这是一个错误的尝试,因为目标将所有.c文件都作为依赖项,从而导致了循环依赖.
This is a bad attempt because the targets take all .c files as dependency, which caused circular dependency.
使用shell脚本可以很容易地完成这项工作,但是我想知道是否有一种方法可以完成相同的工作.
Using shell script can get the job done very easily, but I am wondering if there's a way to do the same job.
谢谢.
推荐答案
使用$(ALL_PROG): %: %.c
代替$(ALL_PROG): $(SRC)
.
这是我可以与GNU make
一起使用的示例Makefile:
Here is an example Makefile I might use with GNU make
:
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上使用的编辑器会将它们自动转换为空格.
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.
PROGS
变量将包含目录中所有*.c
文件的名称.
The PROGS
variable will contain the names of all *.c
files in the directory.
.PHONY:
指令告诉Make哪些目标未引用实际文件. $(patsubst %, test@%, $(PROGS))
扩展到可执行文件名称列表,每个名称以test@
开头:如果目录包含文件foo.c
和bar.c
,则扩展为test@foo test@bar
.
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 with test@
: if the directory contains files foo.c
and bar.c
, this expands to test@foo test@bar
.
$(PROGS): %: %.c
配方将每个.c文件编译为相应的二进制文件.
The $(PROGS): %: %.c
recipe compiles each .c file to the corresponding binary.
$(patsubst %, test@%, $(PROGS)): test@%: %
配方为每个二进制文件创建一个测试目标.如果我们有文件foo.c
和bar.c
,则此规则扩展为test@foo test@bar: test@%: %
.这意味着对于test@foo
和test@bar
目标,相应的test@%
目标都需要%
二进制文件. ./$^
依次扩展为./%
,从而扩展为二进制名称. (如果您不希望Make显示正在运行的命令,请使用@./$^
.如果您不关心测试是否失败,请使用-./$^
.)
The $(patsubst %, test@%, $(PROGS)): test@%: %
recipe creates a test target for each binary. If we have files foo.c
and bar.c
, then this rule expands to test@foo test@bar: test@%: %
. This means that for both test@foo
and test@bar
targets, the corresponding test@%
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 -./$^
.)
如果我们有foo.c
和bar.c
,则test
配方将扩展为test@foo
test@bar
;即所有可能的测试目标.
The test
recipe expands to test@foo
test@bar
if we have foo.c
and bar.c
; i.e. all possible test targets.
您可以运行make clean test
重新编译目录中的所有.c文件,然后执行它们.
You can run make clean test
to recompile all .c files in the directory, and execute them.
如果您只担心特定的测试程序(例如foo.c
),则可以运行make test@foo
,如果foo.c
比foo
更新,它将重新编译该程序.
If you are only worried about a specific test program, say foo.c
, you can run make test@foo
, which will recompile the program if foo.c
is newer than foo
.
这篇关于如何建立多个具有相似名称的目标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!