Подтвердить что ты не робот

Получение имени файла makefile из make файла

Как получить имя файла makefile в make файле?

Спасибо.

Примечание:

Мне нужно это, потому что я хотел бы, чтобы мой make файл вызывал себя, но make файл не называется Makefile, поэтому я хотел бы написать что-то вроде этого:

target:
    ($MAKE) -f ($MAKEFILENAME) other_target
4b9b3361

Ответ 1

location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
WHERE_ART_THOU := $(location)
$(warning $(WHERE_ART_THOU))

Я также считаю, что это GNU make-specific, но я не уверен.

Ответ 2

(Если у вас есть какие-либо вопросы, обратитесь к удивительно написанному GNU make manual. Но помните, что так же, как Makefile, это руководство должно быть полностью прочитайте, прежде чем применять концепции на практике).

Я не мог понять, как это делается легко. Насколько я понимаю, вам нужно будет выполнить ручную работу.

Позже я опишу, как это можно сделать и показать скрипты, в которых представлена ​​переменная current_makefile. Но я хотел бы подчеркнуть важную концепцию в первую очередь.

Вы должны понимать, что если бы у нас была какая-то переменная current_makefile, которая расширяется до текущего имени файла makefile, тогда она должна измениться в процессе чтения make файлов. Это означает, что он должен использоваться внутри "непосредственного" контекста расширения, то есть внутри команд, которые выполняются во время чтения make файла. Большинство команд, однако, выполняются после чтения make файлов. Поэтому некоторые команды будут печатать правильное значение плавно, в то время как в определенных местах, где используется "отложенное" расширение, оно всегда будет расширяться до корневого имени файла makefile.

Если вы хотите использовать эту переменную в тексте правила, например, вам придется делать трюки, потому что текст правила всегда имеет отложенное расширение. Итак, если у вас есть правило

rule:
        echo In makefile $(current_makefile):
        echo Making target [email protected]

он всегда будет печатать имя корневого файла make. Вместо этого, чтобы принудительно произвести немедленное расширение, вам придется создать другую переменную с именем, специфичным для makefile (то есть имена таких переменных должны быть разными в каждом make файле):

this_makefile_unique_name := $(current_makefile)
rule:
        echo In makefile $(current_makefile):
        echo Making target [email protected]

или используйте eval:.

define make_rule
rule:
        echo In makefile $(1):
        echo Making target [email protected]

$(eval $(call make_rule,$(current_makefile)))

Если вы хотите использовать имя текущего файла makefile только для целей отладки, рассмотрите специальные функции отладки, такие как предупреждение или информация:.

$(warning We're in makefile $(current_makefile))

Эти функции используют "немедленное" расширение и печатают правильное значение.


Как определить такой файл $(current_makefile)?

Вам нужно вручную поддерживать стек включений makefile. Когда вы включаете make файл, его имя помещается в верхнюю часть стека; когда вы возвращаетесь из включенного makefile в внешний, самое верхнее имя выставляется из стека. Это достигается путем вставки специальных вызовов в начало и конец make файла:

# Beginning of makefile
$(eval $(makefile_names_push))
#... makefile text
$(warning $(current_makefile))
#...
$(eval $(makefile_names_pop))
#End of file

Теперь определите функции в начале файла make root.

lastword=$(word $(words $(1)),$(1))

define makefile_names_push
current_makefile := $$(CURDIR)/$$(call lastword,$$(MAKEFILE_LIST))
makefile_stack :=$$(makefile_stack) $$(current_makefile)
endef

define makefile_names_pop
makefile_stack := $$(filter-out $$(current_makefile),$$(makefile_stack))
current_makefile := $$(call lastword,$$(makefile_stack))
endef

Если вы уверены, что ваш make достаточно новый (версия 3.81+), замените вызов lastword на встроенную функцию:.

#inctead of $$(call lastword,$$(MAKEFILE_LIST))
$$(lastword $$(MAKEFILE_LIST))

Полезно ли это?

Совершенно бесполезно. Единственное, что может быть полезно здесь, это сделать 100 make файлов, которые являются символическими ссылками на один make файл, правила в этих make файлах в зависимости от их имен. Но это может быть достигнуто в рамках одного метода makefile и foreach-eval, описанного в руководстве. Так что мой пост был пустой тратой времени, хотя мне было весело: -)

Ответ 3

Быстрая экскурсия в Google предлагает this имеет ответ.

Ответ 4

Я хотел сделать что-то подобное (для отражения содержимого Makefile), когда я использую Make для управления простыми повторяющимися задачами. Я наткнулся на эту страницу и обнаружил, что это именно то, что мне нужно, и действительно полезно для моего ограниченного понимания дела.

Мой результат после прочтения этой страницы:


    # Makefile - 'make' and 'make help' now echo the makefile.
    help:
        cat $(lastword $(MAKEFILE_LIST))
    start:
        sudo -u www /path/to/webapp/myhttpd restart
    stop:
        sudo kill cat /path/to/webapp/data/httpd.pid
код>

Спасибо всем на этой странице.

Ответ 5

G'day,

Если вы сделаете копию своего исходного файла makefile, скажем makefile_test, а затем введите команду:

make -np -f makefile_test 2>&1 | tee output

Это будет оценивать make файл и вашу среду make, но не выполнять какие-либо команды. Просмотр выходного файла для ссылок на makefile_test покажет вам, что установлено в make-среде и где это значение задано.

N.B. Это может генерировать много информации! И не добавляйте переключатель -d (debug), который будет генерировать тонны дополнительного вывода о процессе принятия решений, но минимальная дополнительная информация о make env.

НТН

Ответ 6

Это возвращает имя первого вызываемого файла Makefile, то есть тот, который находится внизу стека вызовов:

MAKEFILE_JUSTNAME := $(firstword $(MAKEFILE_LIST))
MAKEFILE_COMPLETE := $(CURDIR)/$(MAKEFILE_JUSTNAME)

При использовании в неперекрестно-рекурсивных ситуациях (например, для makedepend) это просто имя текущего файла makefile.