mrjoops
mrjoops

Reputation: 38

Why my prerequisites automatic variable is empty?

Use case: I use many Makefiles that share some logic but differ notably in prerequisites, so I include a Common.mk file and use a PREREQ variable in all of them.

Problem: $(PREREQ) is correctly set but $^ is mysteriously empty

Reproduction:

Here is an example Common.mk

all: $(PREREQ)
        echo $^
        echo $(PREREQ)

A B:

and here is the Makefile

include Common.mk

PREREQ ?= A

Now here is the result of typing make at the prompt:

echo

echo A
A

I expected to have the same output but it's not the case. Amusingly, if you type make PREREQ=B or if you switch the two lines in the Makefile, it works as expected and $^ is correctly set.

I use GNU Make 4.3.

Why $^ is empty in this case ?

Upvotes: 0

Views: 68

Answers (2)

MadScientist
MadScientist

Reputation: 101111

Please see this discussion of when variables are expanded.

There you will see that prerequisites are expanded when make reads the makefile and parses the line, while variables inside the recipe are expanded when the recipe is going to be invoked.

Your makefile:

include Common.mk

PREREQ ?= A

Is the same thing to make as if you'd written it all in one file, so it looks like this:

all: $(PREREQ)
        echo $^
        echo $(PREREQ)

A B:

PREREQ ?= A

You can see that at the time the all rule definition is parsed, PREREQ is not set yet. This means that the all rule expands to this:

all:
        echo $^
        echo $(PREREQ)

And so the $^ variable is empty. If you change your makefile to this:

PREREQ ?= A

include Common.mk

it will work as you expect.

Upvotes: 1

Croisen
Croisen

Reputation: 1

This is just a guess but maybe with the ?= operator is the culprit. As it only assigns it after it checks that the variable PREREQ is empty.

Now when using

> make PREREQ=B

the variable is already assigned to PREREQ and does not require some sort of downtime I say to get the $^ auto variable.

Try running the example makefile with (granted I have version 4.4.1, and do not know if this option is available to you)

> make --warn-undefined-variables

To me it output this:

> make --warn-undefined-variables
some.mk:1: warning: undefined variable 'PREREQ'
echo 

echo A
A

Hope this helps

Upvotes: 0

Related Questions