Użyłem trochę prowizji (program do tworzenia Ruby) i ma opcję uzyskania listy wszystkich dostępnych celów, np.
> 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...
...
ale wydaje się, że nie ma takiej możliwości w GNU make.
Najwyraźniej kod jest już prawie gotowy, począwszy od 2007 r. - http://www.mail-archive.com/[email protected]/msg06434.html .
W każdym razie zrobiłem niewielki hack, aby wyodrębnić cele z makefile, który możesz dołączyć do makefile.
list:
@grep '^[^#[:space:]].*:' Makefile
Daje ci listę zdefiniowanych celów. To tylko początek - na przykład nie filtruje zależności.
> make list
list:
copy:
run:
plot:
turnin:
alias makefile-targets='grep "^[^#[:space:]].*:" Makefile'
Najczęściej muszę tylko sprawdzić aktualny plik makefile, a uzupełnianie bash rozszerza się mój alias.grep : Makefile
?Odpowiedzi:
Jest to próba ulepszenia wspaniałego podejścia @ nobar w następujący sposób:
sh -c
)-f <file>
@
poprzedza polecenie znakiem, aby zapobiec jego powtórzeniu przed wykonaniemCo ciekawe, GNU
make
nie ma funkcji wyświetlania tylko nazw celów zdefiniowanych w makefile. Ta-p
opcja generuje dane wyjściowe, które obejmują wszystkie cele, ale zakopuje je w wielu innych informacjach.Umieść następującą regułę w pliku makefile dla GNU,
make
aby zaimplementować nazwany cel,list
który po prostu wyświetla wszystkie nazwy celów w kolejności alfabetycznej - tzn .: wywołaj jakomake list
:Ważne : po wklejeniu upewnij się, że ostatni wiersz jest wcięty dokładnie 1 rzeczywistym znakiem tabulacji. (spacje nie działają) .
Zauważ, że sortowanie wynikowej listy celów jest najlepszą opcją, ponieważ brak sortowania nie daje pomocnej kolejności, ponieważ kolejność pojawiania się celów w pliku makefile nie jest zachowana.
Również cele podrzędne reguły składającej się z wielu celów są niezmiennie wyprowadzane oddzielnie i dlatego, z powodu sortowania, zwykle nie pojawiają się obok siebie; np. reguła zaczynająca się od nie
a z:
będzie miała celów i będzie wyświetlana obok siebie , jeśli są dodatkowe cele.a
z
Objaśnienie reguły :
PHONY: list
$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null
make
ponownie, aby wydrukować i przeanalizować bazę danych pochodzącą z makefile:-p
drukuje bazę danych-Rr
pomija włączenie wbudowanych reguł i zmiennych-q
testuje tylko aktualny status celu (bez przerabiania czegokolwiek), ale to samo w sobie nie uniemożliwia wykonania poleceń receptury we wszystkich przypadkach; W związku z tym:-f $(lastword $(MAKEFILE_LIST))
zapewnia, że ten sam plik makefile jest kierowany jak w pierwotnym wywołaniu, niezależnie od tego, czy był on celowany pośrednio czy jawnie-f ...
.Zastrzeżenie : To się zepsuje, jeśli twój plik makefile zawiera
include
dyrektywy; aby rozwiązać ten problem, zdefiniuj zmiennąTHIS_FILE := $(lastword $(MAKEFILE_LIST))
przed wszelkimiinclude
dyrektywami i użyj-f $(THIS_FILE)
zamiast tego.:
jest celowo niepoprawnym celem, który ma zapewnić, że żadne polecenia nie zostaną wykonane ;2>/dev/null
pomija wynikowy komunikat o błędzie. Uwaga: To jednak polega na-p
wydrukowaniu bazy danych, co ma miejsce w przypadku GNU make 3.82. Niestety, GNU make oferty opcja nie do bezpośredniego prostu wydrukować bazę danych, bez również wykonanie domyślne (lub danego zadania); jeśli nie musisz kierować na konkretny plik Makefile, możesz użyćmake -p -f/dev/null
, zgodnie z zaleceniami naman
stronie.-v RS=
/^# File/,/^# Finished Make data base/
if ($$1 !~ "^[#.]")
#
... ignoruje nie-cele, których bloki zaczynają się od# Not a target:
.
... ignoruje specjalne cele:
egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
usuwa niechciane cele z danych wyjściowych:'^[^[:alnum:]]'
... wyklucza ukryte cele, które - zgodnie z konwencją - to cele, które nie zaczynają się od litery ani cyfry.'^$@$$'
... wykluczalist
sam celUruchomione
make list
następnie drukuje wszystkie cele, każdy na osobnej linii; możesz potokować, abyxargs
zamiast tego utworzyć listę oddzieloną spacjami.źródło
rake --tasks
on?-n
opcja.-n
opcji jest „Wydrukowanie poleceń, które zostaną wykonane ...” - innymi słowy: funkcja suchobiegu. Też nie, że Twój cytat brakuje italicization słowa tylko :make -p
przez sam robi wydrukować bazę danych, ale niezmiennie prowadzi również zadanie domyślnej ; instrukcja zaleca niezręczny,make -p -f/dev/null
aby tego uniknąć..PHONY: *
W Bash (przynajmniej) można to zrobić automatycznie po uzupełnieniu tabulatora:
make
spacetabtabźródło
. /etc/bash_completion
) i te, które w ogóle go nie obsługują (np. OSX 10.9)bash-completion
pakietu. Znaleziono w Fedorze, RHEL, Gentoo, itp.$(RUN_TARGETS): run-%: ...
To oczywiście nie zadziała w wielu przypadkach, ale jeśli
Makefile
został stworzony przez CMake, możesz być w stanie uruchomićmake help
.źródło
touch CMakeLists.txt && cmake . && make help
i powinno działać. Mogę tylko zgadywać, że używasz starożytnego cmake'a, czy nie używasz generatora Makefiles Unixa?Połączyłem te dwie odpowiedzi: https://stackoverflow.com/a/9524878/86967 i https://stackoverflow.com/a/7390874/86967 i zrobiłem trochę ucieczki, aby można było tego użyć z wnętrza makefile.
.
źródło
sh -c "…"
jest konieczne, ponieważmake
domyślnie używa tego do wywoływania poleceń receptur; (b) użyte polecenie jest zbyt uproszczone, co prowadzi do fałszywych trafień (jak zauważasz); (c) jeśli użyjesz przedrostka, polecenie@
nie zostanie powtórzone na standardowe wyjście przed wykonaniem, co eliminuje potrzebę użycia-s
przy wywołaniu.make -s
(za pomocą aliasu Bash) niż komend poprzedzających w pliku makefile@
. W niektórych przypadkach@
może być przydatny, zwłaszcza jako przedrostekecho
poleceń (gdzie wyświetlanie polecenia byłoby zbędne), ale ogólnie nie lubię go używać. W ten sposób widzę „przepisy”, kiedy muszę ( nie używam-s
), ale zazwyczaj nie. Oto powiązana dokumentacja: GNU Make Manual, 5.2 Recepcja echa .Jeśli masz ukończone bash dla
make
zainstalowanego skryptu zakończenia zdefiniuje funkcję_make_target_extract_script
. Ta funkcja ma na celu utworzeniesed
skryptu, którego można użyć do uzyskania celów jako listy.Użyj tego w ten sposób:
źródło
/etc/bash_completion
i / lub funkcję_make_target_extract_script
- wydaje się, że jesteś na Ubuntu> 12. Jeśli celujesz/usr/share/bash-completion/completions/make
zamiast tego, twoje podejście będzie działać na dodatkowych platformach, takich jak Fedora 20. Istnieją (starsze) platformy, które mają ten plik, ale nie funkcja (np. Debian 7 i Ubuntu 12); inne platformy, takie jak OSX, wcale nie są wyposażone w funkcję uzupełniania tabulatorówmake
. Być może pomocne byłoby opublikowanie rzeczywistej definicji funkcji.Jak wskazuje mklement0 , w GNU-make brakuje funkcji wyświetlania wszystkich celów Makefile, a jego odpowiedź i inne zapewniają sposoby na to.
Jednak oryginalny post wspomina także o prowizji , której zmiana zadań robi coś nieco innego niż tylko wypisanie wszystkich zadań w pliku rakefile. Rake da ci tylko listę zadań, które mają powiązane opisy. Zadania bez opisów nie zostaną wymienione . Daje to autorowi możliwość dostarczenia dostosowanych opisów pomocy, a także pominięcia pomocy dla niektórych celów.
Jeśli chcesz naśladować zachowanie prowizji, w którym podajesz opisy dla każdego celu , możesz to zrobić za pomocą prostej techniki: umieść opisy w komentarzach dla każdego celu, który chcesz wymienić.
Możesz umieścić opis obok celu lub, jak to często robię, obok specyfikacji PHONY nad celem, tak jak poniżej:
Który da
Możesz także znaleźć krótki przykład kodu w tej liście i tutaj .
Ponownie nie rozwiązuje to problemu umieszczenia wszystkich celów w pliku Makefile. Na przykład, jeśli masz duży plik Makefile, który mógł zostać wygenerowany lub napisany przez kogoś innego, i chcesz szybko wyświetlić listę jego celów bez przekopywania się, nie pomoże to.
Jeśli jednak piszesz plik Makefile i chcesz uzyskać sposób generowania tekstu pomocy w spójny, samowydajny sposób, ta technika może być przydatna.
źródło
echo
polecenia jako opisu polecenia ( stackoverflow.com/a/52059487/814145 ).@echo "Target 1"
to tylko symbol zastępczy, a nie „polecenie echa opisu”. Wygenerowany tekst pomocy nie pochodzi z@echo
. W prawdziwym pliku Makefileecho
zostaną one zastąpione poleceniem kompilacji lub jakimś innym. Zedytuję post, aby to wyjaśnić.Odpowiedź @ nobar pomaga pokazać, jak używać uzupełniania tabulatorów, aby wyświetlić listę celów makefile .
Działa to świetnie na platformach, które domyślnie zapewniają tę funkcjonalność (np. Debian, Fedora ).
Na innych platformach (np. Ubuntu ) musisz jawnie załadować tę funkcję, zgodnie z odpowiedzią @ hek2mgl :
. /etc/bash_completion
instaluje kilka funkcji uzupełniania tabulatorów, w tym tę dlamake
make
:. /usr/share/bash-completion/completions/make
-f <file>
.źródło
Moja ulubiona odpowiedź na to pytanie została opublikowana przez Chrisa Downa w Unix & Linux Stack Exchange. Zacytuję.
Użytkownik Brainstone sugeruje potokowanie w
sort -u
celu usunięcia zduplikowanych wpisów:Źródło: Jak wyświetlić listę wszystkich celów w marce? (Unix i Linux SE)
źródło
Koncentrując się na łatwej składni do opisu celu make i mając czysty wynik, wybrałem takie podejście:
Traktowanie powyższego jako pliku Makefile i uruchomienie go daje ci coś w rodzaju
Objaśnienie łańcucha poleceń:
źródło
awk -F ':|##' '/^[^\t].+:.*##/ { printf "\033[36mmake %-28s\033[0m -%s\n", $$1, $$NF }' $(MAKEFILE_LIST) | sort
z##
komentarzem przed tą samą linią co cel. Ale myślę, że twoje rozwiązanie pozwala na czytelność.grep: parentheses not balanced
na moim komputerze z systemem OSX 10.15.Wiele praktycznych rozwiązań tutaj, ale jak lubię mówić: „jeśli warto to zrobić raz, to warto to zrobić ponownie”. Poprosiłem o skorzystanie z sugestii użycia (tab) (tab), ale jak niektórzy zauważyli, możesz nie mieć pomocy w uzupełnianiu lub, jeśli masz wiele plików dołączeń, możesz chcieć łatwiejszego sposobu, aby ustalić, gdzie jest zdefiniowany cel.
Nie testowałem poniżej z pod-markami ... Myślę, że to nie zadziała. Jak wiemy rekurencyjny sprawia, że jest uważany za szkodliwy.
Które lubię, ponieważ:
Wyjaśnienie:
Przykładowe dane wyjściowe:
źródło
Ten był dla mnie pomocny, ponieważ chciałem zobaczyć cele kompilacji wymagane (i ich zależności) przez make target. Wiem, że tworzenie celów nie może zaczynać się od „.” postać. Nie wiem, jakie języki są obsługiwane, więc wybrałem wyrażenia nawiasowe egrep.
źródło
To jest dalekie od czystego, ale wykonałem pracę dla mnie.
Używam
make -p
tego, który zrzuca wewnętrzną bazę danych, ditch stderr, używam szybkiego i brudnego,grep -A 100000
aby utrzymać dół wyniku. Następnie oczyszczam dane wyjściowe za pomocą kilkugrep -v
, a na koniec używam,cut
aby uzyskać to, co znajduje się przed dwukropkiem, a mianowicie cele.To wystarczy dla moich skryptów pomocniczych na większości moich plików Makefiles.
EDYCJA: dodano,
grep -v Makefile
że jest to reguła wewnętrznaźródło
Jest to modyfikacja bardzo pomocnej odpowiedzi jsp ( https://stackoverflow.com/a/45843594/814145 ). Podoba mi się pomysł, aby uzyskać nie tylko listę celów, ale także ich opisy. Makefile jsp umieszcza opis jako komentarz, który często znalazłem, będzie powtarzany w poleceniu echo opisu celu. Zamiast tego wyodrębniam opis z polecenia echo dla każdego celu.
Przykład Makefile:
Wyjście
make help
:Uwagi:
echo
lub:
jako pierwsze polecenie przepisu.:
oznacza „nic nie rób”. Używam go tutaj do celów, których echo nie jest potrzebne, takich jakall
cel powyżej.help
celu, aby dodać „:” domake help
wyniku.źródło
Jeszcze jedna dodatkowa odpowiedź na powyższe.
testowane na MacOSX-ie przy użyciu tylko cat i awk na terminalu
wyświetli plik make jak poniżej:
w Makefile powinna to być ta sama instrukcja, upewnij się, że uciekasz przed zmiennymi używając zmiennej $$ zamiast $ zmiennej.
Wyjaśnienie
kot - wypluwa zawartość
| - potok analizuje dane wyjściowe do następnego awk
awk - uruchamia wyrażenie regularne z wyłączeniem „powłoki” i akceptując tylko wiersze „Az”, a następnie drukuje pierwszą kolumnę o wartości 1 USD
awk - ponownie usuwa ostatni znak „:” z listy
jest to szorstki wynik i możesz robić bardziej funkowe rzeczy za pomocą AWK. Staraj się unikać sed, ponieważ nie jest on tak spójny w wariantach BSD, tzn. Niektóre działają na * nix, ale zawodzą na BSD takich jak MacOSX.
Więcej
Powinieneś być w stanie dodać to (z modyfikacjami) do pliku do zrobienia , do domyślnego folderu zakończenia bash /usr/local/etc/bash-completion.d/, co oznacza, że kiedy "zrobisz kartę tab " ... cele oparte na skrypcie jednoliniowym.
źródło
Zwyklę robię:
Wróciłby z czymś takim jak:
mam nadzieję, że to pomoże
źródło
Skrypt Bash
Oto bardzo prosty sposób, aby to zrobić
bash
- w oparciu o komentarz @ cibercitizen1 powyżej :Zobacz także bardziej autorytatywną odpowiedź @ Marc.2377, która mówi, jak
make
robi to moduł uzupełniania Bash .źródło
nie jestem pewien, dlaczego poprzednia odpowiedź była tak skomplikowana:
źródło
$(SHELLS): ...
), (b) włączenie celów, które zaczynają się od cyfry, (c) nie- włączenie definicji zmiennych , (d) ukierunkowanie na właściwymake
plik makefile, jeśli został określony za pomocą jawnej ścieżki makefile. (a) jest kluczową wadą: nawet jeśli niezawodnie wybrałeś właściwy plik makefile, parsowanie surowego pliku nie będzie działać w ogólnym przypadku, z powodu braku rozszerzania zmiennej.awk -F: '/^[A-z]/ {print $$1}' Makefile
. Wreszcie, w dużej mierze akademicki punkt: użycie[A-z]
zamiast[:alpha:]
oznacza, że ominiesz cele zaczynające się od obcej postaci, takiej jaká
.[[:alpha:]]
zamiast[:alpha:]
([:alpha:]
reprezentuje lokalizacji świadomy zestaw liter wewnątrz klasy znaków ([...]
), stąd konieczność efektywnej podwójne[[
/]]
.awk -F: '/^[A-Za-z]/ { print $$1 }' Makefile
używa pojedynczego procesu i, mam nadzieję, bardziej poprawnego wyrażenia regularnego (chociaż oczywiście możesz mieć cele z podkreśleniami, liczbami itp., jak zauważono we wcześniejszych komentarzach).