正确构建一个gnu make的git子模块

我目前正在尝试编写一个Makefile,它可以正确构建一个包含git子模块的项目.这个子模块有自己的一组makefile,一次产生几个目标,包括一些库.

此Makefile应具有以下属性.

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

只是为了设定想法,这里似乎有用.

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.a和libgnufoo.a,并让主Makefile决定是否需要重建main.没有空配方它不起作用.修改foo / foo.c时,会重建libfoo.a,但make不会重建main.

我感觉空配方强制检查目标文件的日期.但我找不到有关此行为的文档.

这是正确的方法吗?我应该注意哪些陷阱?有什么不那么模糊的方法吗?或者有关此行为的任何文档?

提前致谢.

最佳答案 您的解决方案通常是正确的 – 在您的顶级makefile中,您添加了适用于子项目的目标.它是通过自己的makefile使用独立(子)项目的唯一正确方法.

您要问的具体问题与不终止libfoo依赖规则有关,而GNU make需要一个规则来获取命令,即使它是一个no-op.改为:

$(FOO_LIBSFILES): libfoo ; 

这实际上是无操作,但更惯用.

点赞