Puoi creare Makefile validi senza caratteri di tabulazione?


114
target: dependencies
    command1
    command2

Sul mio sistema (Mac OS X), makesembra richiedere che i Makefile abbiano un carattere di tabulazione prima del contenuto di ciascuna commandriga, oppure genera un errore di sintassi.

Questo è un fastidio quando creo o modifico i Makefile perché ho il mio editor impostato per essere tutto-spazi-tutto-il-tempo.

Puoi creare Makefile validi senza caratteri di tabulazione?


4
Ho anche configurato il mio editor per emulare schede con spazi. Ma il mio editor mi permette anche di digitare Ctrl-Tab nelle rare occasioni in cui devo assolutamente avere una scheda, come nei Makefile. Forse lo fa anche il tuo editore.
toolic

Risposte:


118

Questa è una stranezza / requisito della sintassi make, non ha nulla a che fare con Mac OS X. Sfortunatamente, non c'è niente che puoi fare al riguardo se intendi utilizzare make.

Modifica : GNU Make ora supporta un prefisso di ricetta personalizzato. Vedi questa risposta .

Non sei il primo a non apprezzare questo aspetto make. Per citare il Manuale di Unix Haters :

Il problema con il Makefile di Dennis è che quando ha aggiunto la riga di commento, ha inavvertitamente inserito uno spazio prima del carattere di tabulazione all'inizio della riga 2. Il carattere di tabulazione è una parte molto importante della sintassi dei Makefile. Tutte le righe di comando (le righe che iniziano con cc nel nostro esempio) devono iniziare con le tabulazioni. Dopo aver apportato la modifica, la riga 2 non l'ha fatto, da cui l'errore.

"E allora?" chiedi: "Cosa c'è di sbagliato in questo?"

Non c'è niente di sbagliato in questo, da solo. È solo che, se si considera come funzionano altri strumenti di programmazione in Unix, usare le tabulazioni come parte della sintassi è come una di quelle trappole pungee in The Green Berets: il povero ragazzo del Kansas è davanti a John Wayne e non lo fa. t vedere il cavo di scatto. Dopotutto, non ci sono cavi di viaggio a cui prestare attenzione nei campi di mais del Kansas. Wham!


5
Il problema con le schede è una delle prime cose che chiunque usa make impara: non ho mai trovato che sia un vero problema.

2
@ Neil, nemmeno io: non ho mai detto di essere d'accordo con l'UHH, stavo solo dicendo che ad alcune persone non piace. :-)
Alok Singhal

2
Sembra un buon plug per usare cmake. Non è l'unica stranezza frustrante nella sintassi di make.
orodbhen

3
Ho appena trovato gnu.org/software/make/manual/html_node/Special-Variables.html (vedi .RECIPEPREFIX). Una delle risposte seguenti lo menziona e dovrebbe essere contrassegnata come "corretta" invece del mio. stackoverflow.com/a/21920142
Alok Singhal

3
Non è un grosso problema, ma è fastidioso. Ogni volta. È abbastanza fastidioso ed è fastidioso in \ omicron tempo lineare.
Parthian Shot

60

Da quando questa domanda è stata inizialmente posta, è stata rilasciata una versione di GNU Make che consente di utilizzare qualcosa di diverso dal Tabcarattere prefisso. Dall'annuncio della mailing list :

Nuova variabile speciale: .RECIPEPREFIX consente di ripristinare il carattere di introduzione della ricetta dal predefinito (TAB) a qualcos'altro. Il primo carattere di questo valore variabile è il nuovo carattere di introduzione alla ricetta. Se la variabile è impostata sulla stringa vuota, viene utilizzato di nuovo TAB. Può essere impostato e ripristinato a piacimento; le ricette useranno il valore attivo quando sono state analizzate per la prima volta. Per rilevare questa caratteristica, controllare il valore di $ (. RECIPEPREFIX).

Questa caratteristica è stata aggiunta in GNU Make 3.82, rilasciato nel luglio 2010 (sei mesi dopo la data di domanda originale di questa domanda). Dato che sono passati tre anni e da allora sono cambiati, è probabile che altri gusti Make abbiano seguito GNU Make.


