【发布时间】:2016-06-26 14:05:01
【问题描述】:
今年我将有两个人用纯 C 语言编写一个或两个项目。为了自动化编译(此外,我想使用 Atom 的构建插件)我想要一个 Makefile。
但我不太喜欢手动指定所有命令。我宁愿指定源文件和头文件(以正确的顺序),让程序为我构建其余部分。
有什么工具可以用吗?还是我应该重新考虑手动编写 Makefile?
【问题讨论】:
今年我将有两个人用纯 C 语言编写一个或两个项目。为了自动化编译(此外,我想使用 Atom 的构建插件)我想要一个 Makefile。
但我不太喜欢手动指定所有命令。我宁愿指定源文件和头文件(以正确的顺序),让程序为我构建其余部分。
有什么工具可以用吗?还是我应该重新考虑手动编写 Makefile?
【问题讨论】:
这应该被看作是对 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。此外,依赖关系是什么?我从来没有遇到过他们。 $< 是什么?
make 有许多隐式规则,它们可以从 C 源文件创建目标文件,而无需您编写任何命令。您真正需要做的就是列出程序所需的目标文件。
例如,假设您需要源文件a.c 和b.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 的直接替代品。
【讨论】: