问题描述
我目前正在尝试编写一个Makefile,以正确构建一个包含git子模块的项目.该子模块具有自己的一组makefile,并一次生成多个目标,包括一些库.
I currently try to write a Makefile that build properly a project which contains a git submodule. This submodule have its own set of makefiles and produce several targets at once, including some libraries.
此Makefile应该具有以下属性.
This Makefile should have the following properties.
- 即使使用并行构建,也不要重建两次子模块.
- 在子模块代码已更改时更新子模块目标(也许因为我浏览了主存储库的修订版.
- 子模块库更改后,重新链接主项目.
- 请勿在顶级项目中复制粘贴子模块的Makefile(即保持Makefile递归).
- Don't rebuild twice the submodule even with parallel build.
- Update the submodule targets when the submodule code has changed (maybebecause I navigated through the revisions of the main repository).
- Re-link the main project when the submodule library have changed.
- Don't copy-paste the Makefiles of the submodule in the top-level project (i.e. keep the Makefiles recursive).
仅是设定想法,这似乎是可行的.
Just to set the ideas, here is something that seems to work.
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)
我似乎添加了空食谱,但我不明白为什么.
It seems to work sice I added the empty recipe, but I don't understand why.
想法是始终依靠子模块的Makefile来重建(或不重建)libfoo.a
和libgnufoo.a
,并让主Makefile决定是否需要重建main
.没有空的配方,它将无法正常工作.修改foo/foo.c
时,将重建libfoo.a
,但make
不会重建main
.
The idea is to always rely on the submodule's Makefile to rebuild (or not) libfoo.a
and libgnufoo.a
, and let the main Makefile decide whether main
need to be rebuilt. Without the empty recipe it doesn't work. When a foo/foo.c
is modified, then libfoo.a
is rebuilt, but make
doesn't rebuild main
.
我有一种空的配方力量可以检查目标文件的日期的感觉.但是我找不到有关此行为的文档.
I have the feeling that the empty recipe force make to check the date of the target files. But I can't find documentation about this behavior.
这是正确的方法吗?我应该注意的任何陷阱?有什么更晦涩的方法可以做到这一点吗?或有关此行为的任何文档?
Is this the right way to go? Any pitfall I should be aware of? Any less obscure way to do this? Or any documentation about this behavior?
谢谢.
推荐答案
您的解决方案通常是正确的-在您的顶层Makefile中,添加了可用于子项目的目标.这是通过独立的子文件处理独立(子)项目的唯一正确方法.
Your solution is correct in general - in your toplevel makefile you've added targets that works the subproject. It is the only proper way to work with a standalone (sub-)project, via its own makefile.
您要询问的特定问题与不终止依赖libfoo的规则有关,并且GNU make要求规则具有命令,即使它是无操作的也是如此.改为执行此操作:
The specific problem you are asking about has to do with not terminating the libfoo dependent rule, and GNU make requires a rule to have commands, even if it is a no-op. Do this instead:
$(FOO_LIBSFILES): libfoo ;
这实际上是相同的无操作,但是更惯用.
This is effectively the same no-op, but more idiomatic.
这篇关于用gnu make正确构建一个git子模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!