使用gnu-make正确构建git子模块



我目前正试图编写一个Makefile,以正确构建一个包含git子模块的项目。这个子模块有自己的一组makefile,并同时生成多个目标,包括一些库。

此Makefile应具有以下属性。

  • 即使使用并行构建,也不要两次重建子模块
  • 当子模块代码发生变化时,更新子模块目标(可能因为我浏览了主存储库的修订版)
  • 当子模块库发生更改时,重新链接主项目
  • 不要在顶层项目中复制粘贴子模块的Makefiles(即保持Makefiles递归)

只是为了设定想法,这里有一些似乎有效的东西。

FOO_SUBDIR := $(CURDIR)/foo
LDFLAGS := -L$(FOO_SUBDIR)
FOO_LIBSFILES := $(FOO_SUBDIR)/libfoo.a $(FOO_SUBDIR)/libgnufoo.a
FOO_LDLIBS := -lfoo -lgnufoo

.PHONY: all
all: main
# There are theoretically 3 main binaries
main: main.c $(FOO_LIBSFILES)
gcc -o $@ $< $(LDFLAGS) $(FOO_LDLIBS)
$(FOO_LIBSFILES): libfoo
@# Do nothing
.PHONY: libfoo
libfoo:
$(MAKE) -C $(FOO_SUBDIR)

我加了一个空配方,似乎很管用,但我不明白为什么。

其思想是始终依赖子模块的Makefile来重建(或不重建)libfoo.alibgnufoo.a,并让主Makefile决定是否需要重建main。没有空的配方是行不通的。当修改foo/foo.c时,则重建libfoo.a,但make不重建main

我有一种感觉,空配方强制检查目标文件的日期。但我找不到关于这种行为的文档。

这是正确的路吗?有什么我应该注意的陷阱吗?还有什么不那么晦涩的方法吗?或者关于这种行为的任何文档?

提前谢谢。

您的解决方案总体上是正确的-在顶层生成文件中,您添加了可用于子项目的目标。这是通过自己的makefile处理独立(子)项目的唯一正确方法。

您询问的具体问题与不终止依赖libfoo的规则有关,GNU make要求规则具有命令,即使它是no-op。改为:

$(FOO_LIBSFILES): libfoo ; 

这实际上是相同的no-op,但更惯用。

最新更新