Aart Stuurman
Aart Stuurman

Reputation: 3588

How to prevent the prerequisite of a target from expanding when the target is not used?

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

Answers (2)

MadScientist
MadScientist

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

Matt
Matt

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

Related Questions