2012-12-19 12 views
7

मैं एकाधिक लक्ष्य उत्पन्न करने के लिए SCons प्राप्त करने का प्रयास कर रहा हूं (SConscript में सीधे अज्ञात संख्या)। ,लक्ष्यों की परिवर्तनीय संख्या उत्पन्न करने के लिए स्कैन

headers/ 
    Header1.h 
    Header2.h 
    Header3.h 
    Header4.h 
meta/ 
    headers_list.txt 

अब मैं SConscript headers_list.txt को पढ़ने के लिए, आधारित पर इसकी सामग्री headers/ निर्देशिका से फ़ाइलों को लेने चाहते हैं (यानी यह केवल Header1 और Header3 शामिल हो सकता है) के लिए उन में से प्रत्येक मैं चाहता हूँ:

मैं निर्देशिका की तरह है कुछ फ़ंक्शन का उपयोग करके स्रोत उत्पन्न करने के लिए।

मैं ऐसा करने के लिए env.Command का उपयोग करने का प्रयास कर रहा हूं, लेकिन समस्या यह है कि कॉलर को लक्ष्य सूची निर्दिष्ट करने की आवश्यकता होती है जो स्पष्ट कारणों से env.Command का आह्वान करते समय ज्ञात नहीं है।

केवल एक चीज मैं के बारे में सोच सकते हैं चल रहा है:

for header in parse(headers_file): 
    source = mangle_source_name_for_header(header) 
    env.Command(source, header, generator_action) 

लेकिन इसका मतलब यह है कि मैं हर बार जब मैं आह्वान scons चल रहा हो जाएगा parse(headers_file)। यदि पार्सिंग महंगा है और फ़ाइल को अक्सर नहीं बदला जाता है तो इस चरण को आसानी से कैश किया जा सकता है।

उस कैशिंग को प्राप्त करने के लिए मुझे क्या स्कैनस्क निर्माण/कक्षा/तकनीक याद आ रही है?

संपादित करें:

ऐसा लगता है मेरे सवाल Build-time determination of SCons targets के समान है, लेकिन वहाँ कृत्रिम डमी फ़ाइल के बिना एक तकनीक नहीं है?

इसके अलावा, यहां तक ​​कि अस्थायी फ़ाइल के साथ, मैं नहीं देख सकते कि मैं Command कि दूसरा एक है कि उन पर पुनरावृति होगी लक्ष्यों की चर संख्या उत्पन्न करता है से target चर पारित करना चाहिए है।

संपादित 2:

This होनहार लग रहा है।

उत्तर

3

मुझे मिला एकमात्र तरीका मैं इसे कर सकता हूं emitter के साथ है। उदाहरण नीचे 3 फ़ाइलें के होते हैं:

./ 
|-SConstruct 
|-src/ 
| |-SConscript 
| |-source.txt 
|-build/ 

SConstruct

env = Environment() 

dirname = 'build' 
VariantDir(dirname, 'src', duplicate=0) 

Export('env') 

SConscript(dirname+'/SConscript') 

src/SConscript

Import('env') 

def my_emitter(env, target, source): 
    data = str(source[0]) 
    target = [] 
    with open(data, 'r') as lines: 
     for line in lines: 
      line = line.strip() 
      name, contents = line.split(' ', 1) 
      if not name: continue 

      generated_source = env.Command(name, [], 'echo "{0}" > $TARGET'.format(contents)) 
      source.extend(generated_source) 
      target.append(name+'.c') 

    return target, source 

def my_action(env, target, source): 
    for t,s in zip(target, source[1:]): 
     with open(t.abspath, 'w') as tf: 
      with open(s.abspath, 'r') as sf: 
       tf.write(sf.read()) 

SourcesGenerator = env.Builder(action = my_action, emitter = my_emitter) 
generated_sources = SourcesGenerator(env, source = 'source.txt') 

lib = env.Library('functions', generated_sources) 

src/source.txt

a int a(){} 
b int b(){} 
c int c(){} 
d int d(){} 
g int g(){} 

आउटपुट:

$ scons 
scons: Reading SConscript files ... 
scons: done reading SConscript files. 
scons: Building targets ... 
echo "int a(){}" > build/a 
echo "int b(){}" > build/b 
echo "int c(){}" > build/c 
echo "int d(){}" > build/d 
echo "int g(){}" > build/g 
my_action(["build/a.c", "build/b.c", "build/c.c", "build/d.c", "build/g.c"], ["src/source.txt", "build/a", "build/b", "build/c", "build/d", "build/g"]) 
gcc -o build/a.o -c build/a.c 
gcc -o build/b.o -c build/b.c 
gcc -o build/c.o -c build/c.c 
gcc -o build/d.o -c build/d.c 
gcc -o build/g.o -c build/g.c 
ar rc build/libfunctions.a build/a.o build/b.o build/c.o build/d.o build/g.o 
ranlib build/libfunctions.a 
scons: done building targets. 

इसके अलावा इस एक बात मैं वास्तव में नहीं है की तरह है, जो प्रत्येक scons निष्पादन के साथ headers_list.txt की पार्स करने जाता है। मुझे लगता है कि फाइल को बदलने पर ही इसे पार्स करने का कोई तरीका होना चाहिए। मैं इसे हाथ से पकड़ सकता था, लेकिन मुझे उम्मीद है कि स्कैन को मेरे लिए कैशिंग करने के लिए कुछ चाल है।

और मुझे फ़ाइलों को डुप्लिकेट करने का कोई तरीका नहीं मिला (a और a.c वही होना)। स्रोतों की बजाय my_action में लाइब्रेरी जेनरेट करना एक तरीका होगा (जो दृष्टिकोण है जो मैंने अपने अंतिम समाधान में उपयोग किया था)।

संबंधित मुद्दे