Reputation: 1954
In order invoke my Makefile from different locations without messing up relative paths, I reference paths using a Makefile variable as given in another answer:
DIR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
I get that MAKEFILE_LIST
differs when I include other files, but since I store its value in a variable before making any includes, I am surprised that the variable value differs.
Example:
$ tree .
.
├── another_file
└── subdirectory
└── Makefile
$ cat Makefile
DIR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
test:
@echo $(DIR)
#include $(DIR)/../another_file
$ make
/subdirectory
Just as expected. But if I uncomment the include line, I get
$ make
/
Which does not make sense to me, because another_file
is still included without errors indicating that the value of $(DIR)
is /subdirectory
.
Note that the make target is placed before the include statement, and the behavior does not change when the order is switched. Guess this is due to preprocessing, but it still does not explain to me why $(DIR)
seems to have different values.
$ make --version
GNU Make 3.81
...
This program built for i386-apple-darwin11.3.0
Upvotes: 0
Views: 277
Reputation: 27063
this is because the value of MAKEFILE_LIST
changes after include
and the expansion of the variable DIR
happens at use time.
I sprinkled your Makefile with info
for demonstration
DIR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
$(info list1 $(MAKEFILE_LIST))
$(info dir1 $(DIR))
test:
@echo $(DIR)
include $(DIR)/../another_file
$(info list2 $(MAKEFILE_LIST))
$(info dir2 $(DIR))
output
$ make
list1 Makefile
dir1 /home/lesmana/tmp/maek/subdir
list2 Makefile /home/lesmana/tmp/maek/subdir/../another_file
dir2 /home/lesmana/tmp/maek
/home/lesmana/tmp/maek
note how the value of MAKEFILE_LIST
changed after the include
and with it the value of DIR
.
one way to fix this is by forcing immediate expansion of DIR
by using :=
instead of =
DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
that way the value of DIR
is calculated once and does not change even if MAKEFILE_LIST
changed.
another way would be to use firstword
instead of lastword
.
also note that the expansion of DIR
in the recipe for test
happens just before executing that recipe. That is why it does not matter where the include
happens relative to test
.
read here for more info:
I do not know how to feel about this shell
construct to get the dir of the Makefile. Usually Makefiles from higher up include the Makefile from the subdirs. But you have your use case. I will not argue about that here. I hope my explanation of the flavors of variable helps.
Upvotes: 1