c - 制作 : compiling all files once AND generating object files into different directory

标签 c gcc makefile

我有一个项目,其中包含许多位于不同文件夹位置的源文件。出于某种原因,我的 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/

相关文章:

c - malloc() 崩溃,说损坏的双链表

c - 是否可以列出系统中当前 <LIVE> 的所有 sk_buff?

c - 如何在编译时打印结构成员的偏移量?

gcc - Makefile vpath %.o 未找到 obj 文件

makefile - 如何管理C头文件依赖?

c - 二分查找树没有打印任何内容

c - 为什么我的结构中的变量会发生变化?

c++ - 是否可以并行编译单个 C++ 翻译单元?

linux - 构建 Pulseaudio-11.1 和 intltool >= 0.35.0 错误

c - 是否可以从 util 调用 postgres 内部方法?