我有一些基于某些变量的存在而灵活的 Makefile,通过使用ifdef
它们来检查它们。我必须实际将变量设置为等于命令行上的某个值,这有点烦人。 make all DEBUG
不会触发ifdef
但make all DEBUG=1
会触发。也许我只是在不属于它的地方使用 C 预处理器方法。
Q1) 是否可以在命令行上指定一个变量为空?没有更多的字符?Q2)这种布尔参数的首选方法是什么?
我有一些基于某些变量的存在而灵活的 Makefile,通过使用ifdef
它们来检查它们。我必须实际将变量设置为等于命令行上的某个值,这有点烦人。 make all DEBUG
不会触发ifdef
但make all DEBUG=1
会触发。也许我只是在不属于它的地方使用 C 预处理器方法。
Q1) 是否可以在命令行上指定一个变量为空?没有更多的字符?Q2)这种布尔参数的首选方法是什么?
我猜你的意思是make all DEBUG=
这里,对吧?没有=
make 将被视为DEBUG
要构建的目标,而不是变量赋值。
手册指定具有非空值的变量会导致ifdef
返回 true。不存在或存在但包含空字符串的变量会导致ifdef
返回 false。注意ifdef
不扩展变量,它只是测试变量是否有任何值。
您可以使用该$(origin ...)
函数来测试变量是否真的根本没有定义,或者已定义但为空,如下所示:
ifeq ($(origin DEBUG),undefined)
$(info Variable DEBUG is not defined)
else
$(info Variable DEBUG is defined)
endif
正如@MadScientist 几分钟前解释的那样,
make all DEBUG
为您的品牌添加目标DEBUG
。幸运的是,有一个解决方法:
ifneq (,$(filter DEBUG,$(MAKECMDGOALS)))
DEBUG:=1 # or do whatever you want
DEBUG: all; @echo -n
endif
必须为虚拟目标提供虚拟规则(例如,无回显,如上)。或者把这个语句放在你的 makefile 的底部,或者像示例中那样明确指定先决条件目标。否则,make
可能会错误地选择DEBUG目标 而不是all。
请注意,这不是首选方法;约定就像V=1
用来打开回声。
另一个需要注意的是,make
按顺序处理命令行目标,例如,make A B
将首先处理A目标,然后处理B目标,无论这些目标是独立的,还是相互依赖。因此写作make DEBUG PERFECT
并make PERFECT DEBUG
可能产生不同的结果。但是参数的顺序无关紧要,因此make PERFECT=1 DEBUG=1
和make DEBUG=1 PERFECT=1
是等价的。
已经阐明了为什么不能只使用 DEBUG。但我想补充一点。
您可以在运行make之前使用 shell 脚本来设置您需要的所有变量,因此,例如在 linux shell 中,它将如下所示:
$source debug_setup.sh
$make all
Make is starting...
Debug is enabled
...
其中debug_setup.sh包含您需要设置的所有环境变量:
export DEBUG=1
export DEBUG_OPTION=some_option
这很好,因为您可以在那里发表评论,如果您目前不需要某些东西并且想保留以供将来使用,您可以发表评论,等等。
然后,您可以拥有几个必须/可以用作标准例程的一部分的设置脚本。这一切都取决于您需要设置多少变量,您希望拥有多少组变量等。
请注意,以某种方式通知用户选择了哪组变量是一个好主意。