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

标签 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.

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

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

提前致谢。

最佳答案

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

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

$(FOO_LIBSFILES): libfoo ; 

这实际上是相同的空操作,但更加地道。

关于git - 使用 gnu make 正确构建 git 子模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21806682/

相关文章:

c++ - (避免)在 C++ 中将代码拆分为 .cpp 和 .h 并进行高效编译

makefile - Makefile 规则定义中的分号

Linux Makefile - CXX 未定义

gnu-make - Makefile、正则表达式和多个依赖项

git - 如何将我的分支重置为我在分离 HEAD 模式下创建的提交?

git - 为什么要使用 git 裸仓库进行网站部署?

makefile - 为什么 "make"仅在隐式时才删除目标文件

Makefile:从数字序列生成目标

svn - git svn clone 不检查所有目录

使用终端进行私有(private)存储库的 Git 克隆失败