我在目录中有更简单的C模块。我想在子目录test/
中编写这些单元测试。这些单元测试只不过是链接到被测模块的C程序,位于上面的一个目录中。我想要一个Makefile
来定义多个构建目标,并让我可以一步或单独构建和运行测试可执行文件。
我尝试了以下操作:
CC = gcc
CFLAGS = -ggdb -Wall -Wextra -Werror -O3 -std=c99
PARAM_LIST_TARGET = parameter_list_test
PARAM_LIST_SOURCE_FILES = \
../parameter_list.c \
parameter_list_test.c
PARAM_LIST_OBJECT_FILES := $(addsuffix .o,$(basename $(PARAM_LIST_SOURCE_FILES)))
TARGETS = $(PARAM_LIST_TARGET)
all: $(TARGETS)
$(%_TARGET): $(%_OBJECT_FILES)
$(CC) $(CFLAGS) $^ -o $@
.c.o:
$(CC) -c $< -o $@ $(CFLAGS)
clean:
$(RM) *.o $(TARGETS)
test: all
@for t in $(TARGETS) ; do ./$$t ; done
这是行不通的,这是因为有$(%_TARGET):
行。并不奇怪,我没想到它会起作用,但是我希望这可以说明我正在尝试实现的目标。
我想创建更多_TARGET
,_SOURCE_FILES
和_OBJECT_FILES
形式的块,以测试PARAM_LIST
之外的其他模块,例如:
PARAM_LIST_TARGET = parameter_list_test
PARAM_LIST_SOURCE_FILES = \
../parameter_list.c \
parameter_list_test.c
PARAM_LIST_OBJECT_FILES := $(addsuffix .o,$(basename $(PARAM_LIST_SOURCE_FILES)))
OTHER_MODULE_TARGET = other_module_test
OTHER_MODULE_SOURCE_FILES = \
../other_module.c \
other_module_test.c
OTHER_MODULE_OBJECT_FILES := $(addsuffix .o,$(basename $(OTHER_MODULE_SOURCE_FILES)))
我知道%
适用于文件名,因此尝试在变量上使用它会失败:
$(%_TARGET): $(%_OBJECT_FILES)
$(CC) $(CFLAGS) $^ -o $@
如何编写一个规则,将Makefile变量_TARGET
与其关联的_OBJECT_FILES
匹配,而不为每个测试目标创建一个规则?
或更重要的是,我应该怎么做呢?
编辑:我见过this,但似乎每个可执行文件只能使用一个源文件。
答案 0 :(得分:1)
您始终可以通过构造变量名称来访问make
:
MY_VAR := "my var"
HIS_VAR := "his var"
HER_VAR := "her var"
CATS_VAR := "cats var"
DOGS_VAR := "dogs var"
ALL_PERSONS := MY HIS HER CATS DOGS
ALL_VARS := $(foreach p,$(ALL_PERSONS),$($(p)_VAR))
$(info $(ALL_VARS))
输出:
$ make
"my var" "his var" "her var" "cats var" "dogs var"
答案 1 :(得分:0)
感谢this answer:单独定义依赖项似乎行得通:
TARGETS = $(PARAM_LIST_TARGET) $(OTHER_MODULE_TARGET)
all: $(TARGETS)
$(PARAM_LIST_TARGET): $(PARAM_LIST_OBJECT_FILES)
$(OTHER_MODULE_TARGET): $(OTHER_MODULE_OBJECT_FILES)
$(TARGETS):
$(CC) $(CFLAGS) $^ -o $@
这消除了重复规则的需求(每个目标一个)。仍然,每个目标的依赖关系定义看起来都像重复项,对它们的模式匹配会很好。
除此之外,OBJECT_FILES
变量变得不必要。这有效:
PARAM_LIST_TARGET = parameter_list_test
PARAM_LIST_SOURCE_FILES = \
../parameter_list.c \
parameter_list_test.c
$(PARAM_LIST_TARGET): $(addsuffix .o,$(basename $(PARAM_LIST_SOURCE_FILES))) # The dependencies directly
将最后一行作为所有目标的一条规则仍然感觉很好。像“对于以TARGET结尾的所有变量,建立对具有相同名称但以SOURCE_FILES结尾的变量内容的依赖”。