我有一个项目,其中包含许多位于不同文件夹位置的源文件。出于某种原因,我的 Makefile 可以执行以下操作之一,但不能同时执行这两项操作(这是我真正想要的):-
1) 将所有文件编译到一个单独的目录
2) 执行一次编译,gcc 只需要调用一次,因为这大大减少了编译时间。
这是实现选项 1 的代码片段:-
INCLDDIRS := "The needed include directories"
CFLAGS = "some c flags"
C_SOURCE = "Many many source files in different directories"
C_SOURCE_NAMES = $(notdir $(C_SOURCE))
OBJECT_DIRECTORY = ObjDir
C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_NAMES:.c=.o) )
all: $(OBJECT_DIRECTORY) $(C_OBJECTS)
$(OBJECT_DIRECTORY):
mkdir ObjDir
$(OBJECT_DIRECTORY)/%.o:%.c
$(CC) $(CFLAGS) $(INCLDDIRS) -c -o $@ $<
出于某种原因,上面的代码单独编译每个 c 源文件并生成一个目标文件(即为所有源文件调用 gcc)。这不是我想要的。但是,至少所有生成的文件都位于 ObjDir
这是实现选项 2 的代码片段:-
INCLDDIRS := "The needed iclude directories"
CFLAGS = "some c flags"
C_SOURCE = "Many many source files in different directories"
C_SOURCE_NAMES = $(notdir $(C_SOURCE))
OBJECT_DIRECTORY = ObjDir
C_OBJECTS = $(OBJECT_DIRECTORY)/*.o
all: $(OBJECT_DIRECTORY) $(C_OBJECTS)
$(OBJECT_DIRECTORY):
mkdir ObjDir
$(C_OBJECTS): (C_SOURCE)
$(CC) $(CFLAGS) $(INCLDDIRS) -c $(C_SOURCE)
对于上面的代码片段,所有文件都被编译一次(即 gcc 只被调用一次)但是目标文件是在与 Makefile 相同的位置生成的,而不是在一个单独的目录中。我不想在文件生成后对文件进行 mv,因为这不是更干净的解决方案。
我的问题是: 我必须对我的 Makefile 做些什么才能执行一次编译并将目标文件生成到一个单独的目录中?
最佳答案
您想要的 makefile 看起来像这样。
INCLDDIRS := "The needed include directories"
CFLAGS = "some c flags"
C_SOURCE = "Many many source files in different directories"
C_SOURCE_NAMES = $(notdir $(C_SOURCE))
OBJECT_DIRECTORY = ObjDir
BINARY := your_binary
all: $(BINARY)
$(OBJECT_DIRECTORY):
mkdir $@
$(OBJECT_DIRECTORY/$(BINARY): $(C_SOURCE) | $(OBJECT_DIRECTORY)
$(CC) $(CFLAGS) $(INCLDDIRS) -o $@ $^
它使用 order-only prerequisite对于输出目录(所以 make 知道先创建它但不将其视为导致重建)。
它将源文件列为输出二进制文件的先决条件,并在编译行上全部使用它们。
这个 makefile 和您的目标的主要问题是,对任何 源文件的更改将导致每个 源文件从头开始重新编译。就增量工作而言,这是相当低效的。 (这就是为什么默认的想法是使用中间对象文件。你可以用一些从干净的速度来换取增量的速度。)
您的第二个 makefile 无法正常工作的原因是,在一个干净的目录中,C_OBJECTS
变量没有值。您的通配符 $(OBJECT_DIRECTORY)/*.o
不匹配。
这也是不正确的,因为它将每个 源文件列为每个 目标文件的先决条件,这根本不正确。
关于c - 制作 : compiling all files once AND generating object files into different directory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33805524/