我正在使用Make,我有一个makefile,它设置一个变量,其值需要从父makefile覆盖。我已尝试在父makefile中设置变量并使用export
将其传递给子制表但变量未使用传递的值,而是使用在子Makefile中显式设置的值。 / p>
我知道命令行中指定的变量会覆盖makefile中的任何普通赋值(除非使用override
)但是有一种方法可以实现这一点,而不必在命令行中为每个子目录指定它调用submake(因为有很多,我喜欢保持DRY)?
更新
我应该提到我不能修改submake文件,因为它来自我们跟踪的外部存储库,我没有权限修改它所以我需要在父makefile级别工作来影响submake
示例
这是调用子制作的父makefile中的代表目标:
$.PHONY (external_lib)
$(external_lib):
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_a
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_b
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_c
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_d
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_e
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_f
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_g
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_h
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_i
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) library
答案 0 :(得分:5)
(你似乎正在使用GNUMake以外的东西,这是我所知道的唯一的东西,所以请带上一粒盐。)
首先,您可以通过使组件分离目标来使Makefile更整洁:
COMPONENTS = make_a make_b make_c make_d make_e make_f make_g make_h make_i \
library
.PHONY: external_lib $(COMPONENTS)
$(external_lib): $(COMPONENTS)
$(COMPONENTS):
@$(MAKE) -s -C $(source_dir)/project/component $(PROJECTVARS) $@
(如果您担心名称冲突,可以采用简单的方法来处理。)
现在,如果你想覆盖一个名为VAR的变量,你可以在一个地方完成所有这些:
COMPONENTS = make_a make_b make_c make_d make_e make_f make_g make_h make_i \
library
.PHONY: external_lib $(COMPONENTS)
$(external_lib): $(COMPONENTS)
$(COMPONENTS):
@$(MAKE) -s -C $(source_dir)/project/component $(PROJECTVARS) VAR=$(VAR) $@
这假设您要为所有组件覆盖相同的变量,这就是我阅读问题的方式。如果您想为某些目标覆盖不同的变量,那很容易:
COMPONENTS = make_a make_b make_c make_d make_e make_f make_g make_h make_i \
library
.PHONY: external_lib $(COMPONENTS)
$(external_lib): $(COMPONENTS)
VARNAME = VAR
$(COMPONENTS):
@$(MAKE) -s -C $(source_dir)/project/component $(PROJECTVARS) \
$(VARNAME)=$($(VARNAME)) $@
make_c: VARNAME=OtherVar
make_h: VARNAME=YetAnotherVar
如果你想覆盖某些目标的几个变量,这有点棘手......
答案 1 :(得分:1)
如果您不希望子makefile覆盖父级设置的值,请让sub-makefile使用VARIABLE ?= value
语法分配值。这只会在尚未定义变量的情况下执行赋值。在您的情况下,变量将在父makefile中定义,因此不会进行赋值。
<强>更新强> 如果你不能修改子makefile,那么你没有很多选项。我建议您在调用sub-make文件时在命令行上设置变量。为清楚起见,将这些定义包装在make变量中。例如,
CUSTOM_DEFINITIONS := VAR1=value1 VAR2=value2 VAR3=value3
$(external_lib):
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) $(CUSTOM_DEFINITIONS) make_a
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) $(CUSTOM_DEFINITIONS) make_b
$(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) $(CUSTOM_DEFINITIONS) make_c
这不是最漂亮的解决方案,但可以从父makefile完成。
答案 2 :(得分:1)
除了使用并不总是推荐的导出之外,你可以将变量传递给像这样的子制作文件 -
**HOSTCC = gcc**
CC= MIPS-GCC
FLAGS = -O2 -Wall -DSELECT_PROBLEM
M="CC=$(CC) $(FLAGS)"
所有
cd ../rng ; $(MAKE) $(M) **HOSTCC=$(HOSTCC)** ;
所以如果你的sub-make文件有2个文件,每个文件需要不同的编译工具链,你可以做上面显示的。
答案 3 :(得分:0)
make.info的第5.7.2节(gnu make that):
The special variable `MAKEFLAGS` is always exported. ...
Variables are _not_ normally passed down if they were created by
default by `make` (Implicit Rules)
if you want to export specific variables to sub-`make`, use the
`export` directive.
export VARIABLE ...
因此,我的建议是使用MAKEFLAGS
变量,或者明确export
您想要使用的变量。
答案 4 :(得分:0)
在将子变量分配给子变量之前,您需要检查变量是否已经有值。
从GNU Make手册(http://www.gnu.org/software/make/manual/make.html)第6.5节:
如果您希望变量仅在尚未设置的情况下设置为值,则可以使用简写运算符?=' instead of
='。变量“FOO”的这两个设置是相同的(参见原点功能):
FOO ?= bar
和
ifeq ($(origin FOO), undefined)
FOO = bar
endif