2010-08-13 12 views
7

ho una regola che crea una directorySoppressione make uscita di errore regola

bin: 
    -mkdir [email protected] 

Tuttavia, dopo la prima volta che la directory è stato generato, ricevo questo output:

mkdir bin 
mkdir: cannot create directory `bin': File exists 
make: [bin] Error 1 (ignored) 

C'è qualche modo Posso solo eseguire la regola se la directory non esiste o sopprimere l'output quando la directory esiste già?

+0

Vicino duplicato: http://stackoverflow.com/questions/3477292/what-do-and-do-as-prefixes-to-recipe-lines-in-make – reinierpost

risposta

8

Il modo tradizionale di gestire la creazione di directory è quello di utilizzare un file timbro che viene dipendeva e crea la directory come un effetto collaterale. Rimuovere il file timbro quando si effettua distclean o qualunque sia il vostro obiettivo "veramente pulito" è:

bin/.dirstamp: 
    mkdir -p $(DIRS) 
    touch [email protected] 

bin/foo: bin/.dirstamp 
    $(MKFOO) -o [email protected] 

distclean: 
    rm -rf bin 

La ragione di questo è la seguente: ogni volta che viene creato un file in bin/rimosso, il mtime della directory contenente viene aggiornato . Se un obiettivo dipende da bin, la prossima volta che viene eseguito make, verrà ricreare i file che non è necessario.

+0

La directory dir va su tutti i file generati in quella posizione? –

+0

Ogni file creato in tale directory dovrebbe dipendere, direttamente o indirettamente, dal file di francobollo per garantire che sia stato creato prima dell'uso. –

7

L'errore viene ignorato già dalla riga di comando "-". Se davvero si vuole perdere i messaggi di errore da mkdir, utilizzare redirezione dell'I/O:

bin: 
    -mkdir bin 2> /dev/null 

si continua a ottenere il 'ignorato' avvertimento da make, però, quindi potrebbe essere meglio utilizzare l'opzione per mkdir che non causa il fallimento quando il target esiste già, che è l'opzione -p:

MKDIR_P = mkdir -p 

bin: 
    ${MKDIR_P} [email protected] 

l'opzione -p crea in realtà tutte le directory che mancano sui percorsi dati, quindi è in grado di generare aa numero di directory in una invocazione, ma come ide-effect è che non genera un errore per le directory già esistenti. Ciò presuppone un'implementazione POSIX-ish di mkdir; le macchine più datate potrebbero non supportarlo (anche se è ormai di serie da molto tempo ormai).

+0

perché il reindirizzamento '2> & 1' è utile? Comprenderei '2>/dev/null' per inviare stderr a oblio ma inviandolo allo stdout .....? – humanityANDpeace

+0

@humanityandpeace: hai ragione - un thinko nel 2010. L'ho risolto. Grazie. –

0

La regola non deve essere eseguita a meno che il suo obiettivo non esista o non sia aggiornato a causa delle sue dipendenze. In altre parole, non si dovrebbe mai incontrare questo errore.

[Esempio Aggiunto]

[[email protected] tmp]$ ls -la 
total 20 
drwxr-xr-x. 2 max users 4096 Aug 14 21:11 . 
drwx------. 80 max max 4096 Aug 14 18:25 .. 
-rw-rw-r-- 1 max max  38 Aug 14 21:11 Makefile 
[[email protected] tmp]$ cat Makefile 
.PHONY: all 
all: bin 

bin: 
    mkdir [email protected] 

[[email protected] tmp]$ make 
mkdir bin 
[[email protected] tmp]$ ls -la 
total 24 
drwxr-xr-x. 3 max users 4096 Aug 14 21:11 . 
drwx------. 80 max max 4096 Aug 14 18:25 .. 
drwxrwxr-x 2 max max 4096 Aug 14 21:11 bin 
-rw-rw-r-- 1 max max  38 Aug 14 21:11 Makefile 
[[email protected] tmp]$ make 
make: Nothing to be done for `all'. 
[[email protected] tmp]$ make 
make: Nothing to be done for `all'. 

La vostra cartella dipende da niente? La tua cartella è un bersaglio fasullo?

+0

No. È sempre obsoleto, quello che vedi nell'OP è quello che ho. –

0

Bene ho finito con questo costrutto, forse qualcuno lo troverà utile o può commentare su di esso:

BINDIR = . 
TMPDIR = tmp 
OUTDIRS = $(BINDIR) $(TMPDIR) 
$(OUTDIRS): 
    @test -d [email protected] || mkdir [email protected] 
+0

Make esegue 'test' per te in ogni caso, quindi finisce due volte per dichiarare la directory. Questo nasconde semplicemente il problema che il target predefinito è. (Punto). –

0

Fai assume il primo obiettivo è la destinazione predefinita. Se quello è il tuo makefile completo, allora deve sempre cercare di rifare il target predefinito, che è bin. Inserire le seguenti righe alla parte superiore del vostro makefile:

all: bin 
.PHONY: all 
12

Un altro modo per sopprimere l'output make: error ... (ignored) consiste nell'aggiungere || true a un comando che potrebbe non riuscire.Esempio con grep che verifica la presenza di errori in un file di log LaTeX:

undefined: 
    @grep -i undefined *.log || true 

Senza la || true, fanno si lamenta quando grep non riesce a trovare alcuna corrispondenza.

Questo funziona per tutti i comandi, non solo per mkdir; è per questo che ho aggiunto questa risposta.

+0

daniel, il carattere di prefisso '-' di un comando in una regola di creazione esegue la stessa cosa anche senza richiedere alla shell di gestirla. Questo è probabilmente più veloce e meno probabile che si ritorceri contro. –

+7

Il prefisso '-' causa l'output fastidioso" errore ignorato ", che la mia soluzione non ha. Quindi no, i due non fanno la stessa cosa. –

+0

Chiama. Grazie –

Problemi correlati