如何通过命令行在Makefile中取消定义变量

时间:2012-08-31 13:05:56

标签: command-line makefile

我想通过传递命令来从Makefile中取消定义变量。这可能吗?男人做的没那么多。

我想做以下事情:

我想用FreeBSD编译一个端口。此端口标记为broken。虽然我没有更改Makefile的权限,但我正在寻找取消定义broken的可能性?变量

编辑: 在Makefile中是:

BROKEN=                 does not link

我想取消/取消定义。因为Makefile没有进一步执行。到目前为止,这与编译器标志无关。

5 个答案:

答案 0 :(得分:4)

我认为你实际上不能取消定义变量。

但是,如果'空'对您来说足够好:

make -e variable=''

答案 1 :(得分:2)

你可以这样做。假设undef是您要用来取消定义变量的目标名称,方法如下。

FOO:=foo

ifeq (undef,$(filter undef,$(MAKECMDGOALS)))
override undefine FOO
endif

.PHONY: all
all:
        echo $(FOO) '($(origin FOO))'

.PHONY: undef
undef: $(if $(filter-out undef,$(MAKECMDGOALS)),,$(.DEFAULT_GOAL)))

使用的make元素的说明:

  • MAKECMDGOALS是预定义的只读变量,包含调用make的目标。我们使用它来检查make是否使用undef调用。
  • .DEFAULT_GOAL是包含默认目标的预定义变量。如果未明确设置,则将其设置为第一个目标,在本例中为all
  • ifeq ... endif允许Makefile中的条件部分。
  • $(filter pattern,list)函数返回list中与pattern匹配的所有元素。因此,如果调用make并将undef作为其目标之一,则$(filter undef,$(MAKECMDGOALS))将为undef,否则将为空字符串。
  • $(filter-out pattern,list)功能与$(filter key,list)相反。它返回list中与pattern不匹配的所有元素。因此,如果仅使用make调用undef,则$(filter-out undef,$(MAKECMDGOALS))将为空字符串,否则它将是命令行上给出的所有目标的列表,不包括undef
  • undefine取消定义变量。
  • override更改变量,即使它是在命令行上传递的。您需要根据用例决定是否使用override
  • $(if cond,then[,else])函数如果then为真,则返回cond,否则返回else(如果没有else,则返回空字符串)。非空String为true,空String为false。

因此,在命令行中给出FOO的情况下,Makefile取消定义undef

undef的“神奇”依赖关系确保如果undef是命令行上给出的唯一目标,它将依赖于并因此执行默认目标,在此示例中将是all。这是为了确保make undef的行为类似于make,除非它取消定义变量。

警告:此类Makefile的行为可能会造成混淆。想象一下,在给出CPPFLAGS+=-DNDEBUG的情况下,使用此机制排除debug的Makefile。 make debug allmake allmake all创建不同的输出是出乎意料的。与make debug all相比,期望make all创建附加输出。主要期望是make all始终表现相同,无论命令行上是否还有其他目标。最好使用configure式机制来实现这些机制。

(来源:我未发表的关于GNU make的书。)

答案 2 :(得分:1)

答案 3 :(得分:0)

不确定你正在使用什么编译器(我知道最近BSD默认使用clang)但是使用gcc你可以使用-U取消定义先前定义的符号。

编辑:显然我误解了你的问题。那么你想要的是等价于make variable=X,它将取消定义而不是设置一个值?我不相信这是可能的。

如果您无法修改现有的makefile,是否可以制作自己的副本并使用该副本调用make

答案 4 :(得分:0)

有一个-DIGNORE_BROKEN或类似的东西,请查阅FreeBSD Porter的手册,希望它能提供有关此信息。