From f8c9c501ae3193a95fe9d6b238809ea59329d752 Mon Sep 17 00:00:00 2001 From: stevenknight Date: Thu, 8 Jan 2004 02:01:05 +0000 Subject: [PATCH] Handle Configure() calls in multiple SConscript files. git-svn-id: http://scons.tigris.org/svn/scons/trunk@870 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/CHANGES.txt | 2 ++ src/engine/SCons/Script/SConscript.py | 26 +++++++------- test/Configure.py | 52 ++++++++++++++++++--------- 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index ba14d78a..249b0787 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -107,6 +107,8 @@ RELEASE 0.95 - XXX expansion of variables (e.g. CCFLAGS = "$CCFLAGS -g") without going into an infinite loop. + - Fix calling Configure() from more than one subsidiary SConscript file. + From Vincent Risi: - Add support for the bcc32, ilink32 and tlib Borland tools. diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 0c9b22f9..521429f2 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -1,6 +1,6 @@ """SCons.Script.SConscript -This module defines the Python API provided to SConscript and SConstruct +This module defines the Python API provided to SConscript and SConstruct files. """ @@ -101,12 +101,12 @@ def get_calling_namespaces(): into this module in the current callstack.""" try: 1/0 except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame - + while frame.f_globals.get("__name__") == __name__: frame = frame.f_back return frame.f_locals, frame.f_globals - + def compute_exports(exports): """Compute a dictionary of exports given one of the parameters to the Export() function or the exports argument to SConscript().""" @@ -127,13 +127,13 @@ def compute_exports(exports): raise SCons.Errors.UserError, "Export of non-existent variable '%s'"%x return retval - + class Frame: """A frame on the SConstruct/SConscript call stack""" def __init__(self, exports, sconscript): self.globals = BuildDefaultGlobals() - self.retval = None + self.retval = None self.prev_dir = SCons.Node.FS.default_fs.getcwd() self.exports = compute_exports(exports) # exports from the calling SConscript # make sure the sconscript attr is a Node. @@ -141,7 +141,7 @@ class Frame: self.sconscript = sconscript else: self.sconscript = SCons.Node.FS.default_fs.File(str(sconscript)) - + # the SConstruct/SConscript call stack: stack = [] @@ -155,15 +155,13 @@ def Return(*vars): retval.append(stack[-1].globals[v]) except KeyError, x: raise SCons.Errors.UserError, "Return of non-existent variable '%s'"%x - + if len(retval) == 1: stack[-1].retval = retval[0] else: stack[-1].retval = tuple(retval) def _SConscript(fs, *files, **kw): - global sconscript_reading - sconscript_reading = 1 top = fs.Top sd = fs.SConstruct_dir.rdir() exports = kw.get('exports', []) @@ -174,6 +172,8 @@ def _SConscript(fs, *files, **kw): stack.append(Frame(exports,fn)) old_sys_path = sys.path try: + global sconscript_reading + sconscript_reading = 1 if fn == "-": exec sys.stdin in stack[-1].globals else: @@ -238,7 +238,7 @@ def _SConscript(fs, *files, **kw): else: SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, "Ignoring missing SConscript '%s'" % f.path) - + finally: sconscript_reading = 0 sys.path = old_sys_path @@ -525,13 +525,13 @@ def GetJobs(): "\tuse GetOption('num_jobs') instead.") return GetOption('num_jobs') - + def SetJobs(num): SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, "The SetJobs() function has been deprecated;\n" +\ "\tuse SetOption('num_jobs', num) instead.") SetOption('num_jobs', num) - + def ParseConfig(env, command, function=None): SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, "The ParseConfig() function has been deprecated;\n" +\ @@ -664,7 +664,7 @@ for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders: def BuildDefaultGlobals(): """ - Create a dictionary containing all the default globals for + Create a dictionary containing all the default globals for SConstruct and SConscript files. """ diff --git a/test/Configure.py b/test/Configure.py index 9c5d14a3..6d024f2e 100644 --- a/test/Configure.py +++ b/test/Configure.py @@ -72,7 +72,7 @@ def checkLog( test, logfile, numUpToDate, numCache ): test.fail_test( len( re.findall( "\(cached\): Building \S+ failed in a previous run.", log ) ) != numCache ) except: print "contents of log ", test.workpath(work_dir, logfile), "\n", log - raise + raise try: @@ -80,7 +80,7 @@ try: # 1.1 if checks are ok, the cache mechanism should work reset(match=2) - + test.write([work_dir, 'SConstruct'], """ env = Environment() import os @@ -140,14 +140,14 @@ Checking for main() in C library no_c_library_SAFFDG... no test.run(chdir=work_dir, stdout = required_stdout) checkLog(test, 'config.log', 0, 0 ) - + test.run(chdir=work_dir, stdout = required_stdout) checkLog(test, 'config.log', 2, 2 ) # 2.1 test that normal builds work together with Sconf reset() - + test.write([work_dir, 'SConstruct'], """ env = Environment() @@ -178,14 +178,14 @@ Checking for C header file no_std_c_header.h... no """) test.run(chdir=work_dir, stdout = required_stdout ) checkLog( test, 'config.log', 0, 0 ) - + test.run(chdir=work_dir, stdout = required_stdout ) checkLog( test, 'config.log', 3, 1 ) # 2.2 test that BuildDir builds work together with Sconf reset() - + test.write([work_dir, 'SConstruct'], """ env = Environment(LOGFILE='build/config.log') @@ -218,10 +218,10 @@ Checking for C header file no_std_c_header.h... no """) test.run(chdir=work_dir, stdout = required_stdout ) checkLog( test, 'build/config.log', 0, 0 ) - + test.run(chdir=work_dir, stdout = required_stdout ) checkLog( test, 'build/config.log', 3, 1 ) - + # 2.3 test that Configure calls in SConscript files work # even if BuildDir is set reset() @@ -307,15 +307,15 @@ Executing Custom Test ... ok # 3.1 test custom tests reset() - + compileOK = '#include \\nint main() {printf("Hello");return 0;}' - compileFAIL = "syntax error" + compileFAIL = "syntax error" linkOK = compileOK linkFAIL = "void myFunc(); int main() { myFunc(); }" runOK = compileOK runFAIL = "int main() { return 1; }" - test.write([work_dir, 'pyAct.py'], 'import sys\nprint sys.argv[1]\nsys.exit(int(sys.argv[1]))\n') - test.write([work_dir, 'SConstruct'], """ + test.write([work_dir, 'pyAct.py'], 'import sys\nprint sys.argv[1]\nsys.exit(int(sys.argv[1]))\n') + test.write([work_dir, 'SConstruct'], """ def CheckCustom(test): test.Message( 'Executing MyTest ... ' ) retCompileOK = test.TryCompile( '%s', '.c' ) @@ -374,7 +374,7 @@ env = conf.Finish() # 4.2 test that calling Configure from a builder results in a # readable Error reset(match=2) - + test.write([work_dir, 'SConstruct'], """ def ConfigureAction(target, source, env): env.Configure() @@ -385,13 +385,33 @@ env.MyAction('target', []) """) test.run(chdir=work_dir, status=2, stderr="scons: *** Calling Configure from Builders is not supported.\n") - + + # 4.3 test the calling Configure from multiple subsidiary + # SConscript files does *not* result in an error. + + test.subdir([work_dir, 'dir1'], [work_dir, 'dir2']) + test.write([work_dir, 'SConstruct'], """ +env = Environment() +SConscript(dirs=['dir1', 'dir2'], exports="env") +""") + test.write([work_dir, 'dir1', 'SConscript'], """ +Import("env") +conf = env.Configure() +conf.Finish() +""") + test.write([work_dir, 'dir2', 'SConscript'], """ +Import("env") +conf = env.Configure() +conf.Finish() +""") + test.run(chdir=work_dir) + test.pass_test() - + finally: pass #os.system( 'find . -type f -exec ls -l {} \;' ) #print "-------------config.log------------------" #print test.read( test.workpath('config.log' )) - #print "-------------build/config.log------------" + #print "-------------build/config.log------------" #print test.read( test.workpath('build/config.log' )) -- 2.26.2