summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/generated/builders.gen13
-rw-r--r--doc/generated/functions.gen26
-rw-r--r--doc/generated/variables.gen67
-rw-r--r--doc/man/scons.xml57
-rw-r--r--doc/user/command-line.xml63
-rwxr-xr-xsrc/CHANGES.txt11
-rw-r--r--src/engine/SCons/ActionTests.py4
-rw-r--r--src/engine/SCons/Environment.py41
-rw-r--r--src/engine/SCons/Environment.xml22
-rw-r--r--src/engine/SCons/Platform/win32.py58
-rw-r--r--src/engine/SCons/SConfTests.py28
-rw-r--r--src/engine/SCons/Script/Main.py7
-rw-r--r--src/engine/SCons/Script/Main.xml37
-rw-r--r--src/engine/SCons/Script/SConsOptions.py2
-rw-r--r--src/engine/SCons/Tool/MSCommon/vc.py9
-rw-r--r--test/Clang/clang_shared_library.py2
-rw-r--r--test/Clang/clangxx_shared_library.py3
-rw-r--r--test/Command.py46
-rw-r--r--test/Errors/execute-a-directory.py6
-rw-r--r--test/Errors/non-executable-file.py6
-rw-r--r--test/LINK/VersionedLib.py12
-rw-r--r--test/SWIG/recursive-includes-cpp.py2
-rw-r--r--test/option/debug-action-timestamps.py10
-rw-r--r--testing/framework/TestCommon.py4
24 files changed, 362 insertions, 174 deletions
diff --git a/doc/generated/builders.gen b/doc/generated/builders.gen
index eb7fbca..65201ea 100644
--- a/doc/generated/builders.gen
+++ b/doc/generated/builders.gen
@@ -44,8 +44,9 @@ env.CFile(target = 'bar', source = 'bar.y')
<term>
<function>env.Command()</function>
</term>
- <listitem><para>
-The <function>Command</function> "Builder" is actually
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+The <function xmlns="http://www.scons.org/dbxsd/v1.0">Command</function> "Builder" is actually
a function that looks like a Builder,
but takes a required third argument, which is the
action to take to construct the target
@@ -53,7 +54,7 @@ from the source, used for "one-off" builds
where a full builder is not needed.
Thus it does not follow the builder
calling rules described at the start of this section.
-See instead the <link linkend="f-Command"><function>Command</function></link> function description
+See instead the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="f-Command"><function>Command</function></link> function description
for the calling syntax and details.
</para>
</listitem>
@@ -453,7 +454,7 @@ a builder.
env.Install('/usr/local/bin', source = ['foo', 'bar'])
</example_commands>
-<para>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
If the <option>--install-sandbox</option> command line
option is given, the target directory will be prefixed
by the directory path specified.
@@ -461,8 +462,8 @@ This is useful to test installs without installing to
a "live" location in the system.
</para>
-<para>
-See also <function>FindInstalledFiles</function>.
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+See also <function xmlns="http://www.scons.org/dbxsd/v1.0">FindInstalledFiles</function>.
For more thoughts on installation, see the User Guide
(particularly the section on Command-Line Targets
and the chapters on Installing Files and on Alias Targets).
diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen
index dd6d4dd..28160ba 100644
--- a/doc/generated/functions.gen
+++ b/doc/generated/functions.gen
@@ -217,6 +217,21 @@ AddOption('--prefix',
help='installation prefix')
env = Environment(PREFIX = GetOption('prefix'))
</example_commands>
+
+<note xmlns="http://www.scons.org/dbxsd/v1.0">
+<para>
+While <function xmlns="http://www.scons.org/dbxsd/v1.0">AddOption</function> behaves like
+<function>optparse.add_option</function>,
+the behavior of options added by <function xmlns="http://www.scons.org/dbxsd/v1.0">AddOption</function>
+which take arguments is underfined in
+<command>scons</command> if whitespace
+(rather than <literal>=</literal> sign) is used as
+the separator on the command line when
+the option is invoked.
+Such usage should be avoided.
+</para>
+</note>
+
</listitem>
</varlistentry>
<varlistentry id="f-AddPostAction">
@@ -436,7 +451,7 @@ Otherwise, the construction variable
and the value of the keyword argument
are both coerced to lists,
and the lists are added together.
-(See also the <function>Prepend</function> method).
+(See also the <function xmlns="http://www.scons.org/dbxsd/v1.0">Prepend</function> method).
</para>
<para>
@@ -920,7 +935,8 @@ env['DISTDIR'] = 'destination/directory'
env.Command(env.Dir('$DISTDIR')), None, make_distdir)
</example_commands>
-<para>
+
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
Also note that SCons will usually
automatically create any directory necessary to hold a target file,
so you normally don't need to create directories by hand.
@@ -4627,7 +4643,7 @@ the <literal>env['ENV']['PATH']</literal> key does not exist,
the user's current external <envar>PATH</envar>
(<literal>os.environ['PATH']</literal>) is used as fallback.
</para>
-<para>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
On Windows systems, searches for executable
programs with any of the file extensions listed in the
<varname>pathext</varname> keyword argument,
@@ -4641,14 +4657,14 @@ is used as a fallback if <varname>pathext</varname> is
and the key <literal>env['ENV']['PATHEXT']</literal>
does not exist.
</para>
-<para>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
Will not select any
path name or names
in the specified
<varname>reject</varname>
list, if any.
</para>
-<note>
+<note xmlns="http://www.scons.org/dbxsd/v1.0">
<para>
If you would prefer to search
the user's current external <envar>PATH</envar>
diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen
index db4c416..705bf5b 100644
--- a/doc/generated/variables.gen
+++ b/doc/generated/variables.gen
@@ -2602,7 +2602,8 @@ is <quote><literal>-dNOPAUSE -dBATCH -sDEVICE=pdfwrite</literal></quote>
</varlistentry>
<varlistentry id="cv-HOST_ARCH">
<term>HOST_ARCH</term>
- <listitem><para>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
Sets the host architecture for Visual Studio compiler. If not set,
default to the detected host architecture: note that this may depend
on the python you are using.
@@ -2618,7 +2619,8 @@ Valid values are the same as for <envar>$TARGET_ARCH</envar>.
This is currently only used on Windows, but in the future it will be
used on other OSes as well.
</para>
-<para>
+
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
The name of the host hardware architecture used to create the Environment.
If a platform is specified when creating the Environment, then
that Platform's logic will handle setting this value.
@@ -2691,7 +2693,7 @@ to <literal>'.dll'</literal>.
<listitem><para>
Used to override <link linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link>/<link linkend="cv-LDMODULEVERSION"><envar>$LDMODULEVERSION</envar></link> when
generating versioned import library for a shared library/loadable module. If
-undefined, the <link linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link>/<link linkend="cv-LDMODULEVERSION"><envar>$LDMODULEVERSION</envar></link> is used to
+undefined, the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link>/<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-LDMODULEVERSION"><envar>$LDMODULEVERSION</envar></link> is used to
determine the version of versioned import library.
</para>
</listitem>
@@ -2849,7 +2851,7 @@ The command line used to call the Java archive tool.
<listitem><para>
The string displayed when the Java archive tool
is called
-If this is not set, then <envar>$JARCOM</envar> (the command line) is displayed.
+If this is not set, then <envar xmlns="http://www.scons.org/dbxsd/v1.0">$JARCOM</envar> (the command line) is displayed.
</para>
<example_commands>
@@ -2858,7 +2860,7 @@ env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET")
<para>
The string displayed when the Java archive tool
is called
-If this is not set, then <link linkend="cv-JARCOM"><envar>$JARCOM</envar></link> (the command line) is displayed.
+If this is not set, then <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-JARCOM"><envar>$JARCOM</envar></link> (the command line) is displayed.
</para>
<example_commands>
@@ -3205,6 +3207,17 @@ general information on specifying emitters.
</para>
</listitem>
</varlistentry>
+ <varlistentry id="cv-LDMODULEEMITTER">
+ <term>LDMODULEEMITTER</term>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+Contains the emitter specification for the
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-LoadableModule"><function>LoadableModule</function></link> builder.
+The manpage section "Builder Objects" contains
+general information on specifying emitters.
+</para>
+</listitem>
+ </varlistentry>
<varlistentry id="cv-LDMODULEFLAGS">
<term>LDMODULEFLAGS</term>
<listitem><para>
@@ -3359,9 +3372,10 @@ when the <envar>$_LIBDIRFLAGS</envar> variable is automatically generated.
</varlistentry>
<varlistentry id="cv-LIBEMITTER">
<term>LIBEMITTER</term>
- <listitem><para>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
Contains the emitter specification for the
-<link linkend="b-StaticLibrary"><function>StaticLibrary</function></link> builder.
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-StaticLibrary"><function>StaticLibrary</function></link> builder.
The manpage section "Builder Objects" contains
general information on specifying emitters.
</para>
@@ -4741,9 +4755,10 @@ for example.
</varlistentry>
<varlistentry id="cv-PROGEMITTER">
<term>PROGEMITTER</term>
- <listitem><para>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
Contains the emitter specification for the
-<link linkend="b-Program"><function>Program</function></link> builder.
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-Program"><function>Program</function></link> builder.
The manpage section "Builder Objects" contains
general information on specifying emitters.
</para>
@@ -5981,9 +5996,10 @@ If this is not set, then <link linkend="cv-SHFORTRANPPCOM"><envar>$SHFORTRANPPCO
</varlistentry>
<varlistentry id="cv-SHLIBEMITTER">
<term>SHLIBEMITTER</term>
- <listitem><para>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
Contains the emitter specification for the
-<link linkend="b-SharedLibrary"><function>SharedLibrary</function></link> builder.
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-SharedLibrary"><function>SharedLibrary</function></link> builder.
The manpage section "Builder Objects" contains
general information on specifying emitters.
</para>
@@ -6024,8 +6040,8 @@ The suffix used for shared library file names.
<term>SHLIBVERSION</term>
<listitem><para>
When this construction variable is defined, a versioned shared library
-is created by the <link linkend="b-SharedLibrary"><function>SharedLibrary</function></link> builder. This activates the
-<link linkend="cv-_SHLIBVERSIONFLAGS"><envar>$_SHLIBVERSIONFLAGS</envar></link> and thus modifies the <link linkend="cv-SHLINKCOM"><envar>$SHLINKCOM</envar></link> as
+is created by the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-SharedLibrary"><function>SharedLibrary</function></link> builder. This activates the
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-_SHLIBVERSIONFLAGS"><envar>$_SHLIBVERSIONFLAGS</envar></link> and thus modifies the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLINKCOM"><envar>$SHLINKCOM</envar></link> as
required, adds the version number to the library name, and creates the symlinks
that are needed. <link linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link> versions should exist as alpha-numeric,
decimal-delimited values as defined by the regular expression "\w+[\.\w+]*".
@@ -6033,6 +6049,16 @@ Example <link linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link> valu
</para>
</listitem>
</varlistentry>
+ <varlistentry id="cv-SHLIBVERSIONFLAGS">
+ <term>SHLIBVERSIONFLAGS</term>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
+Extra flags added to <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLINKCOM"><envar>$SHLINKCOM</envar></link> when building versioned
+<link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="b-SharedLibrary"><function>SharedLibrary</function></link>. These flags are only used when <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link> is
+set.
+</para>
+</listitem>
+ </varlistentry>
<varlistentry id="cv-_SHLIBVERSIONFLAGS">
<term>_SHLIBVERSIONFLAGS</term>
<listitem><para>
@@ -6045,15 +6071,6 @@ and some extra dynamically generated options (such as
</para>
</listitem>
</varlistentry>
- <varlistentry id="cv-SHLIBVERSIONFLAGS">
- <term>SHLIBVERSIONFLAGS</term>
- <listitem><para>
-Extra flags added to <link linkend="cv-SHLINKCOM"><envar>$SHLINKCOM</envar></link> when building versioned
-<link linkend="b-SharedLibrary"><function>SharedLibrary</function></link>. These flags are only used when <link linkend="cv-SHLIBVERSION"><envar>$SHLIBVERSION</envar></link> is
-set.
-</para>
-</listitem>
- </varlistentry>
<varlistentry id="cv-SHLINK">
<term>SHLINK</term>
<listitem><para>
@@ -6484,7 +6501,8 @@ for more information).
</varlistentry>
<varlistentry id="cv-TARGET_ARCH">
<term>TARGET_ARCH</term>
- <listitem><para>
+ <listitem>
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
Sets the target architecture for Visual Studio compiler (i.e. the arch
of the binaries generated by the compiler). If not set, default to
<envar>$HOST_ARCH</envar>, or, if that is unset, to the architecture of the
@@ -6515,7 +6533,8 @@ and <literal>ia64</literal> (Itanium).
For example, if you want to compile 64-bit binaries, you would set
<literal>TARGET_ARCH='x86_64'</literal> in your SCons environment.
</para>
-<para>
+
+<para xmlns="http://www.scons.org/dbxsd/v1.0">
The name of the target hardware architecture for the compiled objects
created by this Environment.
This defaults to the value of HOST_ARCH, and the user can override it.
diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index 01f38d1..a7327ea 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -686,19 +686,32 @@ option except for the way default targets are handled.
When this option is used and no targets are specified on the command line,
all default targets are built, whether or not they are below the current
directory.</para>
-
</listitem>
</varlistentry>
+
<varlistentry>
- <term>--debug=<emphasis>type</emphasis></term>
+ <term>--debug=<replaceable>type</replaceable>[<replaceable>,type</replaceable>...]</term>
<listitem>
<para>Debug the build process.
-<emphasis>type[,type...]</emphasis>
-specifies what type of debugging. Multiple types may be specified,
-separated by commas. The following types are valid:</para>
+<emphasis>type</emphasis>
+specifies the kind of debugging info to emit.
+Multiple types may be specified, separated by commas.
+The following entries show the recognized types:</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>--debug=action-timestamps</term>
+ <listitem>
+<para>Prints additional time profiling information. For
+each command, shows the absolute start and end times.
+This may be useful in debugging parallel builds.
+Implies the <option>--debug=time</option> option.
+</para>
+<para>Since &scons; 3.1.</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term>--debug=count</term>
<listitem>
@@ -893,40 +906,6 @@ should take place in parallel.)
</listitem>
</varlistentry>
-<varlistentry>
- <term>--debug=action_timestamps</term>
- <listitem>
- <para>Prints additional time profiling information:</para>
- <itemizedlist>
- <listitem>
- <para>The time spent executing each individual build command</para>
- </listitem>
- <listitem>
- <para>The total build time (time SCons ran from beginning to end)</para>
- </listitem>
- <listitem>
- <para>The total time spent reading and executing SConscript files</para>
- </listitem>
- <listitem>
- <para>The total time spent SCons itself spend running
-(that is, not counting reading and executing SConscript files)</para>
- </listitem>
- <listitem>
- <para>The total time spent executing all build commands</para>
- </listitem>
- <listitem>
- <para>The elapsed wall-clock time spent executing those build commands</para>
- </listitem>
- <listitem>
- <para>The absolute start and end wall-clock time spent executing those build commands</para>
- </listitem>
- <listitem>
- <para>The time spent processing each file passed to the <emphasis>SConscript()</emphasis> function</para>
- </listitem>
- </itemizedlist>
- </listitem>
-</varlistentry>
-
<varlistentry>
<term>--diskcheck=<emphasis>types</emphasis></term>
<listitem>
diff --git a/doc/user/command-line.xml b/doc/user/command-line.xml
index d129d2e..d8f9fff 100644
--- a/doc/user/command-line.xml
+++ b/doc/user/command-line.xml
@@ -2,7 +2,7 @@
<!DOCTYPE sconsdoc [
<!ENTITY % scons SYSTEM "../scons.mod">
%scons;
-
+
<!ENTITY % builders-mod SYSTEM "../generated/builders.mod">
%builders-mod;
<!ENTITY % functions-mod SYSTEM "../generated/functions.mod">
@@ -89,7 +89,7 @@
all of the command-line variable settings,
the ability to apply command-line variable settings
to construction environments,
- and functions for configuring
+ and functions for configuring
specific types of variables
(Boolean values, path names, etc.)
with automatic validation of the user's specified values.
@@ -599,24 +599,30 @@ foo.in
&SCons; also allows you to define your own
command-line options with the &AddOption; function.
The &AddOption; function takes the same arguments
- as the <function>optparse.add_option</function> function
- from the standard Python library.
+ as the <function>add_option</function> method
+ from the standard Python library module <emphasis>optparse</emphasis>.
<footnote>
<para>
The &AddOption; function is,
in fact, implemented using a subclass
- of the <classname>optparse.OptionParser</classname>.
+ of <classname>optparse.OptionParser</classname>.
</para>
</footnote>
+ </para>
+
+ <para>
Once you have added a custom command-line option
with the &AddOption; function,
the value of the option (if any) is immediately available
using the standard &GetOption; function.
+ <!--
(The value can also be set using &SetOption;,
although that's not very useful in practice
because a default value can be specified in
directly in the &AddOption; call.)
-
+ -->
+ &SetOption; is not currently supported for
+ options added with &AddOption;.
</para>
<para>
@@ -678,6 +684,47 @@ foo.in
<scons_output_command>scons -Q -n --prefix=/tmp/install</scons_output_command>
</scons_output>
+ <note>
+ <para>
+ Option-arguments separated from long options by whitespace,
+ rather than by an <literal>=</literal>, cannot be correctly
+ resolved by <command>scons</command>.
+ While <literal>--input=ARG</literal>
+ is clearly opt followed by arg, for <literal>--input ARG</literal>
+ it is not possible to tell without instructions whether
+ <parameter>ARG</parameter> is an argument belonging to the
+ <parameter>input</parameter> option or a positional argument.
+ <command>scons</command> treats positional arguments as either
+ command-line build options or command-line targets
+ which are made available for use in an &SConscript;
+ (see the immediately following sections for details).
+ Thus, they must be collected before &SConscript; processing
+ takes place. Since &AddOption; calls, which provide
+ the processing instructions to resolve any ambiguity,
+ happen in an &SConscript;,
+ <command>scons</command> does not know in time
+ for options added this way, and unexpected things will happen,
+ such as option-arguments assigned as targets and/or exceptions
+ due to missing option-arguments.
+ </para>
+ <para>
+ As a result, this usage style should be avoided when invoking
+ <command>scons</command>. For single-argument
+ options, use the <literal>--input=ARG</literal> form on the
+ command line. For multiple-argument options
+ (<parameter>nargs</parameter> greater than one),
+ set <parameter>nargs</parameter> to one in
+ &AddOption; calls and either: combine the option-arguments into one word
+ with a separator, and parse the result in your own code
+ (see the built-in <parameter>--debug</parameter> option, which
+ allows specifying multiple arguments as a single comma-separated
+ word, for an example of such usage); or allow the option to
+ be specified multiple times by setting
+ <literal>action='append'</literal>. Both methods can be
+ supported at the same time.
+ </para>
+ </note>
+
</section>
</section>
@@ -1132,12 +1179,12 @@ vars = Variables('custom.py', ARGUMENTS)
</screen>
<para>
-
+
where values in the option file &custom_py; get overwritten
by the ones specified on the command line.
</para>
-
+
</section>
<section>
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:
diff --git a/test/Clang/clang_shared_library.py b/test/Clang/clang_shared_library.py
index 9af3770..83fa4dd 100644
--- a/test/Clang/clang_shared_library.py
+++ b/test/Clang/clang_shared_library.py
@@ -35,7 +35,7 @@ if not test.where_is('clang'):
base = Base()
platform = base['PLATFORM']
-if platform == 'posix':
+if platform in ['posix', 'sunos']:
filename_options = ['foo.os']
libraryname = 'libfoo.so'
elif platform == 'darwin':
diff --git a/test/Clang/clangxx_shared_library.py b/test/Clang/clangxx_shared_library.py
index 6240299..a16be6b 100644
--- a/test/Clang/clangxx_shared_library.py
+++ b/test/Clang/clangxx_shared_library.py
@@ -44,6 +44,9 @@ elif platform == 'darwin':
elif platform == 'win32':
filename_options = ['foo.obj','foo.os']
libraryname = 'foo.dll'
+elif platform == 'sunos':
+ filename_options = ['foo.pic.o']
+ libraryname = 'libfoo.so'
else:
test.fail_test()
diff --git a/test/Command.py b/test/Command.py
index 09a8daa..d8ca86d 100644
--- a/test/Command.py
+++ b/test/Command.py
@@ -21,7 +21,6 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import TestSCons
@@ -43,7 +42,9 @@ test.write('build.py', build_py)
test.write(['expand_chdir_sub', 'subbuild.py'], build_py)
test.write('SConstruct', """
+from __future__ import print_function
import os
+import sys
def buildIt(env, target, source):
with open(str(target[0]), 'w') as f, open(str(source[0]), 'r') as infp:
@@ -62,6 +63,18 @@ def sub(env, target, source):
t.write(s.read())
return 0
+def source_scanner(node, env, path, builder):
+ print("Source scanner node=", node, "builder =", builder,file=sys.stderr)
+ return []
+
+def target_scanner(node, env, path, builder):
+ print("Target scanner node=", node, "builder =", builder,file=sys.stderr)
+ return []
+
+def factory(node,*lst,**kw):
+ print("factory called on:",node,file=sys.stderr)
+ return env.File(node)
+
env = Environment(COPY_THROUGH_TEMP = r'%(_python_)s build.py .tmp $SOURCE' + '\\n' + r'%(_python_)s build.py $TARGET .tmp',
EXPAND = '$COPY_THROUGH_TEMP')
env.Command(target = 'f1.out', source = 'f1.in',
@@ -82,6 +95,19 @@ env.Command(target = 'f7.out', source = 'f7.in',
action = r'%(_python_)s build.py $TARGET $SOURCE')
Command(target = 'f8.out', source = 'f8.in',
action = r'%(_python_)s build.py $TARGET $SOURCE')
+env.Command(target = 'f7s.out', source = 'f7.in',
+ action = r'%(_python_)s build.py $TARGET $SOURCE',
+ target_scanner=Scanner(lambda node, env, path: target_scanner(node, env, path, "w-env")),
+ source_scanner=Scanner(lambda node, env, path: source_scanner(node, env, path, "w-env")))
+Command(target = 'f8s.out', source = 'f8.in',
+ action = r'%(_python_)s build.py $TARGET $SOURCE',
+ target_scanner=Scanner(lambda node, env, path: target_scanner(node, env, path, "wo-env")),
+ source_scanner=Scanner(lambda node, env, path: source_scanner(node, env, path, "wo-env")))
+Command(target = 'f8f.out', source = 'f8.in',
+ action = r'%(_python_)s build.py $TARGET $SOURCE',
+ target_factory=factory,
+ source_factory=factory
+ )
env.Command(target = 'f9.out', source = 'f9.in',
action = r'$EXPAND')
env.Command(target = '${F10}.out', source = '${F10}.in',
@@ -108,7 +134,18 @@ test.write('f9.in', "f9.in\n")
test.write('f10.in', "f10.in\n")
test.write(['expand_chdir_sub', 'f11.in'], "expand_chdir_sub/f11.in\n")
-test.run(arguments = '.')
+test_str = r'''factory called on: f8.in
+factory called on: f8f.out
+Source scanner node= f7.in builder = w-env
+Target scanner node= f7s.out builder = w-env
+Source scanner node= f8.in builder = wo-env
+Target scanner node= f8s.out builder = wo-env
+'''
+
+out = test.run(arguments='.',
+ stderr=test_str,
+ match=TestSCons.match_re_dotall)
+
test.must_match('f1.out', "f1.in\n", mode='r')
test.must_match('f2.out', "f2.in\n", mode='r')
@@ -118,9 +155,12 @@ test.must_match('f5.out', "XYZZY is set\nf5.in\n", mode='r')
test.must_match('f6.out', "f6.in\n", mode='r')
test.must_match('f7.out', "f7.in\n", mode='r')
test.must_match('f8.out', "f8.in\n", mode='r')
+test.must_match('f7s.out', "f7.in\n", mode='r')
+test.must_match('f8s.out', "f8.in\n", mode='r')
test.must_match('f9.out', "f9.in\n", mode='r')
test.must_match('f10.out', "f10.in\n", mode='r')
-test.must_match(['expand_chdir_sub', 'f11.out'], "expand_chdir_sub/f11.in\n", mode='r')
+test.must_match(['expand_chdir_sub', 'f11.out'],
+ "expand_chdir_sub/f11.in\n", mode='r')
test.pass_test()
diff --git a/test/Errors/execute-a-directory.py b/test/Errors/execute-a-directory.py
index 95fa7b6..8b6d13b 100644
--- a/test/Errors/execute-a-directory.py
+++ b/test/Errors/execute-a-directory.py
@@ -65,7 +65,7 @@ scons: \\*\\*\\* \\[%s\\] Error 1
"""
cannot_execute = """\
-(sh: )*.+: cannot execute
+(sh: )*.+: cannot execute( \\[Is a directory\\])?
scons: \\*\\*\\* \\[%s\\] Error %s
"""
@@ -93,10 +93,6 @@ if os.name == 'nt':
konnte_nicht_gefunden_werden % ('f3', 1),
unspecified % 'f3'
]
-elif sys.platform.find('sunos') != -1:
- errs = [
- cannot_execute % ('f3', 1),
- ]
else:
errs = [
cannot_execute % ('f3', 126),
diff --git a/test/Errors/non-executable-file.py b/test/Errors/non-executable-file.py
index 0e00c77..64c75c6 100644
--- a/test/Errors/non-executable-file.py
+++ b/test/Errors/non-executable-file.py
@@ -54,7 +54,7 @@ scons: \\*\\*\\* \\[%s\\] Error 1
"""
cannot_execute = """\
-(sh: )*.+: cannot execute
+(sh: )*.+: cannot execute( \\[Permission denied\\])?
scons: \\*\\*\\* \\[%s\\] Error %s
"""
@@ -88,10 +88,6 @@ if os.name == 'nt':
konnte_nicht_gefunden_werden % ('f1', 1),
unspecified % 'f1'
]
-elif sys.platform.find('sunos') != -1:
- errs = [
- cannot_execute % ('f1', 1),
- ]
else:
errs = [
cannot_execute % ('f1', 126),
diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py
index 468e3e5..64f9b90 100644
--- a/test/LINK/VersionedLib.py
+++ b/test/LINK/VersionedLib.py
@@ -138,37 +138,37 @@ elif 'sunlink' in tool_list:
test_plan = [
{
'libversion' : '2',
- 'files' : [ 'libtest.so', 'libtest.so.2', 'so_test.os' ],
+ 'files' : [ 'libtest.so', 'libtest.so.2', 'test.pic.o' ],
'instfiles' : [ 'libtest.so', 'libtest.so.2' ],
'symlinks' : [ ('libtest.so', 'libtest.so.2') ],
},
{
'libversion' : '2.5',
- 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5', 'so_test.os' ],
+ 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5', 'test.pic.o' ],
'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5' ],
'symlinks' : [ ('libtest.so', 'libtest.so.2.5'), ('libtest.so.2', 'libtest.so.2.5') ],
},
{
'libversion' : '2.5.4',
- 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4', 'so_test.os' ],
+ 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4', 'test.pic.o' ],
'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4' ],
'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4'), ('libtest.so.2', 'libtest.so.2.5.4') ],
},
{
'libversion' : '2.5.4.7.8',
- 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8', 'so_test.os' ],
+ 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8', 'test.pic.o' ],
'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8' ],
'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4.7.8'), ('libtest.so.2', 'libtest.so.2.5.4.7.8') ],
},
{
'libversion' : 'aabf114f',
- 'files' : [ 'libtest.so', 'libtest.so.aabf114f', 'so_test.os' ],
+ 'files' : [ 'libtest.so', 'libtest.so.aabf114f', 'test.pic.o' ],
'instfiles' : [ 'libtest.so', 'libtest.so.aabf114f' ],
'symlinks' : [ ('libtest.so', 'libtest.so.aabf114f') ],
},
{
'libversion' : '2.dfffa11',
- 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11', 'so_test.os' ],
+ 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11', 'test.pic.o' ],
'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11' ],
'symlinks' : [ ('libtest.so', 'libtest.so.2.dfffa11'), ('libtest.so.2', 'libtest.so.2.dfffa11') ],
},
diff --git a/test/SWIG/recursive-includes-cpp.py b/test/SWIG/recursive-includes-cpp.py
index 3999cc3..dcd9d05 100644
--- a/test/SWIG/recursive-includes-cpp.py
+++ b/test/SWIG/recursive-includes-cpp.py
@@ -115,6 +115,8 @@ env.SharedLibrary(
if sys.platform == 'win32':
object_suffix = ".obj"
+elif sys.platform == 'sunos5':
+ object_suffix = ".pic.o"
else:
object_suffix = ".os"
diff --git a/test/option/debug-action-timestamps.py b/test/option/debug-action-timestamps.py
index 0277516..059cfdf 100644
--- a/test/option/debug-action-timestamps.py
+++ b/test/option/debug-action-timestamps.py
@@ -34,13 +34,13 @@ def setup_fixtures():
test.file_fixture('../fixture/SConstruct_test_main.py', 'SConstruct')
def test_help_function():
- # Before anything else, make sure we get valid --debug=action_timestamps results
+ # Before anything else, make sure we get valid --debug=action-timestamps results
# when just running the help option.
- test.run(arguments = "-h --debug=action_timestamps")
+ test.run(arguments = "-h --debug=action-timestamps")
def build():
# Execute build
- test.run(arguments='--debug=action_timestamps')
+ test.run(arguments='--debug=action-timestamps')
build_output = test.stdout()
return build_output
@@ -84,8 +84,8 @@ def test_correctness_of_timestamps(build_output):
debug_time_patterns = [
r'Command execution time: (.*): (\d+\.\d+) seconds',
- r'Command execution start time: (.*): (\d+\.\d+) seconds',
- r'Command execution stop time: (.*): (\d+\.\d+) seconds'
+ r'Command execution start timestamp: (.*): (\d+\.\d+)',
+ r'Command execution end timestamp: (.*): (\d+\.\d+)'
]
test = TestSCons.TestSCons()
diff --git a/testing/framework/TestCommon.py b/testing/framework/TestCommon.py
index ca4a147..8e6cc8e 100644
--- a/testing/framework/TestCommon.py
+++ b/testing/framework/TestCommon.py
@@ -165,8 +165,8 @@ elif sys.platform.find('darwin') != -1:
elif sys.platform.find('sunos') != -1:
exe_suffix = ''
obj_suffix = '.o'
- shobj_suffix = '.o'
- shobj_prefix = 'so_'
+ shobj_suffix = '.pic.o'
+ shobj_prefix = ''
lib_prefix = 'lib'
lib_suffix = '.a'
dll_prefix = 'lib'