2011-09-21 8 views
5

Qual è il metodo SCONS corretto per l'aggiornamento del contenuto di un file che fa parte della compilazione?Come rendere SCONS aggiornare il contenuto di un file utilizzato in una build

Uso SCONS per creare un progetto abbastanza grande. Ma per il bene di una semplice domanda, per scontato che assomiglia a questo:

env.Program("foo", ["foo.c", "version.c"]) 

In determinate condizioni di compilazione, è necessario aggiornare il contenuto di uno dei file CPP nella build con nuove informazioni - informazioni sulla versione in realtà. Nell'esempio sopra, avrei bisogno di modificare il contenuto di "version.c". Ho pensato che avrei potuto fare questo piuttosto bene con il seguente esempio:

env.Command(target="version.c", source=[], action=PythonFunctionToUpdateContents) 
env.Program("foo", ["foo.c", "version.c"]) 

I PythonFunctionToUpdateContents userebbero obiettivo [0] come il nome del file, aprirlo, cercare qualche testo specifico, cambiarlo, scrivere le modifiche torna allo stesso file. Sfortunatamente, l'esempio sopra non funziona. SCONS elimina automaticamente un file di destinazione prima di costruirlo, quindi il mio file "version.c" è stato eliminato prima che potesse essere aggiornato.

Ho provato a impostare il target e l'origine sullo stesso file nella chiamata env.Command(), ma ciò crea solo un ciclo di dipendenze.

So che potrei risolvere questo problema facendo in modo che SCONS generi il file ENTRE versione.c, ma non è adatto poiché version.c contiene molti altri codici che possono cambiare come parte del normale sviluppo.

risposta

5

Il solito modo per farlo è avere un "version.c.in" o "version-in.c" o qualsiasi altra cosa si voglia chiamare. Modificalo e mostralo a version.c. Dovresti aggiungere il file "in" al tuo sistema di controllo della versione, mentre il file version.c non ci sarà. Così il risultato di tutto questo apparirebbe come segue:

env.Command(target="version.c", source="version-in.c", 
      action=PythonFunctionToUpdateContents) 
env.Program("foo", ["foo.c", "version.c"]) 

Questo vale anche per gli altri sistemi di compilazione troppo - è generalmente una cattiva idea di avere un file di input anche essere un file di output. Molto meglio usare un file intermedio per portare a termine il lavoro.

+0

L'esempio era troppo semplice, forse. La mia chiamata "env.Program()" è in realtà una chiamata esterna a un processo di generazione di terze parti che non è basato su SCONS. Quindi sto cercando di ottenere il file modificato prima di avviare il processo. Sono d'accordo: modificare il file non è una buona idea. Ma non ho il controllo su quella parte del processo di costruzione. –

+1

Lo stesso principio si applica però: si dispone di un file che si controlla che è il modello dell'input per il processo di build esterno. Crea una copia modificata del tuo modello nella directory pertinente prima di dare il via al processo esterno. In caso contrario, è sempre possibile creare un'intera copia della build di terze parti (potrebbe non essere pratico) e modificare i file in tale copia. – richq

5

Questa risposta è un pò in ritardo alla festa, ma qui è in ogni caso:

Si dovrebbe usare env.Precious("version.c"). Ciò impedisce che il file venga eliminato prima di essere creato.

Probabilmente si desidera utilizzare anche env.NoClean("version.c") in modo che non venga eliminato durante una pulizia.

Si potrebbe usare env.SideEffect forse, ma quello sembra avere un paio di cose strane a riguardo. Mi è stato detto sulla mailing list di non usarlo in generale.

+0

Aggiornamento per chiunque legga questa risposta: 'env.SideEffect' dovrebbe essere usato per quando più builder genereranno lo stesso file (come ad esempio un log, un file binario che contiene un contatore, ecc.); Non penso che sarebbe di aiuto in questa situazione. L'abbinamento di 'Prezioso' e' NoClean' sarebbe la soluzione "corretta". –

Problemi correlati