diff options
author | William Deegan <bill@baddogconsulting.com> | 2019-12-10 16:24:13 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-10 16:24:13 (GMT) |
commit | 00c82b641c13ede400982f51b75f01938c99353b (patch) | |
tree | 2a217fa865d49438b730b4f2472f168719d726ac /src | |
parent | dc8aaebf2271cbd78edeeda923ce2c8acd67f946 (diff) | |
parent | 392d323e36bf8c80c7a6d43160148359cfae8ff6 (diff) | |
download | SCons-00c82b641c13ede400982f51b75f01938c99353b.zip SCons-00c82b641c13ede400982f51b75f01938c99353b.tar.gz SCons-00c82b641c13ede400982f51b75f01938c99353b.tar.bz2 |
Merge branch 'master' into py3-doctasks
Diffstat (limited to 'src')
-rwxr-xr-x | src/CHANGES.txt | 11 | ||||
-rw-r--r-- | src/engine/SCons/ActionTests.py | 4 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 41 | ||||
-rw-r--r-- | src/engine/SCons/Environment.xml | 22 | ||||
-rw-r--r-- | src/engine/SCons/Platform/win32.py | 58 | ||||
-rw-r--r-- | src/engine/SCons/SConfTests.py | 28 | ||||
-rw-r--r-- | src/engine/SCons/Script/Main.py | 7 | ||||
-rw-r--r-- | src/engine/SCons/Script/Main.xml | 37 | ||||
-rw-r--r-- | src/engine/SCons/Script/SConsOptions.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Tool/MSCommon/vc.py | 9 |
10 files changed, 154 insertions, 65 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index e24555d..47b63ee 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,6 +4,8 @@ Change Log +NOTE: Please add your name below (and your changes) alphabetically by last name. + RELEASE VERSION/DATE TO BE FILLED IN LATER From Edoardo Bezzeccheri @@ -16,6 +18,15 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Tim Gates - Resolved a typo in engine.SCons.Tool + From Adam Gross: + - Resolved a race condition in multithreaded Windows builds with Python 2 + in the case where a child process is spawned while a Python action has a + file open. Original author: Ryan Beasley. + + From Jason Kenny + - Update Command() function to accept target_scanner, source_factory, and target_factory arguments. + This makes Command act more like a one-off builder. + From Ivan Kravets - Added support for "-imacros" to ParseFlags diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 3054368..3303750 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -1208,10 +1208,6 @@ class CommandActionTestCase(unittest.TestCase): # Newer cygwin seems to return 126 for following expect_nonexecutable_file = 126 expect_nonexecutable_dir = 127 - elif sys.platform.find('sunos') != -1: - expect_nonexistent = 1 - expect_nonexecutable_file = 1 - expect_nonexecutable_dir = 1 else: expect_nonexistent = 127 expect_nonexecutable_file = 126 diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 1296f54..916ebc4 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1983,13 +1983,42 @@ class Base(SubstitutionEnvironment): be any type that the Builder constructor will accept for an action.""" bkw = { - 'action' : action, - 'target_factory' : self.fs.Entry, - 'source_factory' : self.fs.Entry, + 'action': action, + 'target_factory': self.fs.Entry, + 'source_factory': self.fs.Entry, } - try: bkw['source_scanner'] = kw['source_scanner'] - except KeyError: pass - else: del kw['source_scanner'] + # source scanner + try: + bkw['source_scanner'] = kw['source_scanner'] + except KeyError: + pass + else: + del kw['source_scanner'] + + # target scanner + try: + bkw['target_scanner'] = kw['target_scanner'] + except KeyError: + pass + else: + del kw['target_scanner'] + + # source factory + try: + bkw['source_factory'] = kw['source_factory'] + except KeyError: + pass + else: + del kw['source_factory'] + + # target factory + try: + bkw['target_factory'] = kw['target_factory'] + except KeyError: + pass + else: + del kw['target_factory'] + bld = SCons.Builder.Builder(**bkw) return bld(self, target, source, **kw) diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 0963fd2..73c347e 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -937,19 +937,29 @@ for a single special-case build. </para> <para> -As a special case, the -<varname>source_scanner</varname> -keyword argument can +&b-Command; builder accepts +<varname>source_scanner</varname>, +<varname>target_scanner</varname>, +<varname>source_factory</varname>, and +<varname>target_factory</varname> +keyword arguments. The *_scanner args can be used to specify a Scanner object -that will be used to scan the sources. -(The global +that will be used to apply a custom +scanner for a source or target. +For example, the global <literal>DirScanner</literal> object can be used if any of the sources will be directories that must be scanned on-disk for changes to files that aren't -already specified in other Builder of function calls.) +already specified in other Builder of function calls. +The *_factory args take a factory function that the +Command will use to turn any sources or targets +specified as strings into SCons Nodes. +See the sections "Builder Objects" +below, for more information about how these +args work in a Builder. </para> <para> diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 0a3b199..77c048e 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -51,10 +51,6 @@ try: import msvcrt import win32api import win32con - - msvcrt.get_osfhandle - win32api.SetHandleInformation - win32con.HANDLE_FLAG_INHERIT except ImportError: parallel_msg = \ "you do not seem to have the pywin32 extensions installed;\n" + \ @@ -66,28 +62,44 @@ except AttributeError: else: parallel_msg = None - _builtin_open = open + if sys.version_info.major == 2: + import __builtin__ + + _builtin_file = __builtin__.file + _builtin_open = __builtin__.open + + def _scons_fixup_mode(mode): + """Adjust 'mode' to mark handle as non-inheritable. + + SCons is multithreaded, so allowing handles to be inherited by + children opens us up to races, where (e.g.) processes spawned by + the Taskmaster may inherit and retain references to files opened + by other threads. This may lead to sharing violations and, + ultimately, build failures. + + By including 'N' as part of fopen's 'mode' parameter, all file + handles returned from these functions are atomically marked as + non-inheritable. + """ + if not mode: + # Python's default is 'r'. + # https://docs.python.org/2/library/functions.html#open + mode = 'rN' + elif 'N' not in mode: + mode += 'N' + return mode - def _scons_open(*args, **kw): - fp = _builtin_open(*args, **kw) - win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()), - win32con.HANDLE_FLAG_INHERIT, - 0) - return fp + class _scons_file(_builtin_file): + def __init__(self, name, mode=None, *args, **kwargs): + _builtin_file.__init__(self, name, _scons_fixup_mode(mode), + *args, **kwargs) - open = _scons_open + def _scons_open(name, mode=None, *args, **kwargs): + return _builtin_open(name, _scons_fixup_mode(mode), + *args, **kwargs) - if sys.version_info.major == 2: - _builtin_file = file - class _scons_file(_builtin_file): - def __init__(self, *args, **kw): - _builtin_file.__init__(self, *args, **kw) - win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()), - win32con.HANDLE_FLAG_INHERIT, 0) - file = _scons_file - else: - # No longer needed for python 3.4 and above. Files are opened non sharable - pass + __builtin__.file = _scons_file + __builtin__.open = _scons_open diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index f770450..787138e 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -56,6 +56,18 @@ class SConfTestCase(unittest.TestCase): os.chdir(self.save_cwd) def _resetSConfState(self): + if sys.platform in ['cygwin', 'win32'] and sys.version_info.major == 2: + # On Windows with Python2, SCons.Platform.win32 redefines the + # built-in file() and open() functions to disable handle + # inheritance. Because we are unloading all SCons modules other + # than SCons.Compat, SCons.Platform.win32 will lose the variables + # it needs. As a result, we should reset the file() and open() + # functions to their original built-in versions. + import __builtin__ + import SCons.Platform.win32 + __builtin__.file = SCons.Platform.win32._builtin_file + __builtin__.open = SCons.Platform.win32._builtin_open + # Ok, this is tricky, and i do not know, if everything is sane. # We try to reset scons' state (including all global variables) import SCons.SConsign @@ -90,22 +102,6 @@ class SConfTestCase(unittest.TestCase): global existing_lib existing_lib = 'm' - if sys.platform in ['cygwin', 'win32']: - # On Windows, SCons.Platform.win32 redefines the builtin - # file() and open() functions to close the file handles. - # This interferes with the unittest.py infrastructure in - # some way. Just sidestep the issue by restoring the - # original builtin functions whenever we have to reset - # all of our global state. - - import SCons.Platform.win32 - - try: - file = SCons.Platform.win32._builtin_file - open = SCons.Platform.win32._builtin_open - except AttributeError: - pass - def _baseTryXXX(self, TryFunc): # TryCompile and TryLink are much the same, so we can test them # in one method, we pass the function as a string ('TryCompile', diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 58dbf64..238a828 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -211,10 +211,9 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): last_command_end = finish_time cumulative_command_time = cumulative_command_time+finish_time-start_time if print_action_timestamps: - sys.stdout.write("Command execution start time: %s: %f seconds\n"%(str(self.node), start_time)) + sys.stdout.write("Command execution start timestamp: %s: %f\n"%(str(self.node), start_time)) + sys.stdout.write("Command execution end timestamp: %s: %f\n"%(str(self.node), finish_time)) sys.stdout.write("Command execution time: %s: %f seconds\n"%(str(self.node), finish_time-start_time)) - if print_action_timestamps: - sys.stdout.write("Command execution stop time: %s: %f seconds\n"%(str(self.node), finish_time)) def do_failed(self, status=2): _BuildFailures.append(self.exception[1]) @@ -679,7 +678,7 @@ def _set_debug_values(options): options.tree_printers.append(TreePrinter(status=True)) if "time" in debug_values: print_time = 1 - if "action_timestamps" in debug_values: + if "action-timestamps" in debug_values: print_time = 1 print_action_timestamps = 1 if "tree" in debug_values: diff --git a/src/engine/SCons/Script/Main.xml b/src/engine/SCons/Script/Main.xml index 83d9605..5c68dee 100644 --- a/src/engine/SCons/Script/Main.xml +++ b/src/engine/SCons/Script/Main.xml @@ -33,11 +33,11 @@ See its __doc__ string for a discussion of the format. This function adds a new command-line option to be recognized. The specified <varname>arguments</varname> -are the same as supported by the standard Python -<function>optparse.add_option</function>() -method (with a few additional capabilities noted below); +are the same as supported by the <function>add_option</function> +method in the standard Python library module <emphasis>optparse</emphasis>, +with a few additional capabilities noted below; see the documentation for -<literal>optparse</literal> +<emphasis>optparse</emphasis> for a thorough discussion of its option-processing capabities. </para> @@ -78,12 +78,22 @@ the option will have a default value of </para> <para> +Unlike regular <emphasis>optparse</emphasis>, option names +added via <function>AddOption</function> must be matched +exactly, the automatic matching of abbreviations on the +command line for long options is not supported. +To allow specific abbreviations, +include them in the &f-AddOption; call. +</para> + +<para> Once a new command-line option has been added with &f-AddOption;, the option value may be accessed using &f-GetOption; or <function>env.GetOption</function>(). +<!-- The value may also be set, using &f-SetOption; or @@ -95,6 +105,9 @@ Note, however, that a value specified on the command line will <emphasis>always</emphasis> override a value set by any SConscript file. +--> +&f-SetOption; is not currently supported for +options added with &f-AddOption;. </para> <para> @@ -133,6 +146,22 @@ AddOption('--prefix', help='installation prefix') env = Environment(PREFIX = GetOption('prefix')) </example_commands> + +<note> +<para> +While &AddOption; behaves like +<function>add_option</function>, +from the <emphasis>optparse</emphasis> module, +the behavior of options added by &AddOption; +which take arguments is underfined in +<command>scons</command> if whitespace +(rather than an <literal>=</literal> sign) is used as +the separator on the command line when +the option is invoked. +Such usage should be avoided. +</para> +</note> + </summary> </scons_function> diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index 7b5d523..66c7239 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -622,7 +622,7 @@ def Parser(version): debug_options = ["count", "duplicate", "explain", "findlibs", "includes", "memoizer", "memory", "objects", "pdb", "prepare", "presub", "stacktrace", - "time", "action_timestamps"] + "time", "action-timestamps"] def opt_debug(option, opt, value__, parser, debug_options=debug_options, diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 4f6048d..86bdbe0 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -161,11 +161,18 @@ def get_host_target(env): if not host_platform: host_platform = platform.machine() + # Solaris returns i86pc for both 32 and 64 bit architectures + if host_platform == "i86pc": + if platform.architecture()[0] == "64bit": + host_platform = "amd64" + else: + host_platform = "x86" + # Retain user requested TARGET_ARCH req_target_platform = env.get('TARGET_ARCH') debug('get_host_target() req_target_platform:%s'%req_target_platform) - if req_target_platform: + if req_target_platform: # If user requested a specific platform then only try that one. target_platform = req_target_platform else: |