我想通过传递命令来从Makefile中取消定义变量。这可能吗?人造品牌没有太大帮助。
我想执行以下操作:
我想用FreeBSD编译端口。此端口标记为broken
。尽管我没有更改Makefile的权限,但我正在寻找取消broken
定义的可能性?变量。
编辑:在Makefile中是:
BROKEN= does not link
而且我想取消设置/取消定义。因为Makefile不会进一步执行。到目前为止,这与编译器标志无关。
我认为您实际上不能未定义变量。
但是,如果“空”对您足够好:
make -e variable=''
您可以这样做。假设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 all
和make all
为make all
创建了different输出。期望make debug all
与make all
相比创建additional输出。主要期望是make all
总是表现相同,无论命令行上可能还存在其他什么目标。最好使用configure
样式的机制来实现这种机制。
((来源:来自我未出版的有关GNU make的书。)
不确定您使用的是哪个编译器(我知道最近的BSD默认使用clang,但是使用gcc您可以使用-U
取消定义先前定义的符号。
编辑:显然我误解了你的问题。因此,您想要的是make variable=X
的等效项,它将取消定义而不是设置值?我认为这是不可能的。
如果无法修改现有的makefile,可以制作自己的副本并改为使用该副本来调用make
吗?
有一个-DIGNORE_BROKEN或类似的东西,请查看FreeBSD Porter的手册,希望它有关于此的信息。