I'm using Make and I have a makefile which sets a variable with a value that I need to override from a parent makefile. I've tried setting the variable in the parent makefile and using export
to pass it to the submake but the variable is not using the passed down value, instead it is using the value explicitly set in the sub-Makefile.
I know that variables specified on the command line override any ordinary assignments in the makefile (unless override
is used) but is there a way to achieve this for submakes without having to specify it on the command line for each invocation of the submake (because there are quite a few and I like to stay DRY)?
UPDATE
I should have mentioned that I can't modify the submake file because it's from an external repository that we track and I don't have the authority to modify it so I need to work at the parent makefile level to influence the submake.
EXAMPLE
Here's a representative target in the parent makefile that's calling the submake:
$.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
(You appear to be using something other than GNUMake, which is the only Make I know, so take this with a grain of salt.)
First you can make your Makefile tidier by making the components separate targets:
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) $@
(If you're worried about name collisions, there are simple ways to deal with that.)
Now if you want to override a variable called, say, VAR, you can do it all in one place:
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) $@
This assumes that you want to override the same variable for all components, which is how I read the question. If you want to override a different variable for some targets, that's easy:
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
If you want to override several variables for some targets, that's a little tricky...
If you don't want your sub-makefile to override the value set by the parent, have the sub-makefile assign the value using the VARIABLE ?= value
syntax. This will only perform the assignment if the variable has yet been defined. In your case, the variable will have been defined in the parent makefile so the assignment will not take place.
Update: If you can't modify the sub-makefile, then you don't have a lot of options. I would probably recommend setting the variable on the command line when you invoke the sub-make file. Wrap these definitions in a make variable for the sake of clarity. For example,
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
It's not the prettiest solution, but it can be done from the parent makefile.
Apart from using Export which is not always recommended, you can pass variables to sub-make files like this --
**HOSTCC = gcc**
CC= MIPS-GCC
FLAGS = -O2 -Wall -DSELECT_PROBLEM
M="CC=$(CC) $(FLAGS)"
all:
cd ../rng ; $(MAKE) $(M) **HOSTCC=$(HOSTCC)** ;
so if your sub-make file has 2 files each requires different compile toolchain you can do what is shown above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With