覆盖父makefile中的子映射分配变量

The*_*ice 5 makefile

我正在使用Make,我有一个makefile,它设置一个变量,其值需要从父makefile中覆盖.我已经尝试在父makefile中设置变量并使用export它将其传递给子制表但变量不使用传递的值,而是使用在子Makefile中显式设置的值.

我知道在命令行上指定的变量会覆盖makefile中的任何普通赋值(除非override被使用),但是有一种方法可以为子制作实现这一点,而不必在每次调用子制作时在命令行上指定它(因为有不少,我喜欢留DRY)?

UPDATE

我应该提到我不能修改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
Run Code Online (Sandbox Code Playgroud)

Bet*_*eta 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) $@
Run Code Online (Sandbox Code Playgroud)

(如果您担心名称冲突,可以采用简单的方法来处理.)

现在,如果要覆盖名为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) $@
Run Code Online (Sandbox Code Playgroud)

这假设您要为所有组件覆盖相同的变量,这就是我阅读问题的方式.如果要为某些目标覆盖不同的变量,那很容易:

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
Run Code Online (Sandbox Code Playgroud)

如果你想覆盖某些目标的几个变量,这有点棘手......