我正在用C编写一个矩阵库以供练习。为了加强良好习惯,我正在使用统一测试框架进行测试,这意味着我编译多个测试文件并运行它们。由于我不知道我将得到多少测试文件,所以我一直试图编写我的Makefile,以便在我的测试/目录中找到任何.c文件,并使用它来生成相应的可执行文件。
以下是我的项目文件结构:
├── bin
├── include
| ├── fml.h
├── src
| ├── fml.c
├── test-framework
| ├── unity.c
| ├── unity.h
| ├── unity_internals.h
├── tests
| ├── check_fml_at.c
| ├── check_fml_set_at.c
| ├── check_fml_mem_management.c
├── Makefile
├── Readme这是我一直在挣扎的Makefile:
BIN_DIR = bin
SRC_DIR = src
TESTS_DIR = tests
FML = $(BIN_DIR)/fml.o
TEST_FRAMEWORK = $(BIN_DIR)/unity.o
CFLAGS = -Wall -Werror -g
CC = gcc
TESTS = $(patsubst %.c, %, $(patsubst $(TESTS_DIR)/%, \
$(BIN_DIR)/%, $(wildcard $(TESTS_DIR)/*.c)))
$(info $$var is [${TESTS}])
$(TESTS): $(BIN_DIR)/%: $(TESTS_DIR)/%.c $(FML) $(TEST_FRAMEWORK)
$(CC) $(CFLAGS) $^ -o $@ -Iinclude -Itest-framework
$(FML): src/fml.c include/fml.h
$(CC) $(CFLAGS) -c $< -o $@ -Iinclude
$(TEST_FRAMEWORK): test-framework/unity.c test-framework/unity.h test-framework/unity_internals.h
$(CC) $(CFLAGS) -c $< -o $@
memcheck:
valgrind $(TESTS)
check:
$(TESTS)
clean:
rm $(TESTS) $(OBJS)每个测试文件都需要库(fml)和测试框架(统一)。
运行make时,预期的行为是check_fml_at、check_fml_set_at和check_fml_mem_management在bin/文件中显示为可执行文件,以及fml.o和unity.o库。我已经检查并正确地计算了测试变量为check_fml_at、check_fml_set_at和check_fml_mem_management。但是由于某种原因,只构建了第一个测试,当我运行make时,我只在bin dir中看到check_fml_at以及fml.o和unity.o。
为什么makefile会这样做?我能做些什么来确保构建测试中的每个文件,以便运行每个测试?
谢谢你的帮助!--杜根
发布于 2022-01-28 20:23:09
您的静态模式规则似乎没有任何固有的错误。在不带参数的情况下运行make时只生成一个测试的原因是,make随后选择了一个默认目标,而不是默认规则。如果makefile中的第一个规则有多个目标,那么第一个出现的规则就是默认目标。
如果希望默认情况是生成所有测试,则插入一个新的第一条规则,将所有测试指定为先决条件:
.PHONY: all
all: $(TESTS)顺便说一句,请注意,当多个测试由memcheck指定时,您的check和$(TESTS)菜谱不会像您想要的那样工作。不是运行每个测试,而是只运行第一个测试,其他测试的名称作为命令行参数传递。也许你想要更像
.PHONY: memcheck check
memcheck:
for t in $(TESTS); do valgrind $$t; done
check:
for t in $(TESTS); do $$t; donehttps://stackoverflow.com/questions/70898775
复制相似问题