c-二进制文件在源文件更改时不重新生成



我有一个如下的目录结构:

  • 生成文件
    • bin

      main.c
      Makefile
      
    • lib

      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期间重新编译,但二进制文件不会重新编译。当二进制文件的某个依赖项发生更改时,我如何确保重新编译它?

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)

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

根据你对@JerryCoffin的回答的最后一条评论,你可以做这样的事情:

binary1 : lib1.o lib2.o main1.o
binary2 : lib2.o main2.o
binary3 : lib1.o main3.o
binary1 binary2 binary3:
$(CC) -o $@ $^

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

相关内容

  • 没有找到相关文章

最新更新