【问题标题】:Simplification of similar commands in MakefilesMakefiles 中类似命令的简化
【发布时间】:2023-03-22 20:06:01
【问题描述】:

我有一个生成文件:

CFLAGS= -Wall -g

all: ex1.c 
    cc ex1.c -o ex1
    valgrind ./ex1
    cc ex2.c -o ex2
    valgrind ./ex2
    cc ex3.c -o ex3
    valgrind ./ex3

clean:
    rm -f ex1
    rm -f ex2
    rm -f ex3

有什么方法可以简化这一点,这样我就不必为每个文件添加 3 行(我预计大约 50 个文件),而是我可以插入一个数字,它会针对该数量的文件运行命令?所有文件都将具有相同的命名方案/^ex\d{1,}\.c/,并且都在同一个目录中。

感谢您的帮助。

【问题讨论】:

    标签: c makefile gnu-make


    【解决方案1】:

    你不一定需要循环:

    CFLAGS= -Wall -g
    
    ALL_EX=ex1 ex2 ex3
    
    all: $(ALL_EX)
    
    ex%: ex%.c
        $(CC) $(CFLAGS) $@.c -o $@
        valgrind ./$@
    
    clean: ; rm -f $(ALL_EX)
    

    要添加另一个测试,您只需将另一个 exN 添加到 ALL_EX 变量即可。

    或者,从编译中拆分 valgrind 调用:

    CFLAGS= -Wall -g
    
    ALL_EX=ex1 ex2 ex3
    TEST_EX=$(ALL_EX:ex%=test_ex%)
    
    all: $(TEST_EX)
    cmp: $(ALL_EX)
    
    ex%: ex%.c
        $(CC) $(CFLAGS) $@.c -o $@
    test_ex%: ex%
        valgrind ./$<
    
    clean: ; rm -f $(ALL_EX)
    

    这样您还可以避免重复编译 ex*.c 文件。最重要的是:通过这种方式,您可以使用 make -j 并行化编译和测试。

    【讨论】:

    • 我绝对赞成将valgrind 运行分离到一个单独的规则中,但为什么不将其作为创建真正文件的规则,例如包含 valgrind 输出的文件?或者,如果您不这样做,那么至少将test_ex% 标记为.PHONY
    • 我没有假设 OP 如何使用 make 或 valgrind。我只关注提出的问题:自动化许多文件的编译和测试。
    • 没关系,但是其配方不生成由目标名称指定的文件的目标应声明为.PHONY。这与 OP 打算如何使用 makevalgrind 无关,与为 make 定义正确语义有关。特别是,如果构建目录恰好包含与目标同名的文件,该怎么办。
    • 您的规则缺少先决条件。
    • 除非 OP 明确要求,否则我不会用平庸的挑剔来负担答案。
    猜你喜欢
    • 2015-02-08
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 2014-05-15
    相关资源
    最近更新 更多