Handle Configure() calls in multiple SConscript files.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 8 Jan 2004 02:01:05 +0000 (02:01 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 8 Jan 2004 02:01:05 +0000 (02:01 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@870 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Script/SConscript.py
test/Configure.py

index ba14d78af1d7b45fccb8078535d7ee333437e164..249b0787aa84198fb0b910d522017251ad4a7275 100644 (file)
@@ -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.
index 0c9b22f978f6e5e3702aa3576387379200e49df8..521429f23a81d2324563b55bff095f38233d91ef 100644 (file)
@@ -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.
     """
 
index 9c5d14a376d71561125aca8c91f6ff7d89f03fd4..6d024f2e7bf83a3b1c3b8de7683c1ec3f7821e7f 100644 (file)
@@ -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 <stdio.h>\\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' ))