Я немного использовал rake (программу Ruby make), и у нее есть возможность получить список всех доступных целей, например
> rake --tasks
rake db:charset # retrieve the charset for your data...
rake db:collation # retrieve the collation for your da...
rake db:create # Creates the databases defined in y...
rake db:drop # Drops the database for your curren...
...
но, кажется, нет никакой возможности сделать это в GNU make.
Похоже, код почти готов для этого, по состоянию на 2007 год - http://www.mail-archive.com/help-make@gnu.org/msg06434.html .
В любом случае, я немного взломал, чтобы извлечь цели из make-файла, который вы можете включить в make-файл.
list:
@grep '^[^#[:space:]].*:' Makefile
Это даст вам список определенных целей. Это только начало - например, оно не отфильтровывает зависимости.
> make list
list:
copy:
run:
plot:
turnin:
alias makefile-targets='grep "^[^#[:space:]].*:" Makefile'
чаще всего мне просто нужно проверить текущий make-файл, и расширение bash расширяется мой псевдоним.grep : Makefile
:?Ответы:
Это попытка улучшить отличный подход @ nobar следующим образом:
sh -c
)-f <file>
@
чтобы предотвратить его отображение перед выполнениемЛюбопытно, что в GNU
make
нет возможности перечислять только имена целей, определенных в make-файле.-p
Опция производит вывод , который включает в себя все цели, но хоронит их в много другой информации.Поместите следующее правило в make-файл для GNU,
make
чтобы реализовать именованную цель,list
которая просто перечисляет все имена целей в алфавитном порядке - то есть: invoke asmake list
:Важно : вставив это, убедитесь, что последняя строка имеет ровно 1 фактический символ табуляции. (пробелы не работают) .
Обратите внимание, что сортировка результирующего списка целей является наилучшим вариантом, поскольку не сортировка не создает полезного порядка в том порядке, в котором порядок появления целей в make-файле не сохраняется.
Кроме того, подцели правила, состоящего из нескольких целей, неизменно выводятся по отдельности и, следовательно, из-за сортировки обычно не появляются рядом друг с другом; Например, правило, начинающееся с
a z:
, не будет иметь целейa
иz
перечисляться рядом друг с другом в выходных данных, если есть дополнительные цели.Объяснение правила :
PHONY: list
$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null
make
снова, чтобы распечатать и проанализировать базу данных, полученную из make-файла:-p
печатает базу данных-Rr
подавляет включение встроенных правил и переменных-q
только проверяет текущее состояние цели (не переделывая ничего), но это само по себе не препятствует выполнению команд рецепта во всех случаях; следовательно:-f $(lastword $(MAKEFILE_LIST))
гарантирует, что тот же make-файл нацелен как на исходный вызов, независимо от того, был ли он нацелен неявно или явно-f ...
.Предостережение : это сломается, если ваш make-файл содержит
include
директивы; чтобы решить эту проблему, определите переменнуюTHIS_FILE := $(lastword $(MAKEFILE_LIST))
перед любымinclude
директивами и используйте-f $(THIS_FILE)
вместо нее.:
является намеренно недействительной целью, которая предназначена для обеспечения того, чтобы никакие команды не выполнялись ;2>/dev/null
подавляет полученное сообщение об ошибке. Примечание.-p
Тем не менее, это зависит от печати базы данных, которая имеет место в GNU make 3.82. К сожалению, GNU Make предлагает не прямой вариант , чтобы просто распечатать базу данных, без также выполнения по умолчанию (или заданной) задачи; если вам не нужен целевой Makefile, вы можете использовать егоmake -p -f/dev/null
, как рекомендуется наman
странице.-v RS=
/^# File/,/^# Finished Make data base/
if ($$1 !~ "^[#.]")
#
... игнорирует нецелевые объекты, чьи блоки начинаются с# Not a target:
.
... игнорирует специальные цели:
egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
удаляет нежелательные цели из вывода:'^[^[:alnum:]]'
... исключает скрытые цели, которые, по соглашению, являются целями, которые не начинаются ни с буквы, ни с цифры.'^$@$$'
... исключаетlist
саму цельЗапуск
make list
затем печатает все цели, каждая на своей линии;xargs
вместо этого вы можете создать список, разделенный пробелами.источник
rake --tasks
это?-n
вариант.-n
опции - «Распечатать команды, которые будут выполнены ...» - другими словами: функция пробного запуска. Также не то что ваша цитата отсутствует italicization слова просто :make -p
сам по себе делает печать базы данных, но неизменно также выполняет задачу по умолчанию ; руководство рекомендует неуклюжеmake -p -f/dev/null
избегать этого..PHONY: *
Под Bash (по крайней мере) это можно сделать автоматически с завершением табуляции:
make
spacetabtabисточник
. /etc/bash_completion
), и те, которые вообще не поддерживают его. (например, OSX 10.9)bash-completion
упаковке. Найдено в Fedora, RHEL, Gentoo и т. Д.$(RUN_TARGETS): run-%: ...
Это, очевидно, не будет работать во многих случаях, но если ваш
Makefile
был создан CMake, вы могли бы запуститьmake help
.источник
touch CMakeLists.txt && cmake . && make help
и это должно работать. Я могу только догадываться, что вы используете древний cmake или не используете генератор Unix Makefiles?Я объединил эти два ответа: https://stackoverflow.com/a/9524878/86967 и https://stackoverflow.com/a/7390874/86967 и сделал несколько экранировок, чтобы их можно было использовать из make-файла.
,
источник
sh -c "…"
не нужно, потому что это то, чтоmake
по умолчанию используется для вызова команд рецепта; (б) используемая вами команда слишком упрощена, что приводит к ложным срабатываниям (как вы заметили); (c) если вы добавите к команде префикс@
, она не будет передана на стандартный вывод перед выполнением, что устраняет необходимость использования-s
при вызове.make -s
(через псевдоним Bash), а не префиксировать команды в make-файле с помощью@
. В некоторых случаях это@
может быть полезно, особенно в качестве префикса дляecho
команд (когда отображение команды будет избыточным), но в целом я не люблю его использовать. Таким образом, я могу видеть «рецепты», когда мне нужно ( не используя-s
), но обычно нет. Вот соответствующая документация: Руководство по GNU Make, 5.2 Повторение рецепта .Если у вас есть
make
установленное завершение bash , скрипт завершения определит функцию_make_target_extract_script
. Эта функция предназначена для созданияsed
сценария, который можно использовать для получения целей в виде списка.Используйте это так:
источник
/etc/bash_completion
и / или функция_make_target_extract_script
- вы, кажется, находитесь на Ubuntu> 12. Если вы нацеливаетесь/usr/share/bash-completion/completions/make
вместо этого, ваш подход будет работать на дополнительных платформах, таких как Fedora 20. Существуют (более старые) платформы, которые имеют этот файл, но не функция (например, Debian 7 и Ubuntu 12); другие платформы, такие как OSX, вообще не идут с завершением табуляцииmake
. Возможно, было бы полезно опубликовать фактическое определение функции.Как указывает mklement0 , в GNU-make отсутствует функция для перечисления всех целей Makefile, и его ответ и другие вопросы предоставляют способы сделать это.
Тем не менее, в оригинальном посте также упоминается рейк , чей переключатель задач делает что-то немного отличное от простого перечисления всех задач в rakefile. Rake предоставит вам только список задач, с которыми связаны описания. Задачи без описания не будут перечислены . Это дает автору возможность предоставлять настраиваемые описания справки, а также опускать справку для определенных целей.
Если вы хотите эмулировать поведение рейка, когда вы предоставляете описания для каждой цели , для этого есть простой метод: вставлять описания в комментарии для каждой цели, которую вы хотите перечислить.
Вы можете поместить описание рядом с целью или, как я часто это делаю, рядом со спецификацией PHONY над целью, например:
Который даст
Вы также можете найти краткий пример кода в этом и здесь .
Опять же, это не решает проблему перечисления всех целей в Makefile. Например, если у вас есть большой Makefile, который, возможно, был сгенерирован или кто-то другой написал, и вы хотите быстрый способ перечислить свои цели, не просматривая его, это не поможет.
Однако, если вы пишете Makefile и вам нужен способ генерировать текст справки согласованным, самодокументируемым способом, этот метод может оказаться полезным.
источник
echo
команду в качестве описания команды ( stackoverflow.com/a/52059487/814145 ).@echo "Target 1"
это просто заполнитель, а не «команда echo description». Сгенерированный текст справки не приходит от@echo
. В реальном Makefile ониecho
будут заменены командой build или чем-то подобным. Я отредактирую пост, чтобы сделать это более понятным.Мой любимый ответ на это был опубликован Крисом Дауном в Unix & Linux Stack Exchange. Я процитирую
Пользователь Brainstone предлагает использовать трубопровод
sort -u
для удаления повторяющихся записей:Источник: Как перечислить все цели в make? (Unix & Linux SE)
источник
Ответ @ nobar показывает, как использовать завершение табуляции для вывода списка целей make-файла .
Это прекрасно работает для платформ, которые предоставляют эту функциональность по умолчанию (например, Debian, Fedora ).
На других платформах (например, Ubuntu ) вы должны явно загрузить эту функциональность, как подразумевается в ответе @ hek2mgl :
. /etc/bash_completion
устанавливает несколько функций завершения табуляции, в том числе дляmake
make
:. /usr/share/bash-completion/completions/make
-f <file>
.источник
Сосредоточившись на простом синтаксисе для описания цели создания и имея чистый вывод, я выбрал этот подход:
Так что, рассматривая вышесказанное как Makefile и запустив его, вы получите что-то вроде
Пояснение к цепочке команд:
источник
awk -F ':|##' '/^[^\t].+:.*##/ { printf "\033[36mmake %-28s\033[0m -%s\n", $$1, $$NF }' $(MAKEFILE_LIST) | sort
с##
комментарием перед той же строкой, что и цель. Но я думаю, что ваше решение позволяет до удобочитаемости.grep: parentheses not balanced
о моей машине OSX 10.15.Здесь много работоспособных решений, но, как мне нравится говорить, «если это стоит сделать один раз, то стоит сделать снова». Я высказал предположение о предложении использования (вкладка) (вкладка), но, как некоторые отмечали, у вас может не быть поддержки завершения, или, если у вас много включаемых файлов, вы можете захотеть более простой способ узнать, где определена цель.
Я не проверял нижеприведенное с суб-марками ... Я думаю, что это не сработает. Как известно, рекурсивный делает вредным.
Что мне нравится, потому что:
Объяснение:
Пример вывода:
источник
Это было полезно для меня, потому что я хотел видеть цели сборки, требуемые (и их зависимости) целью make. Я знаю, что создание целей не может начинаться с "." персонаж. Я не знаю, какие языки поддерживаются, поэтому я использовал скобочные выражения egrep.
источник
Это далеко не чисто, но сделал работу для меня.
Я использую
make -p
этот дамп внутренней базы данных, ditch stderr, использую быструю и грязную информацию,grep -A 100000
чтобы сохранить нижнюю часть вывода. Затем я очищаю вывод паройgrep -v
и, наконец, использую,cut
чтобы получить то, что находится перед двоеточием, а именно цели.Этого достаточно для моих вспомогательных скриптов на большинстве моих Makefiles.
РЕДАКТИРОВАТЬ: добавил,
grep -v Makefile
что это внутреннее правилоисточник
Это изменение очень полезного ответа jsp ( https://stackoverflow.com/a/45843594/814145 ). Мне нравится идея получить не только список целей, но и их описание. Makefile jsp помещает описание в качестве комментария, который, как я обнаружил, часто повторяется в команде echo description the description. Поэтому вместо этого я извлекаю описание из команды echo для каждой цели.
Пример Makefile:
Выход
make help
:Ноты:
echo
или:
в качестве первой команды рецепта.:
означает «ничего не делать». Я использую это здесь для тех целей, которые не нужны эхо, такие какall
цель выше.help
цели, чтобы добавить «:» вmake help
вывод.источник
Еще один дополнительный ответ на выше.
протестировано на MacOSX с использованием только cat и awk на терминале
будет вывод файла make, как показано ниже:
в Makefile это должен быть тот же оператор, убедитесь, что вы экранируете переменные, используя переменную $$, а не переменную $.
объяснение
кошка - выплевывает содержимое
| - труба анализирует вывод на следующий awk
awk - запускает регулярное выражение, исключая "shell" и принимая только строки "Az", затем выводит первый столбец за $ 1
awk - еще раз удаляет последний символ ":" из списка
это грубый вывод, и вы можете делать более интересные вещи с помощью только AWK. Старайтесь избегать sed, поскольку он не так согласован в вариантах BSD, т.е. некоторые из них работают на * nix, но не работают на BSD, таких как MacOSX.
Больше
Вы должны иметь возможность добавить это (с изменениями) в файл для make , в папку завершения bash по умолчанию /usr/local/etc/bash-completion.d/, что означает, что когда вы «сделаете вкладку вкладки » ... она завершит цели основаны на сценарии с одним вкладышем.
источник
Я обычно делаю:
Это вернулось бы с чем-то вроде:
надеюсь, это поможет
источник
Для сценария Bash
Вот очень простой способ сделать это на
bash
основе комментария @ cibercitizen1 выше :Смотрите также более авторитетный ответ от @ Marc.2377, в котором говорится, как это
make
делает модуль завершения Bash .источник
не уверен, почему предыдущий ответ был таким сложным:
источник
$(SHELLS): ...
), (б) включение целей , которые начинаются с цифрой, (с) не- включение определений переменных , (d) нацеливание на соответствующий make-файл, если онmake
был указан с явным путем make-файла. (а) является решающим недостатком: даже если вы надежно нацелены на правильный make-файл, анализ необработанного файла не будет работать в общем случае из-за отсутствия расширения переменной.awk -F: '/^[A-z]/ {print $$1}' Makefile
. Наконец, в значительной степени академический момент: использование,[A-z]
а не[:alpha:]
означает, что вы пропустите цели, начинающиеся с иностранного символа, такого какá
.[[:alpha:]]
а не[:alpha:]
([:alpha:]
представляет набор букв с учетом локали внутри класса символов ([...]
), следовательно, эффективная потребность в двойном[[
/]]
.awk -F: '/^[A-Za-z]/ { print $$1 }' Makefile
использует один процесс и, мы надеемся, более правильное регулярное выражение (хотя вы, конечно, могли бы иметь цели с подчеркиванием, цифрами и т. д., как отмечалось в предыдущих комментариях)