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

Cel*_*ibi 5 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)
Run Code Online (Sandbox Code Playgroud)

我添加了空食谱似乎很有效,但我不明白为什么。

这个想法是始终依靠子模块的Makefile进行重建(或不重建)libfoo.alibgnufoo.a,并让主Makefile决定是否main需要重建。没有空食谱,它是行不通的。当foo/foo.c被修改,然后libfoo.a重新生成,但make不重建main

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

这是正确的方法吗?我应该注意的任何陷阱?还有什么比较晦涩的方法吗?或有关此行为的任何文档?

提前致谢。

moc*_*ace 4

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

您所询问的具体问题与不终止 libfoo 相关规则有关,并且 GNU make 需要一个规则来包含命令,即使它是无操作。改为这样做:

$(FOO_LIBSFILES): libfoo ; 
Run Code Online (Sandbox Code Playgroud)

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