我有一个项目,其中包含许多不同文件夹位置的源文件。出于某种原因,我的Makefile可以执行以下操作之一,但不能同时执行以下操作(这是我真正想要的): -
1)将所有文件编译到一个单独的目录
2)执行编译ONCE,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相同的位置,而不是生成单独的目录。我不想在文件生成后将文件复制,因为这不是更清晰的解决方案。
我的问题是: 我需要对Makefile做什么才能进行一次编译,并将目标文件生成到一个单独的目录中?
答案 0 :(得分:3)
你想要的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
不匹配任何内容。
那说它也是不正确的,因为它列出了每个源文件作为每个目标文件的先决条件,这完全没有问题。