Reputation: 3588
In a Makefile with multiple targets, how can one prevent the prerequisites of targets that are not being used from expanding? See the following example:
thisexpands = $(warning Expanded!)
.PHONY: target1
target1: $(thisexpands)
@echo Target 1
.PHONY: target2
target2:
@echo Target 2
Calling target2
forces thisexpands
to expand, even though it is lazily evaluated and it and target1
are never used.
In my real world case expanding thisexpands
when calling target1
is an issue, because it is a shell command that prints errors when called out of context of target1 and it's parent targets(not shown here).
Upvotes: 0
Views: 291
Reputation: 100781
Makefiles are fully parsed before the first rule is run. As part of parsing, all the targets and prerequisites must be expanded. You can find details of when expansion happens for different parts of a makefile in How make Reads a Makefile in the GNU make manual.
One way is to use recursion:
thisexpands = $(warning Expanded!)
target1: ; $(MAKE) target1-recurse T1_DEPS='$(value thisexpands)'
T1_DEPS =
target1-recurse: $(T1_DEPS)
@echo Target 1
This doesn't work:
You can probably defer expansion by using secondary expansion, something like this:
.SECONDEXPANSION:
target1: $$(thisexpands)
Be very careful that you escape the prerequisite list appropriately.
Upvotes: 2
Reputation: 15081
There's no way to cancel the expansion completely. However, you can use the conditional assignment based on the value of $(MAKECMDGOALS)
:
thisexpands = $(if $(filter target1,$(MAKECMDGOALS)),$(warning Expanded!))
.PHONY: target1
target1: $(thisexpands)
@echo Target 1
.PHONY: target2
target2:
@echo Target 2
Note that it works if target1
is only built explicitly (make target1
) and not by default, or as a part of building another target.
Upvotes: 1