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

时间:2014-02-16 02:51:27

标签: git makefile gnu-make git-submodules

我目前正在尝试编写一个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.alibgnufoo.a,并让主Makefile决定是否需要重建main。没有空配方它不起作用。修改foo/foo.c后,会重建libfoo.a,但make不会重建main

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

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

提前致谢。

1 个答案:

答案 0 :(得分:2)

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

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

$(FOO_LIBSFILES): libfoo ; 

这实际上是相同的无操作,但更惯用。