Ich habe ein bisschen Rake verwendet (ein Ruby-Make-Programm) und es gibt eine Option, um eine Liste aller verfügbaren Ziele zu erhalten, z
> 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...
...
aber es scheint keine Option zu geben, dies in GNU make zu tun.
Anscheinend ist der Code ab 2007 fast da - http://www.mail-archive.com/[email protected]/msg06434.html .
Wie auch immer, ich habe wenig gehackt, um die Ziele aus einem Makefile zu extrahieren, das Sie in ein Makefile aufnehmen können.
list:
@grep '^[^#[:space:]].*:' Makefile
Sie erhalten eine Liste der definierten Ziele. Es ist nur ein Anfang - es filtert zum Beispiel nicht die Abhängigkeiten heraus.
> make list
list:
copy:
run:
plot:
turnin:
alias makefile-targets='grep "^[^#[:space:]].*:" Makefile'
Meistens muss ich nur das aktuelle Makefile untersuchen, und die Bash-Vervollständigung wird erweitert mein Alias.grep : Makefile
?Antworten:
Dies ist ein Versuch, den großartigen Ansatz von @ nobar wie folgt zu verbessern :
sh -c
).-f <file>
@
, um zu verhindern, dass er vor der Ausführung wiederholt wirdSeltsamerweise GNU
make
keine Funktion, um nur die Namen der in einem Makefile definierten Ziele aufzulisten. Die-p
Option erzeugt eine Ausgabe, die alle Ziele enthält, diese jedoch in vielen anderen Informationen vergräbt.Fügen Sie die folgende Regel in ein Makefile für GNU ein
make
, um ein Ziel mit dem Namen zu implementierenlist
, das einfach alle Zielnamen in alphabetischer Reihenfolge auflistet - dh: Aufruf alsmake list
:Wichtig : Stellen Sie beim Einfügen sicher, dass die letzte Zeile durch genau 1 aktuelles Tabulatorzeichen eingerückt ist . (Leerzeichen nicht ) .
Beachten Sie, dass das Sortieren der resultierenden Liste von Zielen die beste Option ist, da das Nicht- Sortieren keine hilfreiche Reihenfolge ergibt , da die Reihenfolge, in der die Ziele im Makefile angezeigt werden, nicht beibehalten wird.
Außerdem werden die Unterziele einer Regel, die mehrere Ziele umfasst, immer separat ausgegeben und erscheinen daher aufgrund der Sortierung normalerweise nicht nebeneinander. Beispielsweise hat eine Regel, die mit beginnt
a z:
, keine Zielea
und wirdz
aufgelistet in der Ausgabe nebeneinander , wenn zusätzliche Ziele vorhanden sind.Erklärung der Regel :
PHONY: list
$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null
make
erneut auf, um die aus dem Makefile abgeleitete Datenbank zu drucken und zu analysieren:-p
druckt die Datenbank-Rr
Unterdrückt die Einbeziehung integrierter Regeln und Variablen-q
testet nur den aktuellen Status eines Ziels (ohne etwas neu zu erstellen), aber das allein verhindert nicht in allen Fällen die Ausführung von Rezeptbefehlen; daher:-f $(lastword $(MAKEFILE_LIST))
stellt sicher, dass das gleiche Makefile als Ziel des ursprünglichen Aufrufs ausgewählt wird, unabhängig davon, ob es implizit oder explizit mit ausgewählt wurde-f ...
.Vorsichtsmaßnahme : Dies wird unterbrochen, wenn Ihr Makefile
include
Anweisungen enthält . diese Adresse definieren variableTHIS_FILE := $(lastword $(MAKEFILE_LIST))
bevor irgendwelcheinclude
Direktiven und verwenden-f $(THIS_FILE)
statt.:
ist ein absichtlich ungültiges Ziel , das sicherstellen soll, dass keine Befehle ausgeführt werden ;2>/dev/null
unterdrückt die resultierende Fehlermeldung. Hinweis: Dies-p
hängt jedoch vom Drucken der Datenbank ab, was ab GNU make 3.82 der Fall ist. Leider bietet GNU make keine direkte Option zum einfachen Drucken der Datenbank, ohne auch die Standardaufgabe (oder die angegebene Aufgabe) auszuführen. Wenn Sie nicht auf ein bestimmtes Makefile abzielen müssen, können Sie es verwendenmake -p -f/dev/null
, wie auf derman
Seite empfohlen .-v RS=
/^# File/,/^# Finished Make data base/
if ($$1 !~ "^[#.]")
#
... ignoriert Nichtziele, deren Blöcke mit beginnen# Not a target:
.
... ignoriert spezielle Ziele:
egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
Entfernt unerwünschte Ziele aus der Ausgabe:'^[^[:alnum:]]'
... schließt versteckte Ziele aus, bei denen es sich üblicherweise um Ziele handelt, die weder mit einem Buchstaben noch mit einer Ziffer beginnen.'^$@$$'
... schließt daslist
Ziel selbst ausBeim Ausführen werden
make list
dann alle Ziele in einer eigenen Zeile gedruckt. Sie können zu weiterleiten,xargs
um stattdessen eine durch Leerzeichen getrennte Liste zu erstellen.quelle
rake --tasks
?-n
Option.-n
Option besteht darin, "die Befehle zu drucken , die ausgeführt werden sollen ..." - mit anderen Worten: eine Trockenlauffunktion. Auch nicht, dass Ihr Angebot fehlt die Kursiv des Wortes nur :make -p
von selbst tut die Datenbank drucken, aber immer läuft auch die Standardaufgabe ; Das Handbuch empfiehlt den klobigenmake -p -f/dev/null
, um dies zu vermeiden..PHONY: *
Unter Bash (zumindest) kann dies automatisch mit Tab-Vervollständigung erfolgen:
make
spacetabtabquelle
. /etc/bash_completion
), und diejenigen, die sie überhaupt nicht unterstützen (zB OSX 10.9)bash-completion
Paket. Gefunden in Fedora, RHEL, Gentoo, ect.$(RUN_TARGETS): run-%: ...
Dies funktioniert natürlich in vielen Fällen nicht, aber wenn Ihr
Makefile
von CMake erstellt wurde, können Sie es möglicherweise ausführenmake help
.quelle
touch CMakeLists.txt && cmake . && make help
Sie einfach und es sollte funktionieren. Ich kann nur vermuten, dass Sie einen alten cmake verwenden oder den Unix Makefiles-Generator nicht verwenden.Ich habe diese beiden Antworten kombiniert: https://stackoverflow.com/a/9524878/86967 und https://stackoverflow.com/a/7390874/86967 und einige Fluchtversuche durchgeführt, damit diese aus einem Makefile heraus verwendet werden können.
.
quelle
sh -c "…"
ist nicht erforderlich, da diesmake
standardmäßig zum Aufrufen von Rezeptbefehlen verwendet wird. (b) der von Ihnen verwendete Befehl ist zu einfach, was zu falsch positiven Ergebnissen führt (wie Sie bemerken); (c) Wenn Sie dem Befehl ein Präfix voranstellen@
, wird er vor der Ausführung nicht an stdout zurückgegeben, sodass er beim-s
Aufruf nicht verwendet werden muss.make -s
(über einen Bash-Alias) anstelle des Präfixierens von Befehlen im Makefile mit@
. Es gibt einige Fälle, in denen@
dies nützlich sein kann, insbesondere als Präfix fürecho
Befehle (bei denen die Anzeige des Befehls redundant wäre), aber im Allgemeinen verwende ich ihn nicht gern. Auf diese Weise kann ich die "Rezepte" sehen, wenn ich muss (indem ich sie nicht benutze-s
), aber normalerweise nicht. Hier ist die zugehörige Dokumentation: GNU Make Manual, 5.2 Recipe Echoing .Wenn Sie Bash Completion für
make
installiert haben, definiert das Completion-Skript eine Funktion_make_target_extract_script
. Diese Funktion soll einsed
Skript erstellen, mit dem die Ziele als Liste abgerufen werden können.Verwenden Sie es so:
quelle
/etc/bash_completion
und / oder Funktionen verfügen_make_target_extract_script
- Sie scheinen Ubuntu> 12 zu verwenden. Wenn Sie/usr/share/bash-completion/completions/make
stattdessen zielen , funktioniert Ihr Ansatz auf zusätzlichen Plattformen wie Fedora 20. Es gibt (ältere) Plattformen mit diesen Funktionen diese Datei, aber nicht die Funktion (zB Debian 7 und Ubuntu 12); Andere Plattformen wie OSX verfügen überhaupt nicht über eine Tab-Vervollständigungmake
. Vielleicht wäre es hilfreich, die eigentliche Funktionsdefinition zu veröffentlichen.Wie mklement0 hervorhebt , fehlt in GNU-make eine Funktion zum Auflisten aller Makefile-Ziele, und seine und andere Antworten bieten Möglichkeiten dazu.
Der ursprüngliche Beitrag erwähnt jedoch auch Rake , dessen Aufgabenwechsel etwas anderes bewirkt als nur die Auflistung aller Aufgaben in der Rake-Datei. Rake gibt Ihnen nur eine Liste von Aufgaben, denen Beschreibungen zugeordnet sind. Aufgaben ohne Beschreibung werden nicht aufgelistet . Dies gibt dem Autor die Möglichkeit, sowohl benutzerdefinierte Hilfebeschreibungen bereitzustellen als auch Hilfe für bestimmte Ziele wegzulassen.
Wenn Sie das Verhalten von Rake emulieren möchten, indem Sie Beschreibungen für jedes Ziel bereitstellen , gibt es eine einfache Technik, um dies zu tun: Betten Sie Beschreibungen in Kommentare für jedes Ziel ein, das aufgelistet werden soll.
Sie können die Beschreibung entweder neben das Ziel oder, wie so oft, neben eine PHONY-Spezifikation über dem Ziel setzen:
Welches wird ergeben
Ein kurzes Codebeispiel finden Sie auch in dieser Übersicht und auch hier .
Dies löst wiederum nicht das Problem, alle Ziele in einem Makefile aufzulisten. Wenn Sie beispielsweise ein großes Makefile haben, das möglicherweise generiert wurde oder von jemand anderem geschrieben wurde, und eine schnelle Möglichkeit zum Auflisten der Ziele wünschen, ohne es zu durchsuchen, hilft dies nicht.
Wenn Sie jedoch ein Makefile schreiben und eine Möglichkeit suchen, Hilfetext auf konsistente, selbstdokumentierende Weise zu generieren, kann diese Technik hilfreich sein.
quelle
echo
Befehl als Befehlsbeschreibung zu verwenden ( stackoverflow.com/a/52059487/814145 ).@echo "Target 1"
nur ein Platzhalter und kein "Beschreibungsecho-Befehl" ist. Der generierte Hilfetext stammt nicht von den@echo
. In einem echten Makefileecho
würden diese durch einen Build-Befehl oder ähnliches ersetzt. Ich werde den Beitrag bearbeiten, um dies klarer zu machen.Die Antwort von @ nobar zeigt hilfreich, wie Sie mithilfe der Tab-Vervollständigung die Ziele eines Makefiles auflisten .
Dies funktioniert hervorragend für Plattformen, die diese Funktionalität standardmäßig bereitstellen (z. B. Debian, Fedora ).
Auf anderen Plattformen (z. B. Ubuntu ) müssen Sie diese Funktionalität explizit laden , wie aus der Antwort von @ hek2mgl hervorgeht :
. /etc/bash_completion
Installiert mehrere Funktionen zum Vervollständigen von Registerkarten, einschließlich der fürmake
make
:. /usr/share/bash-completion/completions/make
-f <file>
.quelle
Meine Lieblingsantwort darauf wurde von Chris Down bei Unix & Linux Stack Exchange veröffentlicht. Ich werde zitieren.
Benutzer Brainstone schlägt Piping vor
sort -u
, um doppelte Einträge zu entfernen:Quelle: Wie liste ich alle Ziele in make auf? (Unix & Linux SE)
quelle
Ich konzentrierte mich auf eine einfache Syntax zur Beschreibung eines Make-Ziels und hatte eine saubere Ausgabe. Ich entschied mich für diesen Ansatz:
Wenn Sie also das Obige als Makefile behandeln und es ausführen, erhalten Sie so etwas wie
Erläuterung zur Befehlskette:
quelle
awk -F ':|##' '/^[^\t].+:.*##/ { printf "\033[36mmake %-28s\033[0m -%s\n", $$1, $$NF }' $(MAKEFILE_LIST) | sort
mit dem##
vor dem Kommentar in der gleichen Zeile wie das Ziel. Aber ich denke, Ihre Lösung ermöglicht vor der Lesbarkeit.grep: parentheses not balanced
auf meinem OSX 10.15-Computer.Viele praktikable Lösungen hier, aber wie ich gerne sage: "Wenn es sich lohnt, es einmal zu tun, lohnt es sich, es noch einmal zu tun." Ich habe den zu verwendenden Vorschlag (tab) (tab) positiv bewertet, aber wie einige angemerkt haben, haben Sie möglicherweise keine Abschlussunterstützung, oder wenn Sie viele Include-Dateien haben, möchten Sie möglicherweise einen einfacheren Weg, um zu wissen, wo ein Ziel definiert ist.
Ich habe das Folgende nicht mit Untermarken getestet ... Ich denke, es würde nicht funktionieren. Wie wir wissen, wird rekursiv als schädlich angesehen.
Was ich mag, weil:
Erläuterung:
Beispielausgabe:
quelle
Dieser war für mich hilfreich, weil ich die Build-Ziele sehen wollte, die vom make-Ziel benötigt werden (und deren Abhängigkeiten). Ich weiß, dass Make-Ziele nicht mit einem "." Beginnen können. Charakter. Ich weiß nicht, welche Sprachen unterstützt werden, deshalb habe ich mich für die Klammerausdrücke von egrep entschieden.
quelle
Das ist alles andere als sauber, hat aber den Job für mich gemacht.
Ich benutze
make -p
das Dumps die interne Datenbank, Graben stderr, benutze eine schnelle und schmutzigegrep -A 100000
, um den Boden der Ausgabe zu halten. Dann bereinige ich die Ausgabe mit ein paargrep -v
und benutze schließlich, umcut
zu bekommen, was vor dem Doppelpunkt ist, nämlich die Ziele.Dies reicht für meine Hilfsskripte auf den meisten meiner Makefiles.
BEARBEITEN: hinzugefügt,
grep -v Makefile
dass dies eine interne Regel istquelle
Dies ist eine Änderung der sehr hilfreichen Antwort von jsp ( https://stackoverflow.com/a/45843594/814145 ). Ich mag die Idee, nicht nur eine Liste von Zielen zu erhalten, sondern auch deren Beschreibungen. Das Makefile von jsp fügt die Beschreibung als Kommentar ein, den ich oft gefunden habe und der im Befehl description echo des Ziels wiederholt wird. Also extrahiere ich stattdessen die Beschreibung aus dem Echo-Befehl für jedes Ziel.
Beispiel Makefile:
Ausgabe von
make help
:Anmerkungen:
echo
oder:
-Befehl als ersten Befehl des Rezepts haben.:
bedeutet "nichts tun". Ich benutze es hier für jene Ziele, für die kein Echo benötigt wird, wie zall
obige Ziel.help
Ziel, das ":" in diemake help
Ausgabe einzufügen.quelle
Noch eine zusätzliche Antwort auf oben.
unter MacOSX nur mit cat und awk am Terminal getestet
wird die make-Datei wie folgt ausgeben:
Im Makefile sollte es dieselbe Anweisung sein. Stellen Sie sicher, dass Sie die Variablen mit der Variablen $$ anstelle der Variablen $ maskieren.
Erläuterung
Katze - spuckt den Inhalt aus
| - Pipe analysiert die Ausgabe auf das nächste awk
awk - führt Regex ohne "Shell" aus und akzeptiert nur "Az" -Zeilen. Anschließend wird die erste Spalte von $ 1 gedruckt
awk - entfernt erneut das letzte Zeichen ":" aus der Liste
Dies ist eine grobe Ausgabe und Sie können mit nur AWK mehr funky Sachen machen. Versuchen Sie, sed zu vermeiden, da es in BSD-Varianten nicht so konsistent ist, dh einige funktionieren unter * nix, scheitern jedoch unter BSDs wie MacOSX.
Mehr
Sie sollten diese in der Lage sein add (mit Änderungen) in eine Datei für make , auf den Standard Bash-Completion - Ordner /usr/local/etc/bash-completion.d/ Bedeutung , wenn Sie „make tab tab “ .. es wird füllen Sie bitte den Ziele basierend auf dem Einzeilenskript.
quelle
Normalerweise mache ich:
Es würde mit so etwas zurückkommen wie:
ich hoffe das hilft
quelle
Für ein Bash-Skript
Hier ist eine sehr einfache Möglichkeit, dies zu tun
bash
- basierend auf dem obigen Kommentar von @ cibercitizen1 :Siehe auch die maßgeblichere Antwort von @ Marc.2377, in der angegeben ist, wie das Bash-Vervollständigungsmodul dies
make
tut.quelle
Ich bin mir nicht sicher, warum die vorherige Antwort so kompliziert war:
quelle
$(SHELLS): ...
), (b) Einbeziehung von Zielen, die mit einer Ziffer beginnen, (c) Nicht- Einbeziehung von Variablendefinitionen , (d) Ausrichtung auf das richtige Makefile, wenn diesmake
mit einem expliziten Makefile-Pfad angegeben wurde. (a) ist das entscheidende Manko: Selbst wenn Sie das richtige Makefile zuverlässig ausgewählt haben , funktioniert das Parsen der Rohdatei im allgemeinen Fall aufgrund fehlender variabler Erweiterung nicht.awk -F: '/^[A-z]/ {print $$1}' Makefile
. Schließlich ein weitgehend akademischer Punkt: Verwenden von[A-z]
anstatt[:alpha:]
bedeutet, dass Sie Ziele verfehlen, die mit einem fremden Charakter beginnen, wie zá
.[[:alpha:]]
als[:alpha:]
([:alpha:]
repräsentiert den länderspezifischen Satz von Buchstaben innerhalb einer Zeichenklasse ([...]
), daher die effektive Notwendigkeit für double[[
/]]
.awk -F: '/^[A-Za-z]/ { print $$1 }' Makefile
verwendet einen einzelnen Prozess und hoffentlich einen korrekteren regulären Ausdruck (obwohl Sie natürlich auch Ziele mit Unterstrichen, Zahlen usw. haben könnten, wie in früheren Kommentaren erwähnt).