2011-11-22 14 views
5

Dizeleri değiştirmek ve scons komut dosyasında çağırmak gibi bir python işlevi yazarım. i bekliyordun ki SConscriptSCONS: Scons komut dosyasında kendinden tanımlı bir python işlevi nasıl çağrılır ve doğru bağımlılık yapılır

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

yılında

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şa lib sonra değiştirin() yöntemini çalıştırmaktır. ancak scons, her zaman Replace() komutunu ilk yuvarlak kod ayrıştırma deyiminde çalıştırır. Bazı bağımlılık eksik gözüküyor.

cevap

4

Muhtemelen builders that execute python functions'u aradığınızı düşünüyorum.

Zor olan, SCON'ların, zorlandığınız şekilde çalışmak istememesidir. Oluşturma eylemleri kodunuzda yinelenebilir ve tahribatsız olmalı, aslında somefile'un orijinal içeriğini yok ediyorsunuz. Bunun yerine, aynı sonucu elde etmek için hedef/kaynak paradigmasını ve bir çeşit şablon dosyasını kullanabilirsiniz. benim test yerine işlev çok hatlı verilerle güzel oynuyor değildi, bu yüzden sadece tam düzenli ifadeler (re.sub) kullanarak takas ettik

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) 

Not. Bu muhtemelen daha yavaştır, ancak önemli ölçüde daha fazla esneklik sunar.

İlgili konular