如何编写一个简单的分层Makefile?

12

几天前,我在Stack Overflow上发布了一个有关如何编写分层Makefile(http://stackoverflow.com/questions/1498213/make-hierarchical-make-file)的答案。然而,这个答案被删除了,因此我认为它完全是错误的或离题(或两者都有)。

我想知道如何编写分层Makefile。这是一个调用子目录中几个Makefile的Makefile。我假设一个目录结构,如下所示:

- project
  |--module1
      |--Makefile
      |--...
  |--module2
     |--Makefile
     |--module2.1
     |--module2.2  
     |--...
  |--module3
     |--Makefile
     |--...
  |--etc
我还假设项目成员仅就一组最小的Makefile目标(re:all(默认)、clean、install等)达成了共识。因此,以下命令及make标志将被传播到模块中:
cd project
make clean  
make -k
make install
#etc

以下项目Makefile有什么问题:

PACKAGES = \
    module1 \
    module2 \
    emodule3

VIRTUAL_PACKAGES = $(addsuffix /.virtual.Makefile,${PACKAGES})

TARGETS=clean install all

.PHONY: $(TARGETS)
default: all

FLAGS = $(ifeq $(MAKEFLAGS) "","",-$(MAKEFLAGS))

$(TARGETS): $(VIRTUAL_PACKAGES)

$(VIRTUAL_PACKAGES): 
    $(MAKE) $(FLAGS) -C $(@D) $(MAKECMDGOALS)

жҳҜзҡ„пјҢMakefileдёӯзҡ„$VIRTUAL_PACKAGESзңӢиө·жқҘеҫҲеҘҮжҖӘгҖӮж··еҗҲдҪҝз”ЁforеҫӘзҺҜзҡ„жӣҝд»Јж–№жі•еҸҜиғҪдјҡжӣҙз®ҖзҹӯпјҢдҪҶжҲ‘дёҚзЎ®е®ҡе®ғжҳҜеҗҰжӣҙеҘҪпјҲеӣ дёәжҲ‘йңҖиҰҒдҫқйқ bashпјүпјҡ PACKAGES = \ module1 \ module2 \ emodule3

TARGETS=clean install all

.PHONY: $(TARGETS)
default: all

FLAGS = $(ifeq $(MAKEFLAGS) "","",-$(MAKEFLAGS))

$(TARGETS): 
    for p in $(PACKAGES) ; do $(MAKE) $(FLAGS) -C $$p $@ || break; done

谢谢!


那个对FLAGS的赋值有效吗?你使用的是哪个版本的Make? - Beta
一种非递归解决方案:https://dev59.com/OlrUa4cB1Zd3GeqPj3Af#7321954 - Maxim Egorushkin
可能对你有用,但对于管理复杂项目,我发现cmake要容易得多。很容易拥有CMakeLists.txt的层次结构。Makefile将自动生成。 - Hindol
@Beta: 1) 是的,FLAGS 赋值有效...为什么?2) Makefile 版本是 3.81。 - marcmagransdeabril
1个回答

10

这里有“龙”。虽然可以实现,但其影响可能很棘手。

Google搜索“递归Make伤害论”。你会得到非常好(简单)的说明,介绍了你想要的内容(例如,分层Make),并解释了一些陷阱/问题。一些“回答”将讨论可能的“最佳实践”和缓解问题的方法。然后,你可以决定所提出的问题是否对你的应用程序具有说服力。

原始论文:

http://miller.emu.id.au/pmiller/books/rmch/

其他链接:

http://c2.com/cgi/wiki?RecursiveMakeConsideredHarmful

http://dbaspot.com/configuration-management/194597-thoughts-recursive-make-considered-harmful.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接