2011-11-22 16 views
5

Tôi viết hàm python như thay thế chuỗi và được gọi trong tập lệnh scons.SCons: Cách gọi hàm python tự xác định trong tập lệnh scons và làm phụ thuộc đúng

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') 

Trong SConscript

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

gì tôi mong đợi là chạy Phương thức Replace() sau khi lib xây dựng. nhưng scons luôn chạy Replace() trong cụm từ phân tích cú pháp kịch bản lệnh đầu tiên. có vẻ như tôi thiếu một số phụ thuộc.

Trả lời

4

Tôi tin rằng bạn có thể đang tìm kiếm builders that execute python functions.

Điều khó hiểu là SCons không thực sự muốn làm việc theo cách bạn buộc nó. Các hành động xây dựng nên có thể lặp lại và không phá hủy, trong mã của bạn, bạn thực sự đang hủy các nội dung gốc của somefile. Thay vào đó, bạn có thể sử dụng mô hình đích/nguồn và một số loại tệp mẫu để đạt được kết quả tương tự.

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) 

Lưu ý rằng trong thử nghiệm của tôi, thay thế chức năng đã không chơi độc đáo với dữ liệu nhiều dòng, vì vậy tôi đã chỉ cần hoán đổi để sử dụng đầy đủ biểu thức thông thường (re.sub). Điều này có thể chậm hơn nhưng mang lại sự linh hoạt hơn đáng kể.

Các vấn đề liên quan