2011-11-22 13 views
5

Scrivo una funzione python come sostituire le stringhe e richiamare lo script scons.SCons: come chiamare una funzione python definita nello script scons e fare la giusta dipendenza

def Replace(env, filename, old, new): 
    with open(filename,"r+") as f: 
    d = f.read() 
    d = d.replace(old, new) 
    f.truncate(0) 
    f.seek(0) 
    f.write(d) 
    f.close() 
env.AddMethod(Replace,'Replace') 

In SConscript

lib = env.SharedLibrary('lib', object, extra_libs) 
tmp = env.Command([],[],[env.Replace(somefile, 'A', 'b')]) 
env.Depends(tmp,lib) 

quello che mi aspetto è quello di eseguire il metodo replace() dopo il lib costruito. ma scons esegue sempre Replace() nella prima frase di parsing dello script round. sembra che manchi qualche dipendenza.

risposta

4

Credo che probabilmente stai cercando builders that execute python functions.

La cosa complicata è che SCons non vuole davvero funzionare nel modo in cui lo stai forzando. Le azioni di compilazione dovrebbero essere ripetibili e non distruttive, nel tuo codice stai effettivamente distruggendo il contenuto originale di somefile. Invece, è possibile utilizzare il paradigma target/sorgente e alcuni tipi di file modello per ottenere lo stesso risultato.

import os 
import re 

def replace_action(target, source, env): 
    # NB. this is a pretty sloppy way to write a builder, but 
    #  for things that are used internally or infrequently 
    #  it should be more than sufficient 
    assert(len(target) == 1) 
    assert(len(source) == 1) 
    srcf = str(source[0]) 
    dstf = str(target[0]) 
    with open(srcf, "r") as f: 
     contents = f.read() 
     # In cases where this builder fails, check to make sure you 
     # have correctly added REPLST to your environment 
     for old, new in env['REPLST']: 
      contents = re.sub(old, new, contents) 
     with open(dstf, "w") as outf: 
      outf.write(contents) 

replace_builder = Builder(action = replace_action) 

env = Environment(ENV = os.environ) 
env.Append(BUILDERS = {'Replace' : replace_builder }) 
b = env.Replace('somefile', ['somefile.tmpl'], REPLST=[('A','b')]) 
lib = env.SharedLibrary('lib', object + [b], extra_libs) 

Si noti che nel mio test, la funzione di sostituzione non stava giocando bene con i dati multi-linea, così ho solo scambiato a usare le espressioni regolari completi (re.sub). Questo è probabilmente più lento, ma offre molta più flessibilità.

Problemi correlati