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

问题描述 投票:11回答:5

我想通过传递命令来从Makefile中取消定义变量。这可能吗?人造品牌没有太大帮助。

我想执行以下操作:

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

编辑:在Makefile中是:

BROKEN=                 does not link

而且我想取消设置/取消定义。因为Makefile不会进一步执行。到目前为止,这与编译器标志无关。

command-line makefile
5个回答
4
投票

我认为您实际上不能未定义变量。

但是,如果“空”对您足够好:

make -e variable=''

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为true,则返回cond,否则返回else(如果没有else,则返回空字符串)。非空字符串为true,空字符串为false。

因此,如果在命令行上指定了FOO,则Makefile会取消定义undef

undef的“魔术”依赖性确保了如果undef是命令行上给出的唯一目标,它将取决于并因此执行默认目标,在本示例中为all。这是为了确保make undef的行为类似于make,但未定义变量。

WARNING:此类Makefile的行为可能会造成混淆。想象一下,如果给出了CPPFLAGS+=-DNDEBUG,使用此机制的Makefile会排除debug。出乎意料的是,make debug allmake allmake all创建了different输出。期望make debug allmake all相比创建additional输出。主要期望是make all总是表现相同,无论命令行上可能还存在其他什么目标。最好使用configure样式的机制来实现这种机制。

((来源:来自我未出版的有关GNU make的书。)


1
投票

0
投票

不确定您使用的是哪个编译器(我知道最近的BSD默认使用clang,但是使用gcc您可以使用-U取消定义先前定义的符号。

编辑:显然我误解了你的问题。因此,您想要的是make variable=X的等效项,它将取消定义而不是设置值?我认为这是不可能的。

如果无法修改现有的makefile,可以制作自己的副本并改为使用该副本来调用make吗?


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.