【问题标题】:Properly build a git submodule with gnu make使用 gnu make 正确构建 git 子模块
【发布时间】:2014-02-16 02:51:27
【问题描述】:

我目前尝试编写一个 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

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

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

提前致谢。

【问题讨论】:

    标签: git makefile gnu-make git-submodules


    【解决方案1】:

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

    您要问的具体问题与不终止 libfoo 依赖规则有关,而 GNU make 需要一个规则才能具有命令,即使它是无操作的。改为这样做:

    $(FOO_LIBSFILES): libfoo ; 
    

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

    【讨论】:

    • 非常感谢。所以你的意思是这种行为并不是真正的黑客行为,从长远来看应该有效?
    • @Celelibi 不确定您指的是哪种行为,但是引入一个目标来表示一个子项目并不是 hackish。拥有无操作目标也不是骇人听闻的。
    • 我指的是$(FOO_LIBSFILES) 的规则不要触及这些文件。相反,规则libfoo 做到了。我强制 make 通过提供一个空配方来检查文件日期。
    • @Celelibi 在我看来这是更干净的方法。通过其 make 文件处理单个子项目的单个目标。其他目标取决于它 - 我认为这没有问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多