Können Sie gültige Makefiles ohne Tabulatorzeichen erstellen?


114
target: dependencies
    command1
    command2

Auf meinem System (Mac OS X) makescheint es erforderlich zu sein, dass Makefiles vor dem Inhalt jeder commandZeile ein Tabulatorzeichen haben , oder es wird ein Syntaxfehler ausgegeben.

Dies ist ärgerlich beim Erstellen oder Bearbeiten von Makefiles, da mein Editor so eingerichtet ist, dass er immer nur Leerzeichen enthält.

Können Sie gültige Makefiles ohne Tabulatorzeichen erstellen?


4
Ich habe meinen Editor auch so konfiguriert, dass Tabulatoren mit Leerzeichen emuliert werden. Mein Editor erlaubt mir jedoch auch, Strg-Tab in den seltenen Fällen einzugeben, in denen ich unbedingt einen Tab haben muss, wie in Makefiles. Vielleicht tut es auch Ihr Redakteur.
Toolic

Antworten:


118

Dies ist eine Kuriosität / Anforderung der Syntax. makeSie hat nichts mit Mac OS X zu tun. Leider können Sie nichts dagegen tun, wenn Sie sie verwenden möchten make.

Bearbeiten : GNU Make unterstützt jetzt ein benutzerdefiniertes Rezeptpräfix. Siehe diese Antwort .

Sie sind nicht der erste, der diesen Aspekt nicht mag make. Um das Handbuch von Unix Haters zu zitieren :

Das Problem mit Dennis 'Makefile ist, dass er beim Hinzufügen der Kommentarzeile versehentlich ein Leerzeichen vor dem Tabulatorzeichen am Anfang von Zeile 2 eingefügt hat. Das Tabulatorzeichen ist ein sehr wichtiger Bestandteil der Syntax von Makefiles. Alle Befehlszeilen (in unserem Beispiel die Zeilen, die mit cc beginnen) müssen mit Tabulatoren beginnen. Nachdem er seine Änderung vorgenommen hatte, tat Zeile 2 dies nicht, daher der Fehler.

"Na und?" Sie fragen: "Was ist daran falsch?"

Daran ist an sich nichts auszusetzen. Es ist nur so, dass, wenn man bedenkt, wie andere Programmiertools unter Unix funktionieren, die Verwendung von Tabulatoren als Teil der Syntax wie eine dieser Pungee-Stick-Fallen in The Green Berets ist: Das arme Kind aus Kansas geht vor John Wayne und tut es nicht. t sehen Sie den Auslösedraht. Schließlich gibt es in Kansas Maisfeldern keine Stolperdrähte, auf die man achten muss. WHAM!


5
Das Problem mit Registerkarten ist eines der ersten Dinge, die jemand zum Lernen verwendet - ich habe nie festgestellt, dass es ein echtes Problem ist.

2
@Neil, ich auch nicht: Ich habe nie gesagt, dass ich mit der UHH einverstanden bin, ich habe nur gesagt, dass einige Leute es nicht mögen. :-)
Alok Singhal

2
Scheint ein guter Stecker für die Verwendung von cmake zu sein. Nicht die einzige frustrierende Kuriosität in der Make-Syntax.
Orodbhen

3
Ich habe gerade gnu.org/software/make/manual/html_node/Special-Variables.html gefunden (siehe .RECIPEPREFIX). Eine der folgenden Antworten erwähnt dies ebenfalls und sollte anstelle von meiner als "korrekt" markiert werden. stackoverflow.com/a/21920142
Alok Singhal

3
Es ist kein großes Problem, aber es ist ärgerlich. Jedes Mal. Es ist zuverlässig ärgerlich, und es ist in der linearen Zeit von Omicron ärgerlich.
Parthian Shot

60

In der Zeit, seit diese Frage ursprünglich gestellt wurde, wurde eine Version von GNU Make veröffentlicht, mit der Sie etwas anderes als Tabdas Präfixzeichen verwenden können. Aus der Mailinglistenansage :

Neue spezielle Variable: Mit .RECIPEPREFIX können Sie das Rezept-Einführungszeichen vom Standard (TAB) auf etwas anderes zurücksetzen. Das erste Zeichen dieses Variablenwerts ist das neue Rezepteinführungszeichen. Wenn die Variable auf die leere Zeichenfolge gesetzt ist, wird TAB erneut verwendet. Es kann nach Belieben eingestellt und zurückgesetzt werden; Rezepte verwenden den aktiven Wert, als sie zum ersten Mal analysiert wurden. Um diese Funktion zu erkennen, überprüfen Sie den Wert von $ (. RECIPEPREFIX).

Diese Funktion wurde in GNU Make 3.82 hinzugefügt, das im Juli 2010 veröffentlicht wurde (sechs Monate nach dem ursprünglichen Fragedatum dieser Frage). Da es wiederum drei Jahre her ist und sich seitdem ändert, ist es wahrscheinlich, dass andere Make-Aromen GNU Make gefolgt sind.


