【问题标题】:Binary is not rebuilding when source file changes源文件更改时二进制文件不重建
【发布时间】:2021-04-15 17:46:01
【问题描述】:

我的目录结构如下:

  • 生成文件
    • bin

        main.c
        Makefile
      
    •   lib1.c
        lib2.c
        Makefile
      
    • tst

        test1.cc
        Makefile
      

在我的 Makfile 中,我的代码如下所示:

ALL_OBJECTS = main.o lib1.o lib2.o
BINS = binary
binary,SRCS = main.o lib1.o lib2.o
OBJS = $($(*),SRCS)

all: $(ALL_OBJECTS) $(BINS)

%.o   : %.c
      ${CC} -c $^ -o $@
binary:
        ${CC} -o $@ $(OBJS)

我的问题是,当我更改 main.c、lib1.c 或 lib2.c 等源文件时,*.o 文件会在 make 期间重新编译,但二进制文件不会重新编译。当其中一个依赖项发生更改时,如何确保重新编译二进制文件?

【问题讨论】:

  • 可能不是您想要的答案,但如果您想做任何不平凡的事情,请使用 Cmake 或类似的东西,而不是自己构建 Makefile。 Here 是我写的相关答案
  • 你的二进制文件不依赖 .o 对象
  • @klutt:根据我的经验,CMake 是个坏主意,除非你真的需要它提供的跨平台功能,否则需要大量额外的工作。
  • 没有我可以创建的 .d 文件来概述二进制文件的依赖关系吗?
  • 回复。 "Is there not a .d file I can create which outlines the dependencies for the binary?":据我所知没有。 .d 文件通常包含目标文件对源文件和头文件的依赖关系,并且可以由编译器生成(例如,参见 here)。但是需要手动指定链接器依赖项(我很想被证明是错误的)。

标签: c makefile gnu


【解决方案1】:

您的 Makefile 的某些部分对我来说没有多大意义,并且您显示的目录结构似乎与您显示的 Makefile 不太匹配。例如,对于一个名为 lib 的目录,它包含自己的 Makefile,我希望看到 Makefile 创建一个依赖于 lib1.o 和 lib2.o 的库。然后binary 将依赖于该库。

但现在,您似乎只是从单个 Makefile 构建 binary,而忽略了 lib 目录中的 Makefile。这也可以,但它会与之前的场景不同。

现在,让我们从更“扁平”的目录结构开始,main.clib1.clib2.c 都包含在一个目录中(以及同一目录中的 Makefile)。对于这种情况,我们可以使用非常简单的 Makefile 构建二进制文件:

binary: lib1.o lib2.o main.o
   $(CC) -o binary lib1.o lib2.o main.o

我们只是让二进制文件依赖于目标文件,以及如何从这些目标文件创建二进制文件。任何合理的现代 make 实用程序都已经内置了如何编译 .c 文件以生成 .o 文件的规则,因此我们不必做更多的事情,除非我们希望在构建这些对象时有一些相当不寻常的东西文件。

这确实在两个地方重复了目标文件的名称。我们通常宁愿避免这种情况。我们可以将定义目标文件的名称从规则中分离出来,从它们中生成二进制文件,得到更像这样的东西:

OBJS = lib1.o lib2.o main.o

binary: $(OBJS)
   $(CC) -o binary $(OBJS)

现在我们只有一个位置的目标文件的名称,所以如果(举一个明显的例子)我们添加另一个目标文件,我们只需要在一个位置添加它的名称,而不是两个。

【讨论】:

  • 是的。我为这个例子简化了 Makefile。我正在尝试生成一个规则,以便我有一个二进制文件列表,这些二进制文件具有它们所依赖的 .o 文件,并且它应用相同的规则来编译它们。我试图避免多行 binary1: $(OBJ1), binary2: $(OBJ2) binary3:$(OBJ3) .etc... 基本上所有行都将运行相同的 CC -o $@ @^ 命令。这是我从二进制中省略了依赖项并在命令中计算它们的时候。我想要这样的结构: $(BIN_OUT)%: CC -o $@ $($@,SRCS)
【解决方案2】:

根据您对@JerryCoffin 回答的最后评论,您可以执行以下操作:

binary1 : lib1.o lib2.o main1.o
binary2 : lib2.o main2.o
binary3 : lib1.o main3.o

binary1 binary2 binary3:
    $(CC) -o $@ $^

前三行没有配方,因此只是将先决条件添加到相关的二进制文件中。然后使用自动变量$^ 为二进制目标定义一个配方,该变量将扩展到该目标的依赖项。

【讨论】:

    猜你喜欢
    • 2013-10-30
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 2017-12-24
    • 1970-01-01
    • 2016-01-13
    相关资源
    最近更新 更多