我目前尝试编写一个 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
and libgnufoo.a
,并让主 Makefile 决定是否main
需要重建。没有空的食谱,它就不起作用。当一个foo/foo.c
被修改,那么libfoo.a
已重建,但是make
不重建main
.
我有一种感觉,空的配方强制检查目标文件的日期。但我找不到有关此行为的文档。
这是正确的方法吗?我应该注意什么陷阱吗?还有什么不那么晦涩的方法可以做到这一点吗?或者有关于这种行为的文档吗?
提前致谢。
一般来说,您的解决方案是正确的 - 在您的顶级 makefile 中,您添加了适用于子项目的目标。这是通过其自己的 makefile 处理独立(子)项目的唯一正确方法。
您所询问的具体问题与不终止 libfoo 相关规则有关,并且 GNU make 需要一个规则来包含命令,即使它是无操作。改为这样做:
$(FOO_LIBSFILES): libfoo ;
这实际上是相同的无操作,但更惯用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)