【问题标题】:`make` without manual Makefile writing`make` 无需手动编写 Makefile
【发布时间】:2016-06-26 14:05:01
【问题描述】:

今年我将有两个人用纯 C 语言编写一个或两个项目。为了自动化编译(此外,我想使用 Atom 的构建插件)我想要一个 Makefile。

但我不太喜欢手动指定所有命令。我宁愿指定源文件和头文件(以正确的顺序),让程序为我构建其余部分。

有什么工具可以用吗?还是我应该重新考虑手动编写 Makefile?

【问题讨论】:

    标签: c makefile


    【解决方案1】:

    这应该被看作是对 Joachims 关于如何将它们串在一起的答案的补充。

    我有一个 makefile 用于或多或少的一切,它具有自动依赖发现和自动源文件发现。 虽然它可能不适合大型项目,但我发现它非常适合小型原型和程序。

    我在这里收集并评论了重要部分:

    CC:=gcc                 # Define the Compiler
    CFLAGS:=-O2 -g          # Define the Compiler Options
    SRC_DIR:=src            # Source is in this folder
    BIN_DIR:=bin            # objects will be places in this folder
    
    # Discover all C files
    SRC:=$(shell find $(SRC_DIR) -type f -name *.c)
    # Every C file is compiled into one object file
    OBJ:=$(addprefix bin/,$(notdir $(patsubst %.c,%.o,$(C_SRC))))
    # Every C file creates a dependency file
    DEP:=$(patsubst %.c,%.d,$(C_SRC)
    
    # Include the dependencies
    -include $(DEP)
    
    all: executable
    
    # Bind all objects into the executable
    executable: $(OBJ)
            $(CC) $^ -o executable
    
    # Recipe to create the dependencie files from the source files
    .d: %.c
            $(CC) -MM -MT"$(BIN_DIR)/$(notdir $(<:.c=.o))" -MF "$@" "$<"
    
    # Recipe to do the compilation
    $(C_OBJ):bin/%.o:
            -$(STYLEC) $^
            $(CC) $(CFLAGS) -c -o $@ $<
    

    这将从 src/ 文件夹中获取所有源文件,使用 gcc 生成依赖项,然后进行正确的编译/绑定。

    【讨论】:

    • 我猜你在OBJ := 行中缺少BIN_DIR。你硬编码了bin。此外,依赖关系是什么?我从来没有遇到过他们。 $&lt; 是什么?
    • 依赖是GCC通过-MM生成的。它们是通过检查 C 源代码中的包含指令生成的。对于每个 .c 文件,GCC 将创建一个合适的 .d 文件,并且由于我们找到了所有源文件,我们知道我们可以期望和包含哪些依赖文件。
    • $gnu.org/software/make/manual/html_node/Automatic-Variables.html 感谢您对硬编码 bin 的提醒。
    • 是的,但是依赖文件是干什么用的?
    • 我个人觉得自己指定依赖关系非常乏味。如果我有一个包含头文件 a.h、b.h 和 c.h 的 c 文件 test.c,则在 Makefile 中表达这种关系的手动方式是“test.o: test.c a.h b.h c.h”。每当您包含新的头文件或新的 c 文件时,都必须更新它。这个 Makefile 为您自动执行此过程,您只需要指定二进制文件中应将哪些对象链接在一起。
    【解决方案2】:

    make 有许多隐式规则,它们可以从 C 源文件创建目标文件,而无需您编写任何命令。您真正需要做的就是列出程序所需的目标文件。

    例如,假设您需要源文件a.cb.c,并且您要创建程序p,那么您所需要的就是

    p : a.o b.o
        $(CC) $^ -o $@
    

    $(CC)是用于C编译器前端程序的变量,也用于链接。 make 为您创建此文件,通常为 cc

    $^ 是规则的所有必备条件的列表,在本例中为 a.o b.o

    $@ 是规则目标的名称,在本例中为 p

    使用这个非常简单的 makefile,make 会将 C 源代码编译为目标文件,然后使用提供的规则将目标文件链接到可执行程序中。


    您可以从上面的 makefile 开始自定义,例如通过设置 CC 变量告诉 make 显式使用 gcc 而不是 cc。或者通过创建和设置CFLAGS 变量来设置特殊的编译器标志。将目标添加到“清理”(通常删除程序和目标文件)。还有更多。

    我建议您了解make 和makefile,为此您应该阅读the GNU make online manual,然后再继续其他构建系统。

    GNU build system 仍然很常见,但它最近一直在失地,主要是 CMake(我个人喜欢),但还有许多其他构建系统。有些(如 CMake)可用于生成 makefile,而另一些则是 make 的直接替代品。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多