Получение имени make-файла из make-файла - PullRequest
20 голосов
/ 09 сентября 2009

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

Спасибо.

Примечание:

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

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

Ответы [ 6 ]

11 голосов
/ 09 сентября 2009
location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
WHERE_ART_THOU := $(location)
$(warning $(WHERE_ART_THOU))

Я также считаю, что это GNU-специфика, но я не слишком уверен.

9 голосов
/ 09 сентября 2009

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

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

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

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

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

rule:
        echo In makefile $(current_makefile):
        echo Making target $@

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

this_makefile_unique_name := $(current_makefile)
rule:
        echo In makefile $(current_makefile):
        echo Making target $@

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

define make_rule
rule:
        echo In makefile $(1):
        echo Making target $$@

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

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

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

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


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

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

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

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

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

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

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

Это полезно?

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

3 голосов
/ 09 сентября 2009

Быстрый экскурс в Google предлагает на этом сайте есть ответ.

2 голосов
/ 14 сентября 2009

Я хотел сделать нечто подобное (для отображения содержимого 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`
1 голос
/ 26 января 2011

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

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

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

0 голосов
/ 18 ноября 2009

G'day,

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

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

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

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

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...