2015-11-10 26 views
5

Ho usato strane regole come questa per molto tempo, ma all'improvviso si stanno infrangendo in un nuovo ambiente.% e * insieme sulla linea di dipendenza

C'è un modo efficace per farlo?

all: test.1.out 

test.%.out: %/test*.out 
    /bin/cp -f $< [email protected] 

Sulla mia casella (ubuntu):

alishan:~/Dropbox/make_insanity> make --version 
GNU Make 3.81 
Copyright (C) 2006 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. 
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. 

This program built for x86_64-pc-linux-gnu 
alishan:~/Dropbox/make_insanity> make 
/bin/cp -f 1/test.out test.1.out 

Nessun problema con questo tipo di codice su Mac di altre persone, macchine Ubuntu, Ubuntu macchine virtuali. Non so tutte le loro versioni di make, ma sembra un codice OK.

Sul mio server mageia nella stessa directory dopo la cancellazione.

[[email protected] make_insanity]$ make --version 
GNU Make 3.82 
Built for x86_64-mageia-linux-gnu 
Copyright (C) 2010 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. 
[[email protected] make_insanity]$ make 
make: *** No rule to make target `test.1.out', needed by `all'. Stop. 
[[email protected] make_insanity]$ 

Modifica sia la % o * ad opportuni testo "fissa" il problema, ma naturalmente non produce la generalità desideri.

+0

Mi è stato suggerito che il cambiamento da fare 3.81 a 3.82 è il probabile colpevole. Ho guardato le note di rilascio ma non ho trovato nulla che sembrasse applicarsi. https://lists.gnu.org/archive/html/make-alpha/2010-07/msg00025.html –

risposta

1

io non sono assolutamente sicuro, ma penso che si desidera

test.<name>.out 

debba essere ottenuto da

<name>/test.out 

(se esiste). Se ciò è corretto, è possibile farlo in modo affidabile eseguendo il reverse engineering il nome del prerequisito per ciascun target dal nome del target, ad es.

targs := test.1.out test.a.out 

define src_of = 
$(patsubst .%,%,$(suffix $(basename $(1))))/$(basename $(basename $(1)))$(suffix $(1)) 
endef 

all: $(targs) 

test.%.out: $(call src_of,test.%.out) 
    cp -f $< [email protected] 

clean: 
    rm -f *.*.out 

È un po 'un boccone, lo ammetto.

Quindi, se abbiamo pre-organizzare una demo in cui esistono i presupposti:

$ ls -LR 
.: 
1 a Makefile 

./1: 
test.out 

./a: 
test.out 
$ make 
cp -f 1/test.out test.1.out 
cp -f a/test.out test.a.out 
+0

Grazie. Questo è utile in termini di apprendimento di cose interessanti sul make, ma potrei farlo usando la regola originale senza *. Inoltre, in questa particolare applicazione, è importante che le regole siano leggibili. Questa semplice regola stava funzionando per un po 'su una varietà di piattaforme. Sarebbe bello se potessi salvarlo con qualcosa di semplice. –

0

È possibile eseguire questa operazione utilizzando la funzione di jolly secondary expansion e. Nota che non è mai stato valido senza questo, quindi qualunque codice tu abbia visto dovrebbe essere considerato non funzionante.

.SECONDEXPANSION: 

all: test.1.out 

test.%.out: $$(wildcard $$*/test*.out) 
    @echo Prerequisites found: $^ 

Nota l'uso di $* piuttosto che % per la partita del modello (vedi automatic variables) è sfuggito per un extra $, e il tutto è impostato per espandere due volte in modo entrambe le serie di valori vengono espansi.

Ciò detto, l'intero layout sembra sbagliato. Stavi usando $< che corrisponde solo alla prima parola dei prerequisiti anche se con un carattere jolly ce ne potrebbero essere molti. Mike's answer è probabilmente una scommessa migliore per riorganizzare il tuo Makefile in realtà essere robusto.

+0

Grazie.Questo è quello che volevo. Capisco cosa ne state dicendo di struttura. Questo particolare caso d'uso coinvolgeva persone che fornivano file con nomi leggermente incoerenti in tempo reale, quindi ero bloccato con una cattiva struttura (ovviamente avrei potuto provare a risolverlo a monte di make, ma in genere penso di fare il primo passo per tutto). Avrei dovuto dirlo in primo luogo. –