51

C'è un modo complicato per avere un makefile valido senza schede.

Se modifichi il tuo makefile per leggere:

target: dependencies; command1; command2

Se funzionerà. Se lo vuoi su più di una riga, puoi fare:

target: dependencies; \
command1; \
command2

Disordinato, ma funziona.


L'aggiornamento a una versione di Make che supporta .RECIPEPREFIXè probabilmente l'approccio migliore. Tuttavia, poiché non avevo voglia di farlo, ho finito per utilizzare una soluzione basata su questa. Riga 1:, target:\ Riga 2: [rientro di quattro spazi] seguita da;command
LS

33

Se hai un vimrc nel tuo profilo puoi aggiungere questa riga per evitare che vim cambi in spazi:

autocmd FileType make setlocal noexpandtab

Anch'io stavo lottando con questo, e questo mi ha risolto. Diffondi la buona parola!


19

Questo lo fa per me se desideri utilizzare gli spazi

.RECIPEPREFIX +=

Esempio


Quale versione di make lo supporta? Questo non funziona in GNU Make 4.1.
Cerin

2
GNU Make 4.1 Costruito per x86_64-pc-linux-gnu mi dispiace ma funziona
neok

probabilmente, è necessario menzionare, che questa variabile deve essere dichiarata all'interno del file make stesso (prefisso punto facile da non individuare)
urusai_na

Almeno nella versione 4.2, dovrebbe funzionare. La documentazione dice nella spiegazione di .RECIPEPREFIXquesto "Se la variabile è vuota (come è per impostazione predefinita ) quel carattere è il carattere di tabulazione standard." Ciò significa che la variabile è definita per impostazione predefinita. È confermato utilizzando ifeq ($(origin .RECIPEPREFIX), undefined). Poiché +=aggiungi un singolo spazio e rhs a lhs, var +=imposta varun singolo spazio (più una stringa vuota) finché varè già stato definito. (Se varnon è definito, +=è uguale a =.)
ynn

1
Questa risposta non funziona più. Vedi la mia risposta per l'ultima soluzione.
Ynn

11

Nella modalità di inserimento di vim, si può usare Ctrl-v <TAB>per inserire una tabulazione letterale, anche se si è impostato il tasto Tab per inserire spazi. Questo non risponde alla tua domanda, ovviamente, ma potrebbe essere un'alternativa ai metodi disponibili per evitare di aver bisogno di tabulazioni letterali.


10

Se stai usando EditorConfig , puoi aggiungere le seguenti righe al tuo .editorconfigfile per forzare il tuo IDE a usare la tabulazione per il rientro invece degli spazi in Makefile:

[Makefile]
indent_style = tab

4

Fino a quando GNU Make 4.2

La risposta di Steven Penny funziona.

.RECIPEPREFIX +=

Il motivo per cui funziona è descritto nel mio commento .


Da GNU Make 4.3 (rilasciato il 19 gennaio 2020)

Il comportamento +=dell'operatore è stato modificato in modo incompatibile con le versioni precedenti. Se l'operando di sinistra ha un valore vuoto, non viene più aggiunto uno spazio .

Puoi invece usare

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

, dove <space>è un singolo spazio. Sebbene $(.RECIPEPREFIX)sia espanso come valore vuoto, è necessario per non lasciare che GNU Make ignori <space>. Nota che questo codice funziona anche su GNU Make precedente alla versione 4.3.


1

in ubuntu: vi I makefile sostituiscono lo spazio con la scheda (o qualsiasi altra cosa tu voglia):

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

Per ex sostituire 8 spazi con la tabulazione:

:%s/        /^I/g

Attenzione: ^ inserisco con il tasto tab, non ^ e I caratteri: D


-6

Non portabile. Alcuni tipi di marca richiedono assolutamente caratteri di tabulazione. Ancora un altro motivo per preferire le tabulazioni agli spazi :-)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.