Using GNU Make 4.1
Summary
I am calling a sub-make b.mk from a makefile a.mk.
b.mk is called to ensure that a sub-system is built.
Sometimes I want to force a target of a.mk to be remade:
make -f a.mk <target> --always-make
When I do this, b.mk also considers all targets out of date, but I don't want it to.
Failed remedy
I have tried using make -f b.mk MAKEFLAGS=, as suggested in the manual
5.7.3 Communicating Options to a Sub-make, but with no luck.
Here is the gist of a.mk:
.PHONY: all
$(info ===> a.mk MAKEFLAGS: $(MAKEFLAGS))
all:
$(MAKE) -f b.mk y MAKEFLAGS=
and b.mk:
$(info ===> b.mk MAKEFLAGS: $(MAKEFLAGS))
y: x
cp $< $@
Now, even when b.mk would normally regard y as being up to date:
$ make -f b.mk y
===> b.mk MAKEFLAGS:
make: 'y' is up to date.
... y is remade when a.mk is called with --always-make (-B):
$ make -f a.mk --always-make
===> a.mk MAKEFLAGS: B
make -f b.mk y MAKEFLAGS=
make[1]: Entering directory '/home/matt/junk/make-b'
===> b.mk MAKEFLAGS:
cp x y
make[1]: Leaving directory '/home/matt/junk/make-b'
As you can see, the B flag appears in a.mk's MAKEFLAGS, but not in those of b.mk.
However, y is remade by b.mk.
Questions
- Why?
- Is there a way around this?
- With GNU make I would expect that there's a very good reason for this behaviour. What is the reason?
Update: 2020-08-05
Why (on earth) would I want to do this?
In the answer https://stackoverflow.com/a/63231100/685715, there was a request to see an example of wanting to force a particular target to be remade, but without wanting sub-makes forced too.
Rather than invent something, here is an extract from the actual makefile which led to my question:
WWW_SVG := score.svg
%Score.app/$(WWW_SVG): %Score.svg | %Score.app/
cd $(MUSIC_SCORE_PLAYER) && $(MAKE) -f $(MUSIC_SCORE_PLAYER_MAKEFILE) $(MUSIC_SCORE_PLAYER_TGT) MAKEFLAGS=
cp $< $(MUSIC_SCORE_PLAYER_DIR)$(WWW_SVG)
node $(MUSIC_SCORE_PLAYER_SVG_CONVERTER) > $@
The purpose of the rule is to create one SVG from another. The new one mirrors the state of the SVG part of the DOM after a web application loads and modifies the original SVG.
- The first line of the recipe uses a sub-make to ensure that the web application is up to date, which it may not be as I am currently developing it. The web app is a separate project to the one with the makefile from which the above snippet was extracted.
- The second line copies the original SVG into the web app's deployment directory so that it can be loaded by the web app
- The third line calls a node script to launch the web app, extract the SVG from its DOM, and write it to stdout. This is then redirected to update the SVG target.
While I am testing, I want to be able to force the re-making of targets which have prerequisites that match %FooScore/score.svg, but without rebuilding the web application, unless it is out of date.
Of course, I could move the line that calls the sub-make so that it would be invoked just once, not once for every target that matches the rule. But that is an optimization, not a solution.