首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Makefile中的静态模式规则编译多个可执行文件

用Makefile中的静态模式规则编译多个可执行文件
EN

Stack Overflow用户
提问于 2022-01-28 18:45:35
回答 1查看 43关注 0票数 0

我正在用C编写一个矩阵库以供练习。为了加强良好习惯,我正在使用统一测试框架进行测试,这意味着我编译多个测试文件并运行它们。由于我不知道我将得到多少测试文件,所以我一直试图编写我的Makefile,以便在我的测试/目录中找到任何.c文件,并使用它来生成相应的可执行文件。

以下是我的项目文件结构:

代码语言:javascript
复制
├── 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:

代码语言:javascript
复制
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会这样做?我能做些什么来确保构建测试中的每个文件,以便运行每个测试?

谢谢你的帮助!--杜根

EN

回答 1

Stack Overflow用户

发布于 2022-01-28 20:23:09

您的静态模式规则似乎没有任何固有的错误。在不带参数的情况下运行make时只生成一个测试的原因是,make随后选择了一个默认目标,而不是默认规则。如果makefile中的第一个规则有多个目标,那么第一个出现的规则就是默认目标。

如果希望默认情况是生成所有测试,则插入一个新的第一条规则,将所有测试指定为先决条件:

代码语言:javascript
复制
.PHONY: all
all: $(TESTS)

顺便说一句,请注意,当多个测试由memcheck指定时,您的check$(TESTS)菜谱不会像您想要的那样工作。不是运行每个测试,而是只运行第一个测试,其他测试的名称作为命令行参数传递。也许你想要更像

代码语言:javascript
复制
.PHONY: memcheck check

memcheck:
        for t in $(TESTS); do valgrind $$t; done

check:
        for t in $(TESTS); do $$t; done
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70898775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档