【问题标题】:MAKE: compiling all files once AND generating object files into different directoryMAKE:一次编译所有文件并将目标文件生成到不同的目录中
【发布时间】:2015-11-19 13:38:52
【问题描述】:

我有一个项目,其中包含许多位于不同文件夹位置的源文件。出于某种原因,我的 Makefile 可以执行以下操作之一,但不能同时执行以下操作(这是我真正想要的):-

1) 将所有文件编译到单独的目录中

2) 编译一次,gcc 只需要调用一次,大大减少了编译时间。

这是一个用于实现选项 1 的代码 sn-p:-

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 的代码 sn-p:-

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)

对于上面的 sn-p,所有文件都编译一次(即 gcc 只调用一次),但目标文件与 Makefile 在同一位置生成,而不是在单独的目录中。我不想在生成文件后对其进行 mv,因为这不是更清洁的解决方案。

我的问题是: 我必须对我的 Makefile 做些什么,以便编译一次并且将目标文件生成到单独的目录中?

【问题讨论】:

  • 我认为您可以使用单独的 Makefile,在每个目录中使用一个,并使用“主”makefile 中的 $(MAKE) 来运行其他文件。
  • 第一个 makefile 是正确的,但不是你想要的。第二个根本不正确。

标签: c gcc makefile


【解决方案1】:

你想要的 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 的主要问题和您的目标是,对 any 源文件的更改将导致 每个 源文件从头开始重新编译。就增量工作而言,这是相当低效的。 (这就是为什么默认的想法是使用中间目标文件。你用一些从干净的速度来换取增量速度。)

第二个 makefile 无法正常工作的原因是,在干净的目录中,C_OBJECTS 变量没有值。您的通配符 $(OBJECT_DIRECTORY)/*.o 不匹配。

这也是不正确的,因为它将 每个 源文件列为完全不正确的 每个 目标文件的先决条件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2021-01-25
    • 2021-05-10
    • 2013-06-08
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多