Як отримати список цілей у makefile?


202

Я трохи використовував рейки (програма Ruby make 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 .

У всякому разі, я зробив невеликий злом, щоб витягнути цілі з makefile, які ви можете включити в makefile.

list:
    @grep '^[^#[:space:]].*:' Makefile

Це дасть вам список визначених цілей. Це лише початок - це, наприклад, не фільтрує залежності.

> make list
list:
copy:
run:
plot:
turnin:

2
Я швидко прочитав відповіді, які цікаві, але до сих пір для себе я вважаю за краще тримати його простий, простий і портативний , використовуючи псевдонім (в моєму .bashrc): alias makefile-targets='grep "^[^#[:space:]].*:" Makefile' Найчастіше я просто необхідно вивчити поточну Makefile і завершальні Баш розростається мій псевдонім.
RockyRoad


4
Це занадто банально просто grep : Makefile:?
cibercitizen1

Відповіді:


130

Це спроба вдосконалити чудовий підхід @ nobar таким чином:

  • використовує більш надійну команду для вилучення імен цілі, що, сподіваємось, запобігає помилковим позитивам (а також усуває зайве sh -c)
  • не завжди орієнтується на makefile у поточному каталозі; поважає файли, чітко вказані з-f <file>
  • виключає приховані цілі - за умовою, це цілі, назва яких не починається ні з літери, ні з цифри
  • робить з однією фальшивою ціллю
  • префіксує команду, @щоб запобігти її повторенню перед виконанням

Цікаво, що GNU makeне має функції перелічувати лише імена цілей, визначених у makefile. -pОпція виробляє висновок , який включає в себе всі цілі, але ховає їх в багато іншої інформації.

Розмістіть таке правило в makefile для GNU, makeщоб реалізувати ціль з ім'ям, listяка просто перелічує всі назви цілей в алфавітному порядку - тобто: call asmake list :

.PHONY: list
list:
    @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'

Важливо : вставивши це, переконайтеся, що останній рядок відведений точно на 1 фактичну таблицю вкладок. (пробіли не працюють) .

Зверніть увагу , що сортування в результаті списку завдань є найкращим варіантом, так як НЕ сортувати не виробляє корисний порядок в тому , що порядок , в якому об'єкти відображаються в Makefile це НЕ зберігся.
Крім того, підцілі правила, що містять декілька цілей, незмінно виводяться окремо і, отже, через сортування зазвичай не з’являться поруч; наприклад, правило, що починається з a z:, не матиме цілей aі zперераховується один біля одного у висновку, якщо є додаткові цілі.

Пояснення правила :

  • .PHONY: list
    • оголошує цільовий список фальшивою ціллю, тобто такою, що не посилається на файл , у зв'язку з чим повинен бути безумовно викликаний його рецепт
  • $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null

    • makeЗнову запрошуємо , щоб надрукувати та проаналізувати базу даних, отриману з makefile:
      • -p друкує базу даних
      • -Rr пригнічує включення вбудованих правил та змінних
      • -qперевіряє лише оновлений стан цілі (не переробляючи нічого), але це само по собі не перешкоджає виконанню команд рецептів у всіх випадках; звідси:
      • -f $(lastword $(MAKEFILE_LIST))гарантує, що той самий makefile орієнтований, як і в оригінальному виклику, незалежно від того, націлений він явно чи явно -f ....
        Caveat : це порушиться, якщо ваш makefile містить includeдирективи; щоб вирішити це, визначте змінну THIS_FILE := $(lastword $(MAKEFILE_LIST)) перед будь-якими includeдирективами та використовуйте -f $(THIS_FILE)натомість.
      • :- цілеспрямовано недійсна ціль, яка покликана забезпечити виконання команд ; 2>/dev/nullпригнічує отримане повідомлення про помилку. Примітка. -pТим не менш, це покладається на друк бази даних, що є випадком GNU 3,82. На жаль, GNU не пропонує прямого варіанту просто друкувати базу даних, не виконуючи також завдання (або задане) за замовчуванням; якщо вам не потрібно орієнтуватися на певний Makefile, ви можете використовувати make -p -f/dev/null, як рекомендовано на manсторінці.
  • -v RS=

    • Це дивна ідіома, яка розбиває вхід на блоки суміжних не порожніх рядків.
  • /^# File/,/^# Finished Make data base/
    • Відповідає діапазону рядків у висновку, який містить усі цілі (вірно з GNU складають 3,82) - обмежуючи аналіз на цей діапазон, не потрібно мати справу з помилковими позитивами з інших вихідних розділів.
  • if ($$1 !~ "^[#.]")
    • Вибірково ігнорує блоки:
      • # ... ігнорує нецілі, блоки яких починаються з # Not a target:
      • . ... ігнорує спеціальні цілі
    • Усі інші блоки повинні починатись з рядка, що містить лише ім'я чітко визначеної цілі, за якою слід :
  • egrep -v -e '^[^[:alnum:]]' -e '^$@$$' видаляє небажані цілі з виводу:
    • '^[^[:alnum:]]'... виключає приховані цілі, які - за умовою - це цілі, які не починаються ні з літери, ні з цифри.
    • '^$@$$'... виключає саму listціль

Після цього Run - make listдрукує всі цілі, кожен у своєму рядку; Ви можете xargsстворити список для створення списку, розділеного пробілом.


Це чудова відповідь, проте як би я отримав опис кожного завдання? В даний час я зберігаю це як коментар вище визначення завдання. Не впевнені, чи можливо включити його до списку аналогічно, як rake --tasksце?
Пьотр Кучинський

1
@PiotrKuczynski: Цікаве запитання, але я пропоную вам опублікувати його як нове запитання (вказуючи на це для довідки).
mklement0

"На жаль, GNU не пропонує прямого вибору просто надрукувати базу даних." Є -nваріант.
Bulletmagnet

@Bulletmagnet: Метою -nопції є "Друк команд, які були б виконані ..." - іншими словами: функція сухого запуску. Також не те що ваша цитата відсутня italicization слова просто : make -pсам по собі робить друк бази даних, але незмінно також виконує завдання за замовчуванням ; Посібник рекомендує незграбність, make -p -f/dev/nullщоб цього уникнути.
mklement0

1
Також буде перераховано будь-які цілі .PHONY, тому переконайтеся, що у вас немає.PHONY: *
tekumara

189

У розділі Bash (принаймні) це можна зробити автоматично із заповненням вкладки:

make spacetabtab


1
Перевірено: bash --версія = 4.2.45 (1) -випуск. make --версія = 3,81.
nobar

53
+1, але зауважте, що це не баш- функція, а залежить від вашої платформи . Платформи поділяються на три категорії: ті, де це завершення встановлено за замовчуванням (наприклад, Debian 7, Fedora 20), ті, де ви можете його додатково встановити (наприклад, Ubuntu 14, з . /etc/bash_completion), і ті, які його взагалі не підтримують. (наприклад, OSX 10.9)
mklement0

8
він працює на OS X 10.10 (не з bash, а з zsh).
Флоріан Освальд

4
Відмінна порада, але також потрібен bash-completionпакет. Знайдено у Fedora, RHEL, Gentoo, ect.
NoelProf

4
Це не працює з програмно створеними цілями AFAICT, наприклад$(RUN_TARGETS): run-%: ...
Маттіас

31

Це, очевидно, не спрацює у багатьох випадках, але якщо ваш Makefileстворений CMake, ви, можливо, зможете запустити make help.

$ make help
The following are some of the valid targets for this Makefile:
... all (the default if no target is provided)
... clean
... depend
... install
etc

Чи є у вас можливість увімкнути свій CMakeList, щоб отримати це? У мене з'явився макет-файл, створений CMake, і у мене немає мети допомоги псевдодопомоги
Xavier T.

Ні. На OSX, принаймні, з недавнього CMake (я фактично використовую солов’ї, але я вважаю, що коли я писав це, я використовував 3.3), просто запустіть, touch CMakeLists.txt && cmake . && make helpі він повинен працювати. Я можу лише здогадуватися, що ви використовуєте старовинний cmake або не використовуєте генератор Unix Makefiles?
Timmmm

Я використовую CMake 3.6.2 з генератором Unix для Windows. Я буду копатися, щоб шукати пояснення, бо це здається зручним.
Xavier T.

26

Я поєднав ці дві відповіді: https://stackoverflow.com/a/9524878/86967 та https://stackoverflow.com/a/7390874/86967 і зробив деякі втечі, щоб це можна було використовувати зсередини makefile.

.PHONY: no_targets__ list
no_targets__:
list:
    sh -c "$(MAKE) -p no_targets__ | awk -F':' '/^[a-zA-Z0-9][^\$$#\/\\t=]*:([^=]|$$)/ {split(\$$1,A,/ /);for(i in A)print A[i]}' | grep -v '__\$$' | sort"

.

$ make -s list
build
clean
default
distclean
doc
fresh
install
list
makefile ## this is kind of extraneous, but whatever...
run

10
Я також (нещодавно) виявив, що заповнення вкладки під Bash відображатиме список доступних цілей.
nobar

1
+1 для чудового підходу, але можна зробити декілька вдосконалень: (а) явне вказівка sh -c "…"непотрібна, тому що це makeза замовчуванням використовується для виклику команд рецептів; (b) команда, яку ви використовуєте, надто спрощена, що призводить до помилкових позитивів (як зазначаєте); (c) якщо ви будете префіксувати команду за допомогою @, вона не буде перегукуватися на stdout перед виконанням, що заперечує необхідність використання -sпри виклику.
mklement0

1
є набагато простіша цільова мета, яку ви могли б додати: list: cat Makefile | grep "^ [Az]" | awk '{print $$ 1}' | sed "s /: // g | sort"
thamster

2
Підхід кота / седа провалюється на декількох рівнях. Він не розширює змінні, а також не перераховує цілі, які є результатом включення інших файлів.
Troy Daniels

1
@ mklement0: Я вважаю за краще використовувати make -s(через псевдонім Bash), а не префіксування команд у makefile за допомогою @. Є деякі випадки, коли це @може бути корисним, зокрема, як префікс echoкоманд (де відображення команди було б зайвим), але в цілому я не люблю її використовувати. Таким чином, я бачу "рецепти", коли мені потрібно ( не використовуючи -s), але зазвичай. Ось відповідна документація: Інструкція з виготовлення GNU, 5.2 Рецепт відлуння .
nobar

14

Якщо у вас встановлено bash завершення для makeвстановленого, сценарій завершення визначатиме функцію _make_target_extract_script. Ця функція призначена для створення sedсценарію, який можна використовувати для отримання цілей у списку.

Використовуйте його так:

# Make sure bash completion is enabled
source /etc/bash_completion 

# List targets from Makefile
sed -nrf <(_make_target_extract_script --) Makefile

3
Корисно, але зауважте, що не всі платформи мають сценарій /etc/bash_completionта / або функцію _make_target_extract_script- ви, схоже, перебуваєте на Ubuntu> 12. Якщо ви націлите /usr/share/bash-completion/completions/makeнатомість, ваш підхід буде працювати на додаткових платформах, таких як Fedora 20. Є (старші) платформи, які мають цей файл, але не функція (наприклад, Debian 7 та Ubuntu 12); інші платформи, такі як OSX, взагалі не мають завершення вкладки make. Можливо, розміщення фактичного визначення функції було б корисним.
mklement0

1
Дякуємо за ваш коментар Це дуже цінується. Так, я перевірив це на Ubuntu 14.04
hek2mgl

11

Як вказує mklement0 , у GNU make відсутня функція для переліку всіх цілей Makefile, і його відповідь та інші надають способи цього зробити.

Однак у початковому дописі також згадується граблі , чиї перемикання завдань чимось дещо відрізняються, ніж просто перелік усіх завдань у рейкефілі. Rake дасть вам лише перелік завдань, які мають пов'язані описи. Завдання без описів не будуть перераховані . Це дає автору можливість як надавати індивідуальні описи довідки, так і опускати допомогу для певних цілей.

Якщо ви хочете наслідувати поведінку граблів, де ви надаєте описи для кожної цілі , існує проста техніка для цього: вбудовуйте описи в коментарі до кожної цілі, яку ви хочете перерахувати.

Ви можете або поставити опис поруч із ціллю, або, як я часто це роблю, поруч із специфікацією PHONY над ціллю, як це:

.PHONY: target1 # Target 1 help text
target1: deps
    [... target 1 build commands]

.PHONY: target2 # Target 2 help text
target2:
    [... target 2 build commands]

...                                                                                                         

.PHONY: help # Generate list of targets with descriptions                                                                
help:                                                                                                                    
    @grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20

Який дасть урожай

$ make help
target1             Target 1 help text
target2             Target 2 help text

...
help                Generate list of targets with descriptions

Ви також можете знайти короткий приклад коду в цій суті і тут .

Знову ж таки, це не вирішує проблему переліку всіх цілей у Makefile. Наприклад, якщо у вас є великий Makefile, який, можливо, був сформований або якийсь інший написав, і ви хочете швидкий спосіб перерахувати його цілі, не перекопуючи їх, це не допоможе.

Однак якщо ви пишете Makefile і хочете, щоб генерувати довідковий текст послідовно, самостійно документуючи, ця методика може бути корисною.


Це чудова техніка - приємна і проста, але також дає описи!
Брайан Бернс

Чудова техніка. Я трохи змінив це, щоб використовувати echoкоманду як опис команди ( stackoverflow.com/a/52059487/814145 ).
Penghe Geng

@PengheGeng Дякую за повідомлення. Я хочу уточнити, що @echo "Target 1"це просто заповнювач, а не "команда ехо-опису". Сформований довідковий текст не надходить від @echo's. У реальному Makefile, вони echoбудуть замінені командою build або деяким-таким. Я відредагую публікацію, щоб зробити це більш зрозумілим.
jsp

4

Відповідь @ nobar корисно показує, як використовувати доповнення вкладки для переліку цілей makefile .

  • Це чудово підходить для платформ, які надають цю функціональність за замовчуванням (наприклад, Debian, Fedora ).

  • На інших платформах (наприклад, Ubuntu ) ви повинні явно завантажити цю функціональність, як мається на увазі у відповіді @ hek2mgl :

    • . /etc/bash_completion встановлює кілька функцій заповнення вкладок, включаючи одну для make
    • Крім того, встановити лише завершення вкладки для make:
      • . /usr/share/bash-completion/completions/make
  • Для платформ, які взагалі не пропонують таку функціональність , як OSX , ви можете надати наступні команди (адаптовані звідси ) для її реалізації:
_complete_make() { COMPREPLY=($(compgen -W "$(make -pRrq : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($1 !~ "^[#.]") {print $1}}' | egrep -v '^[^[:alnum:]]' | sort | xargs)" -- "${COMP_WORDS[$COMP_CWORD]}")); }
complete -F _complete_make make
  • Примітка. Це не так складно, як функція завершення вкладок, що постачається з дистрибутивами Linux: головне, вона незмінно націлена на makefile у поточному каталозі , навіть якщо командний рядок націлений на інший makefile -f <file>.

4

Мою улюблену відповідь на це опублікував Кріс Даун на Unix & Linux Stack Exchange. Я цитую.

Ось так модуль завершення bash makeотримує свій список:

make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'

Він виводить список обмежених рядків, визначений новим рядком, без підказок.

Користувач Brainstone пропонує трубопроводів sort -uдля видалення повторюваних записів:

make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}' | sort -u

Джерело: Як перелічити всі цілі, які можна зробити? (Unix та Linux SE)


4

Сфокусувавшись на простому синтаксисі для опису цілі make і маючи чистий результат, я вибрав такий підхід:

help:
    @grep -B1 -E "^[a-zA-Z0-9_-]+\:([^\=]|$$)" Makefile \
     | grep -v -- -- \
     | sed 'N;s/\n/###/' \
     | sed -n 's/^#: \(.*\)###\(.*\):.*/\2###\1/p' \
     | column -t  -s '###'


#: Starts the container stack
up: a b
  command

#: Pulls in new container images
pull: c d 
    another command

make-target-not-shown:

# this does not count as a description, so leaving
# your implementation comments alone, e.g TODOs
also-not-shown:

Тож трактування вищезазначеного як Makefile та його виконання дає щось подібне

> make help
up          Starts the container stack
pull        Pulls in new container images

Пояснення ланцюжка команд:


Дуже приємне рішення. Я використовую це вже кілька років: awk -F ':|##' '/^[^\t].+:.*##/ { printf "\033[36mmake %-28s\033[0m -%s\n", $$1, $$NF }' $(MAKEFILE_LIST) | sort з ##коментарем до того ж рядка, що і цільовий. Але я думаю, що ваше рішення дозволяє перед читанням.
торок

Makefile складається з перших двох рядків звітів grep: parentheses not balancedна моїй машині OSX 10.15.
Малькольм Крум

@Crummy Вибачте, моя помилка. Дякуємо, що вказали на це. Виправлено це. make вимагає уникнути знаків долара, які не повинні починати імена змінних.
Річард Кіфер

Слідкуйте, StackOverflow перетворює вкладки в пробіли, коли відображаються розділи коду вище, але для Makefiles потрібні вкладки. Ви можете відредагувати публікацію, а потім скопіювати розділи, щоб вкладки збереглися.
Річард Кіфер

2

Тут є безліч ефективних рішень, але, як я люблю говорити, "якщо варто зробити один раз, варто зробити ще раз". Я подав пропозицію використовувати (вкладку) (вкладку), але, як деякі зауважили, у вас, можливо, немає підтримки для завершення, або, якщо у вас є багато файлів включення, ви, можливо, хочете простіший спосіб дізнатися, де визначена ціль.

Я не тестував нижче з підмайстрами ... Я думаю, це не спрацювало б. Як ми знаємо, рекурсивна ситуація вважається шкідливою.

.PHONY: list ls
ls list :
    @# search all include files for targets.
    @# ... excluding special targets, and output dynamic rule definitions unresolved.
    @for inc in $(MAKEFILE_LIST); do \
    echo ' =' $$inc '= '; \
    grep -Eo '^[^\.#[:blank:]]+.*:.*' $$inc | grep -v ':=' | \
    cut -f 1 | sort | sed 's/.*/  &/' | sed -n 's/:.*$$//p' | \
    tr $$ \\\ | tr $(open_paren) % | tr $(close_paren) % \
; done

# to get around escaping limitations:
open_paren := \(
close_paren := \)

Що мені подобається тому, що:

  • список цілей за включенням файлу.
  • виводити необроблені визначення динамічних цілей (замінює змінні роздільники модулем)
  • вивести кожну ціль у новий рядок
  • здається зрозумілішим (суб'єктивна думка)

Пояснення:

  • файл foreach у MAKEFILE_LIST
  • вивести ім'я файлу
  • греп-рядки, що містять двокрапку, які не мають відступів, не коментарі, і не починаються з періоду
  • виключити вирази негайного призначення (: =)
  • залежність від скорочення, сортування, відступу та рубання (після двокрапки)
  • munge змінні роздільники, щоб запобігти розширенню

Вибірка зразка:

 = Makefile = 
  includes
  ls list
 = util/kiss/snapshots.mk = 
  rotate-db-snapshots
  rotate-file-snapshots
  snap-db
  snap-files
  snapshot
 = util/kiss/main.mk = 
  dirs
  install
   %MK_DIR_PREFIX%env-config.php
   %MK_DIR_PREFIX%../srdb

1

Ця програма була мені корисною, оскільки я хотів бачити цілі побудови, необхідні (та їх залежності) для цілі make. Я знаю, що створення цілей не може починатися з знака "." характер. Я не знаю, які мови підтримуються, тому я перейшов із дужними виразами egrep.

cat Makefile | egrep "^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$"

1

Це далеко не чисто, але для мене це зробило.

make -p 2&>/dev/null | grep -A 100000 "# Files" | grep -v "^$" | grep -v "^\(\s\|#\|\.\)" | grep -v "Makefile:" | cut -d ":" -f 1

Я використовую, make -pщо скидає внутрішню базу даних, канаву stderr, використовую швидку і брудну, grep -A 100000щоб зберегти нижню частину виводу. Потім я очищую вихід з парою grep -vі, нарешті, використовую, cutщоб отримати те, що знаходиться перед товстою кишкою, а саме цілі.

Цього достатньо для моїх помічників сценаріїв на більшості моїх Makefiles.

EDIT: додано, grep -v Makefileщо це внутрішнє правило


1

Це зміна дуже корисної відповіді jsp ( https://stackoverflow.com/a/45843594/814145 ). Мені подобається ідея отримати не лише перелік цілей, а й їх описи. Makefile jsp описує опис як коментар, який я часто знаходив, буде повторюватися в команді ехо-опису цілі. Тому замість цього я витягую опис із команди ехо для кожної цілі.

Приклад Makefile:

.PHONY: all
all: build
        : "same as 'make build'"

.PHONY: build
build:
        @echo "Build the project"

.PHONY: clean
clean:
        @echo "Clean the project"

.PHONY: help
help:
        @echo -n "Common make targets"
        @echo ":"
        @cat Makefile | sed -n '/^\.PHONY: / h; /\(^\t@*echo\|^\t:\)/ {H; x; /PHONY/ s/.PHONY: \(.*\)\n.*"\(.*\)"/    make \1\t\2/p; d; x}'| sort -k2,2 |expand -t 20

Вихід make help:

$ make help
Common make targets:
    make all        same as 'make build'
    make build      Build the project
    make clean      Clean the project
    make help       Common make targets

Примітки:

  • Так само, як у відповіді jsp , у списку можуть бути лише цілі PHONY, які можуть чи не можуть працювати у вашому випадку
  • Крім того, він містить лише ті цілі PHONY, які мають команду echoабо :команду як першу команду рецепта. :означає "нічого не робити". Я використовую його тут для тих цілей, у яких не потрібне відлуння, як-от allцільова вище.
  • Існує додатковий трюк для helpцілі, щоб додати ":" у make helpвисновку.

0

Ще одна додаткова відповідь на вище.

перевірена на MacOSX, використовуючи лише cat та awk на терміналі

cat Makefile | awk '!/SHELL/ && /^[A-z]/ {print $1}' | awk '{print substr($0, 1, length($0)-1)}'

виведе файл make, як показано нижче:

ціль1

ціль2

ціль3

у Makefile це має бути той самий вислів, переконайтесь, що ви уникаєте змінних, використовуючи змінну $$, а не $ змінну.

Пояснення

кішка - випльовує вміст

| - труби аналізують вихід на наступний awk

awk - запускає регулярні вирази, виключаючи "оболонку" і приймаючи лише рядки "Az", після чого виводить перший стовпець $ 1

awk - ще раз видаляє останній символ ":" зі списку

це приблизний вихід, і ви можете робити більш прикольні речі лише AWK. Постарайтеся уникати sed, оскільки його не так послідовно у варіантах BSD, тобто деякі роботи на * nix, але не вдається на BSD, таких як MacOSX.

Більше

Ви повинні мати змогу додати це (з модифікаціями) до файлу для створення , до папки bash-завершення за замовчуванням /usr/local/etc/bash-completion.d/, що означає, коли ви "зробите вкладку вкладки ". цілі на основі сценарію одного вкладиша.


Ви також можете використовувати make -qp, а не cat. тому він стане make -qp | awk '/: / &&! /: = / && / ^ [Az] / &&! / PATH / &&! / DISPLAY / &&! / TERM_SESSION / &&! / USER_TEXT_ENCODING / &&! / Makefile / {print substr ($ 0, 1 , довжина ($ 0) -1) | "sort -u"} '
Джиммі МГ Лім

0

Я зазвичай роблю:

grep install_targets Makefile

Це повернеться з чимось на кшталт:

install_targets = install-xxx1 install-xxx2 ... etc

Я сподіваюся, що це допомагає


0

Для сценарію Баша

Ось дуже простий спосіб зробити це bash- на основі коментаря @ cibercitizen1 вище :

grep : Makefile | awk -F: '/^[^.]/ {print $1;}'

Дивіться також більш авторитетну відповідь від @ Marc.2377, яка говорить про те, як це makeробить модуль завершення Bash .


-4

не впевнений, чому попередня відповідь була такою складною:

list:
    cat Makefile | grep "^[A-z]" | awk '{print $$1}' | sed "s/://g" 

8
Попередній відповідь настільки складний, оскільки він охоплює всі сценарії , що ваша відповідь не поширюється на : (а) включення цілей , визначених з допомогою змінних (наприклад, $(SHELLS): ...), (б) включення цілей , які починаються з цифрою, (с) не- включення змінних визначень (d) націлювання на належний makefile, якщо він makeбув визначений явним шляхом makefile. (а) є вирішальним недоліком: навіть якщо ви надійно націлили правильний makefile, аналіз сирого файлу не буде працювати в загальному випадку через відсутність змінної розширення.
mklement0

6
Як і в сторону, знову ускладнено: ваша команда може бути спрощена до наступного - але головне полягає в тому , що це не досить міцним : awk -F: '/^[A-z]/ {print $$1}' Makefile. Нарешті, багато в чому академічний момент: використовуючи, [A-z]а не [:alpha:]означає, що ви будете пропускати цілі, які починаються із іноземного характеру, наприклад á.
mklement0

@ mklement0 ваша перша команда awk працює чудово, і є найпростішою поки що, хоча використання [: alpha:], здається, зламає її чомусь - вона пропускає деякі цілі в тестовому файлі.
Брайан Бернс

@ bburns.km: Моє погано: я мав би сказати, [[:alpha:]]а не [:alpha:]( [:alpha:]представляє набір знаків літер усередині класу символів ( [...]), отже, ефективна потреба у подвійному [[ / ]].
mklement0

4
Чому ця відповідь настільки складна? Вам вдається зібрати кілька непотрібних гріхів у цьому короткому фрагменті. awk -F: '/^[A-Za-z]/ { print $$1 }' Makefileвикористовує єдиний процес і, сподіваємось, більш правильний регулярний вираз (хоча, звичайно, ви також можете мати цілі з підкресленнями, цифрами тощо, як зазначалося в попередніх коментарях).
трійка
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.