如何使用$(MAKEFLAGS)
(或以其他方式将命令行中定义的变量传递给sub-make)以支持从make VAR=val
和make -args
进行shell调用的方式?
我需要我的子项目可配置,但我讨厌autotools,所以我正在使用make变量,例如从shell调用:
$ make USE_SSE3=1
和USE_SSE3
需要应用于所有子makefile中的所有构建。
The manual声明:
如果你做'make -ks',那么MAKEFLAGS的值为'ks'。
因此我在Makefile中使用-$(MAKEFLAGS)
(带短划线前缀)。
但是,当使用没有标记的变量时,扩展为无效参数。如果我跑:
$ make FOO=bar
然后sub-make无效-FOO=bar
。没有短划线前缀变量定义的OTOH工作,但make -s
等不起作用。
是否有语法/变量/ hack使得传递参数和单独的变量定义与子makefile一起工作?
遗留$(MKFLAGS)
没有奇怪的短划线前缀问题,但它也不包含变量定义。我尝试用$(patsubst)
修复变量,但这只会通过修剪空格使事情变得更糟。
我需要该解决方案与Mac OS X Mavericks附带的过时GNU Make 3.81兼容。
foo:
$(MAKE) -C subproject -$(MAKEFLAGS)
$ make foo -s # MAKEFLAGS = 's'
$ make foo BAR=baz # MAKEFLAGS = 'BAR=baz'
$ make foo -j8 # MAKEFLAGS = ' --job-server=…'
答案 0 :(得分:9)
您根本不应设置MAKEFLAGS
。你为什么这么想?你没有给出任何理由这样做。
MAKEFLAGS
是一个内部实现,它将参数从父make传递给子make。通常,它不是由makefile修改的。关于你可以做的唯一事情就是添加新标志。
如果你只是使用$(MAKE)
变量而不是硬编码make
来运行递归make,那么它就会工作:
recurse:
@$(MAKE) all FOO=bar
或其他什么。
答案 1 :(得分:1)
如果我做对了,我得到你的答案已经晚了很多年了。
您可以自己手动构建 $(MAKEARGS)
,例如:
MAKEARGS := $(strip \
$(foreach v,$(.VARIABLES),\
$(if $(filter command\ line,$(origin $(v))),\
$(v)=$(value $(v)) ,)))
MAKEARGS :=
分配静态
strip
清除前导和尾随空格。
foreach v
遍历所有变量名。
origin $(v)
检查变量来源是否为“命令行”。
$(v)=$(value $(v))
输出环境分配字符串。
或者,您可以取消选择 $(MAKEFLAGS)
,例如:
MAKEARGS := $(wordlist 2,$(words $(MAKEFLAGS)),$(MAKEFLAGS))
MAKEFLAGS := $(firstword $(MAKEFLAGS))
恕我直言,这可以为您留下更清晰的代码以进行进一步的递归。我这样说是因为我有时需要在某些情况下将参数和标志分开。尤其是当您陷入调试递归 djungle 时。 但对于任何特定情况,应咨询the manual about recursive options processing.
更改 $(MAKEFLAGS)
会导致意外故障。
对于愿意的用户来说,另一个有用的信息可能是 $(MAKEFLAGS)
变量基本上是传递给 make 的整个参数列表,而不仅仅是标志字符。所以 $(info MAKEFLAGS = $(MAKEFLAGS))
可以给你类似的东西:
MAKEFLAGS = rRw -- VAR=val
干杯
答案 2 :(得分:0)
要检查make标志中是否存在-B,请执行以下操作:
BB_CLOBBER := $(shell echo $(MAKEFLAGS) | grep wB)
ifeq (,$(BB_CLOBBER))
# also force clobber make if these files are missing
BB_CLOBBER := $(shell (test -e $(bb_gen)/minimal/.config && test -e $(bb_gen)/full/.config) || echo "B")
endif
bb_prepare:
ifneq (,$(BB_CLOBBER))
@rm -rf $(bb_gen)/full
...