2011-06-01 18 views
25

मान लीजिए मैं एक SConstruct फ़ाइल है कि इस तरह दिखता है:कैसे हल करने के लिए "SCons: चेतावनी: दो विभिन्न वातावरण लक्ष्य के लिए निर्दिष्ट किया गया"

env = Environment() 

env.Program("a", ["a.c", "util.c"]) 
env.Program("b", ["b.c", "util.c"]) 

यह निर्माण चेतावनी संदेश नहीं SCons के साथ ठीक से काम करता है। हालांकि, अगर मैं इस प्रत्येक Program निर्माण के लिए अलग पुस्तकालयों निर्दिष्ट करने के लिए संशोधित (वास्तविक पुस्तकालयों नहीं प्रासंगिक हैं):

 
scons: warning: Two different environments were specified for target util.o, 
     but they appear to have the same action: $CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES 

इस वजह से प्रतीत होता है:

env.Program("a", ["a.c", "util.c"], LIBS="m") 
env.Program("b", ["b.c", "util.c"], LIBS="c") 

तो मैं चेतावनी मिलती है Program बिल्डर द्वारा स्वचालित रूप से स्रोत बनाने के लिए एक नया वातावरण बना रहा है, भले ही यह केवल LIBS चर है जो अलग है (और इसलिए केवल लिंक चरण में एक अलग वातावरण होना चाहिए)। मैं इस के आसपास की तरह कुछ करने से काम कर सकते हैं:

util = env.Object("util.c") 
env.Program("a", ["a.c"] + util, LIBS="m") 
env.Program("b", ["b.c"] + util, LIBS="c") 

यह util.c निर्माण, तो प्रत्येक Program निर्माण में precompiled वस्तु फ़ाइल का उपयोग कर, इस प्रकार की चेतावनी से बचने के लिए एक ही Object बिल्डर का उपयोग करता है। हालांकि, यह वास्तव में आवश्यक नहीं होना चाहिए। क्या इस समस्या के आसपास काम करने का एक और शानदार तरीका है? या यह वास्तव में स्कैन में एक बग है जिसे तय किया जाना चाहिए?

संदर्भ: मेरे पास लगभग 20 पुस्तकालयों और 120 एक्जिक्यूटिव में कई साझा स्रोतों के साथ संकलित लगभग 2000 सी स्रोत फ़ाइलें हैं। मैंने लिखा है कि एक रूपांतरण स्क्रिप्ट का उपयोग कर पिछले मालिकाना निर्माण प्रणाली से SConstruct फ़ाइल बनाई। मेरे वर्तमान SConstruct का उपयोग कर पूर्ण निर्माण के लिए स्कैन द्वारा उत्पादित 450 "दो अलग-अलग वातावरण" चेतावनी संदेश हैं।

env.Program("a", ["a.c", env.Object("util.c")], LIBS="m") 
env.Program("b", ["b.c", env.Object("util.c")], LIBS="c") 

यह एक एकल पर्यावरण के भीतर util.c के निर्माण को अलग:

उत्तर

19

मैं एक समाधान है कि अतिरिक्त चर बनाने वस्तु फ़ाइल नोड्स धारण करने के लिए शामिल नहीं करता पाया। हालांकि इसे दो बार निर्दिष्ट किया गया है, एक बार प्रत्येक Program के लिए, स्कैन इस बारे में चेतावनी नहीं देते हैं क्योंकि यह वही स्रोत है जो उसी env ऑब्जेक्ट के साथ बनाया गया है। निस्संदेह स्कैन केवल इस मामले में स्रोत को संकलित करता है।

0

मेरे कोड में मुझे मिली एक समस्या यह थी कि मैं लक्ष्य ऑब्जेक्ट पथ का सही उपयोग नहीं कर रहा था। या अन्य शब्दों में मेरे पास एक वैरिएंट डायर निर्देश था, लेकिन BUILDPATH का उपयोग करने के बजाय मैं अपने मूल स्रोत कोड पथ का उपयोग कर समाप्त हुआ। इस तरह स्कॉन्स लक्ष्य BUILDPATH और स्रोत पथ में उत्पन्न वस्तु को ढूंढ रहा था।

9

आप बड़ी परियोजनाओं के लिए निर्माण प्रक्रिया को सरल बनाने के विभाजित करें फ़ंक्शन और एक कस्टम सहायक का उपयोग हो सकता है:

def create_objs(SRCS, path=""): 
    return [env.Object(path+src+".cpp") for src in SRCS] 

prg1 = Split("file_1 file_2 file_N") 
prg2 = Split("file_2 file_5 file_8") 

env.Program("a", create_objs(prg1), LIBS="x") 
env.Program("b", create_objs(prg2), LIBS="y") 

वस्तु फ़ाइलों केवल एक बार बनाई गई हैं, और वे एक से अधिक में इस्तेमाल किया जा सकता बनाता है। उम्मीद है कि यह मदद करता है ...

+0

मैंने इस समाधान को वोट दिया क्योंकि मुझे यह याद रखने की आवश्यकता नहीं है कि प्रत्येक ऑब्जेक्ट को किस वातावरण में संकलित किया गया है। सभी एक ही वातावरण में संकलित हैं। यह स्कॉन्स्क्रिप्ट फ़ाइल को साफ करने की अनुमति भी देता है। मैंने .cpp प्रत्यय को स्वचालित रूप से संलग्न न करने के लिए create_obj फ़ंक्शन को संशोधित किया –

1

फाइलों के पहले सेट से एक स्थिर लाइब्रेरी बनाना और लाइब्रेरी को फाइलों के अगले सेट (जिसमें पहले सेट के साथ कुछ फाइलें हैं) को जोड़ने के लिए एक लक्ष्य कार्य भी तैयार करने के लिए ।

env.StaticLibrary ("a", ["a.c","util.c"], LIBS = "m") 
env.Program ("b", ["b.c","util.c"], LIBS = ["c","a"]) 
संबंधित मुद्दे