我想通过传递命令来从 Makefile 中取消定义变量。这可能吗?人类制造并没有太大帮助。
我想做以下事情:
我想用 FreeBSD 编译一个端口。此端口标记为broken。虽然我没有更改 Makefile 的权限,但我正在寻找取消定义的可能性broken?多变的。
编辑:在 Makefile 中是:
BROKEN= does not link
我想取消设置/取消定义损坏。因为 Makefile 没有进一步执行。到目前为止,这与编译器标志无关。
我想通过传递命令来从 Makefile 中取消定义变量。这可能吗?人类制造并没有太大帮助。
我想做以下事情:
我想用 FreeBSD 编译一个端口。此端口标记为broken。虽然我没有更改 Makefile 的权限,但我正在寻找取消定义的可能性broken?多变的。
编辑:在 Makefile 中是:
BROKEN= does not link
我想取消设置/取消定义损坏。因为 Makefile 没有进一步执行。到目前为止,这与编译器标志无关。
我认为您实际上无法取消定义变量。
但是,如果 'empty' 对您来说足够好:
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允许 a 中的条件部分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))undefundefine取消定义变量。override即使它是在命令行上传递的,也会更改变量。您需要根据您的用例决定使用是否override有意义。$(if cond,then[,else])函数返回,否则(如果没有,则返回空字符串)。非空字符串为真,空字符串为假。thencondelseelse因此,Makefile 取消定义FOO以防万一undef在命令行中给出。
的“神奇”依赖undef确保 ifundef是命令行上给出的唯一目标,它将依赖并因此执行默认目标,在本示例中为all. 这是为了确保它的make undef行为类似于make它取消定义变量。
警告:此类Makefiles 的行为可能令人困惑。想象一个 Makefile 使用这种机制来排除CPPFLAGS+=-DNDEBUG万一debug被给定的情况。出乎意料的是,make debug all并make all为. 与 相比,预期会产生额外的输出。主要的期望是,无论命令行上可能另外存在什么其他目标,它的行为总是相同的。最好使用-style 机制来实现此类机制。make allmake debug allmake allmake allconfigure
(来源:来自我未出版的关于 GNU make 的书。)
http://www.gnu.org/software/make/manual/make.html#Undefine-Directive
据说你可以
override undefine VARIABLE
不确定您使用的是什么编译器(我知道最近的 BSD 默认使用 clang)但是使用 gcc 您可以使用-U.
编辑:显然我误读了你的问题。所以你想要的是一个等价于 make variable=X,它将取消定义而不是设置一个值?我不相信这是可能的。
如果您无法修改现有的 makefile,您可以制作自己的副本并make使用该文件调用吗?
有一个 -DIGNORE_BROKEN 或类似的,请查看 FreeBSD Porter 的手册,它应该有这方面的信息。
为什么我从下面的代码中得到这个
富:=富1
ifneq ($(foo),) 覆盖 undefine foo endif
Makefile:5: 无效override指令