我正在尝试将两个构建系统粘合在一起。两者都是递归的(makefile中的规则使用make来调用其他makefile来构建项目的组件)。
我称之为'A'和'B',其中'A'构建应用程序,'B'构建'A'使用的库。
A中的顶级makefile'make TARGET = whatever'这意味着构建的所有递归调用的位都将TARGET的值作为只读变量继承,包括来自B的构建系统,它被调用作为递归构建的一部分。
我不希望在'B'(来自不同的项目)的构建系统中发生这种情况,因为那里的makefile使用TARGET用于他们自己的目的,并且构建失败,因为TARGET具有错误的值并且被读取 - 只。
我只能看到两个解决方案,这两个解决方案都不是可调色的;
1)将TARGET重命名为A中设置它的makefile中的其他内容以及使用它的A中的makefile,以避免与构建系统的较低级别发生冲突。
2)在设置了TARGET变量的B中的makefile中的任何地方使用'override'指令,以覆盖其只读状态。
有人有更好的想法吗? - 理想情况下,我希望B的构建系统从A继承 nothing ,除了那些我从A明确传递给B构建系统的选项。
顺便说一下,我正在使用GNU Make v3.80。
答案 0 :(得分:3)
您可以在A中的二级makefile中将 MAKEOVERRIDES 设置为空。
callb:
cd subdir && $(MAKE) MAKEOVERRIDES=
这会传递正常的命令行参数,例如 -k 和 -s ,但不传递命令行变量定义。
或者您使用与 MAKEFLAGS 相同的历史 MFLAGS ,但 MFLAGS 不包含命令行变量定义。
callb:
cd subdir && $(MAKE) $(MFLAGS)
有关这两个选项的详细信息,请参阅此处:The GNU Make Manual
答案 1 :(得分:0)
也许您可以使用“unexport”指令来阻止TARGET传播到B的makefile?
答案 2 :(得分:0)
在构建系统A调用构建系统B时,不要直接使用“${MAKE}
”;调用一个调用构建系统B的shell脚本(可能在清理环境之后)。
要实现“make -n
”执行命令的行为,请在makefile中的命令行前加上“+
”(类似于在行前加上“@
”或'-
')。
答案 3 :(得分:0)
听起来你修改了A makefile来递归调用B makefile,从而解决了你的问题。为什么不引入一个新的顶级makefile,它递归调用B makefile,然后递归调用A makefile?例如,combined.mk:
all:
$(MAKE) -f Makefile.B
$(MAKE) -f Makefile.A
这样B makefile就不会从A makefile中继承任何内容。