51

Es gibt eine komplizierte Möglichkeit, ein gültiges Makefile ohne Registerkarten zu erstellen.

Wenn Sie Ihr Makefile so ändern, dass es lautet:

target: dependencies; command1; command2

Wenn wird funktionieren. Wenn Sie es in mehr als einer Zeile möchten, können Sie Folgendes tun:

target: dependencies; \
command1; \
command2

Chaotisch, aber es funktioniert.


Ein Upgrade auf eine unterstützte Version von Make .RECIPEPREFIXist wahrscheinlich der beste Ansatz. Da ich jedoch keine Lust dazu hatte, habe ich eine Lösung verwendet, die auf dieser basiert. Zeile 1 : target:\ , Zeile 2: [Einrückung mit vier Leerzeichen], gefolgt von;command
LS

33

Wenn Sie ein vimrc in Ihrem Profil haben, können Sie diese Zeile hinzufügen, um zu verhindern, dass vim zu Leerzeichen wechselt:

autocmd FileType make setlocal noexpandtab

Auch ich hatte damit zu kämpfen, und das hat es für mich behoben. Verbreite das gute Wort!


19

Dies tut es für mich, wenn Sie Leerzeichen verwenden möchten

.RECIPEPREFIX +=

Beispiel


Welche Version von make unterstützt dies? Dies funktioniert in GNU Make 4.1 nicht.
Cerin

2
GNU Make 4.1 Gebaut für x86_64-pc-linux-gnu Es tut mir leid, aber es funktioniert
neok

wahrscheinlich muss erwähnt werden, dass diese Variable innerhalb der make-Datei selbst deklariert werden muss (Präfixpunkt leicht nicht zu erkennen)
urusai_na

Zumindest in Version 4.2 sollte dies funktionieren. In der Dokumentation heißt es in der Erklärung .RECIPEPREFIX: "Wenn die Variable leer ist (wie standardmäßig ), ist dieses Zeichen das Standard-Tabulatorzeichen." Dies bedeutet, dass die Variable standardmäßig definiert ist. Es wird mit bestätigt ifeq ($(origin .RECIPEPREFIX), undefined). Da +=append ein einzelner Raum und die RHS zu den lhs, var +=Sätze varzu einem einzigen Raum (plus eine leere Zeichenkette) solange varbereits definiert werden. (Wenn varnicht definiert, +=ist das gleiche wie =.)
ynn

1
Diese Antwort funktioniert nicht mehr. Siehe meine Antwort für die neueste Lösung.
23.

11

Im Einfügemodus von vim können Sie Ctrl-v <TAB>eine wörtliche Registerkarte einfügen, auch wenn Sie die Tabulatortaste zum Einfügen von Leerzeichen festgelegt haben. Dies beantwortet Ihre Frage natürlich nicht, ist jedoch möglicherweise eine Alternative zu den verfügbaren Methoden, um die Verwendung von wörtlichen Registerkarten zu vermeiden.


10

Wenn Sie EditorConfig verwenden , können Sie Ihrer .editorconfigDatei die folgenden Zeilen hinzufügen , um Ihre IDE zu zwingen, anstelle von Leerzeichen in die Registerkarte zum Einrücken zu verwenden Makefile:

[Makefile]
indent_style = tab

4

Bis GNU Make 4.2

Steven Pennys Antwort funktioniert.

.RECIPEPREFIX +=

Der Grund, warum dies funktioniert, ist in meinem Kommentar beschrieben .


Seit GNU Make 4.3 (veröffentlicht am 19. Januar 2020)

Das Verhalten des +=Bedieners wurde rückwärts inkompatibel geändert . Wenn der linke Operand einen leeren Wert hat, wird kein Leerzeichen mehr hinzugefügt.

Sie können stattdessen verwenden

.RECIPEPREFIX := $(.RECIPEPREFIX)<space>

, wo <space>ist ein einzelnes Leerzeichen. Obwohl $(.RECIPEPREFIX)es als leerer Wert erweitert wird, ist dies erforderlich, damit GNU Make nicht ignoriert wird <space>. Beachten Sie, dass dieser Code auch unter GNU Make älter als Version 4.3 funktioniert.


1

in ubuntu: vi Makefiles ersetzen Leerzeichen durch Tabulatoren (oder alles andere, was Sie wollen):

:%s/<space chars>/^I/g

Zum Beispiel 8 Leerzeichen durch Tabulator ersetzen:

:%s/        /^I/g

Achtung: ^ Ich füge mit Tabulatortaste ein, nicht ^ und ich Zeichen: D.


-6

Nicht tragbar. Bestimmte Geschmacksrichtungen von make erfordern unbedingt Tabulatorzeichen. Ein weiterer Grund, Tabulatoren Leerzeichen vorzuziehen :-)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.