Consider the following makefile:
# various settings, lots of them
# (supposed to be in defaults.mk)
option1="glob_val1"
option2="glob_val2"
#option3="glob_val3" # uncomment and it will override target-specific in sub-make
option4="glob_val4"
# goal is to make many items with various options
# which share common setup, but change in details.
all: item1 item2
# Item 1 is common + changed option3
item1: export option3="i1_val3"
item1:
@echo "start item1:option3=$(option3)"
$(MAKE) generic_item
@echo "done item1"
# Item 2 is common + another option3
item2: export option3="i2_val3"
item2:
@echo "start item2: option3=$(option3)"
$(MAKE) generic_item
@echo "done item2"
# This is generic item that does everything
# basing on options settings
generic_item:
@echo "do generic option3=$(option3) [expecting i<X>_val3 here]"
What I want is to override any of options in target and then call generic routine in 'generic_item'.
The issue is that if option3 is defined on top of the Makefile, it is passed unchanged into sub-make. If option3 on top is commented out, then all works as expected:
start item1:option3=i1_val3
make generic_item
make[1]: Entering directory `/tmp/make_items'
do generic option3=i1_val3 [expecting i<X>_val3 here]
make[1]: Leaving directory `/tmp/make_items'
done item1
start item2: option3=i2_val3
make generic_item
make[1]: Entering directory `/tmp/make_items'
do generic option3=i2_val3 [expecting i<X>_val3 here]
make[1]: Leaving directory `/tmp/make_items'
done item2
I don't want to use $(MAKE) option1=... option2=... generic_item syntax since it doesn't look good and there can be a lot of options with long values and all this will go into log and doesn't look good.
The goal is to have one common target that does stuff basing on values of options (lots of them) and ability to extend it with additional targets which only need to override specific values/add new actions and leave rest to the common target.
Please suggest another approach if my looks wrong.
The main fix is adding -e
to submake
I suggest a number of enhancements. The GNU Make manual is a treasure trove for this kind of advanced scripting.
Note that with the approach shown below the submake is hardly necessary. I only do submake when
For your convenience, I stuck with your submake approach to show you that it can be done:
export option="glob_val"
.SECONDEXPANSION: # http://www.gnu.org/s/hello/manual/make/Secondary-Expansion.html
TARGETS=item1 item2 item3 item4 item5
all: $(TARGETS)
$(TARGETS): option="$(@)_val"
$(TARGETS):
@echo "start $@:option=$(option)"
$(MAKE) -e generic_item
@echo "done $@"
generic_item:
@echo "do generic option=$(option)"
Output of make -s
start item1:option=item1_val
start item2:option=item2_val
start item3:option=item3_val
start item4:option=item4_val
start item5:option=item5_val
do generic option=item1_val
do generic option=item2_val
done item1
do generic option=item4_val
done item2
do generic option=item3_val
done item4
do generic option=item5_val
done item5
done item3