如何在递归构建中忽略命令行变量赋值?

时间:2009-06-01 14:02:27

标签: makefile gnu build-management

我正在尝试将两个构建系统粘合在一起。两者都是递归的(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。

4 个答案:

答案 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中继承任何内容。