Почему включение файла в мой Makefile меняет мою переменную директории Makefile? - PullRequest
0 голосов
/ 05 ноября 2019

Чтобы вызывать мой Makefile из разных мест без путаницы относительных путей, я ссылаюсь на пути, используя переменную Makefile, как указано в другой ответ :

DIR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

Я получаю MAKEFILE_LIST отличается, когда я включаю другие файлы, но, поскольку я сохраняю его значение в переменной, прежде чем делать какие-либо включения, я удивляюсь, что значение переменной отличается.

Пример:

$ tree .
.
├── another_file
└── subdirectory
    └── Makefile

$ cat Makefile
DIR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

test:
    @echo $(DIR)

#include $(DIR)/../another_file

$ make
/subdirectory

Так же, какожидается. Но если я раскомментирую строку включения, я получу

$ make
/

, что для меня не имеет смысла, поскольку another_file по-прежнему включен без ошибок, указывающих, что значение $(DIR) равно /subdirectory.

Обратите внимание, что цель make помещается перед оператором include, и поведение не изменяется при переключении порядка. Полагаю, это связано с предварительной обработкой, но это все еще не объясняет мне, почему $(DIR) имеет разные значения.

$ make --version
GNU Make 3.81
...
This program built for i386-apple-darwin11.3.0

1 Ответ

1 голос
/ 05 ноября 2019

это потому, что значение MAKEFILE_LIST изменяется после include, а расширение переменной DIR происходит во время использования.

Я обрызгал ваш Makefile info для демонстрации

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

обратите внимание, как значение MAKEFILE_LIST изменилось после include, и вместе с этим значение DIR.

можно исправить одним способом. это происходит путем принудительного немедленного расширения DIR с использованием := вместо =

DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

, таким образом значение DIR рассчитывается один раз и не изменяется даже при изменении MAKEFILE_LIST.

другим способом было бы использовать firstword вместо lastword.

и учтите, что расширение DIR в рецепте для test происходит непосредственно перед выполнением этого рецепта. ,Вот почему не имеет значения, где include происходит относительно test.

, читайте здесь для получения дополнительной информации:


Не знаюзнать, как относиться к этой конструкции shell, чтобы получить каталог Makefile. Обычно Makefile от более высокого уровня включает Makefile из subdirs. Но у вас есть вариант использования. Я не буду спорить об этом здесь. Я надеюсь, что мое объяснение вкусов переменных помогает.

...