Skip to content

Commit bec6354

Browse files
authored
Merge branch 'master' into variables-nosubst
2 parents 265046d + a197ed4 commit bec6354

File tree

9 files changed

+162
-41
lines changed

9 files changed

+162
-41
lines changed

CHANGES.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
8888
- When a variable is added to a Variables object, it can now be flagged
8989
as "don't perform substitution". This allows variables to contain
9090
characters which would otherwise cause expansion. Fixes #4241.
91+
- The test runner now recognizes the unittest module's return code of 5,
92+
which means no tests were run. SCons/Script/MainTests.py currently
93+
has no tests, so this particular error code is expected - should not
94+
cause runtest to give up with an "unknown error code".
95+
- Updated the notes about reproducible builds with SCons and the example.
96+
- The Clone() method now respects the variables argument (fixes #3590)
9197

9298

9399
RELEASE 4.7.0 - Sun, 17 Mar 2024 17:22:20 -0700

README.rst

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,19 @@ notifications and other GitHub events (``#github-update``),
249249
if those are of interest. See the website for more contact information:
250250
https://scons.org/contact.html.
251251

252+
Reproducible Builds
253+
===================
254+
SCons itself is set up to do "reproducible builds"
255+
(see (https://reproducible-builds.org/specs/source-date-epoch/)
256+
if environment variables ``SOURCE_DATE_EPOCH`` is set - that is,
257+
fields in the package which could change each time the package is
258+
constructed are forced to constant values.
259+
260+
To support other projects which wish to do the same, a sample script
261+
is provided which can be placed in a site directory, which imports
262+
``SOURCE_DATE_EPOCH`` and sets it in the execution environment of
263+
every created construction envirionment. There's also an installer
264+
script (POSIX shell only). See packaging/etc/README.txt for more details.
252265

253266
Donations
254267
=========
@@ -258,15 +271,6 @@ software, or hardware) to support continued work on the project. Information
258271
is available at https://www.scons.org/donate.html
259272
or the GitHub Sponsors button on https://github.com/scons/scons.
260273

261-
Reproducible Builds
262-
===================
263-
In order to suppor those users who which to produce reproducible builds
264-
(https://reproducible-builds.org/specs/source-date-epoch/) we're now including
265-
logic to force SCons to propagate SOURCE_DATE_EPOCH from your shell environment for
266-
all SCons builds to support reproducible builds we're now providing an example
267-
site_init.py and a script to install it in your ~/.scons. See packaging/etc/README.txt
268-
for more info
269-
270274
For More Information
271275
====================
272276

RELEASE.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ FIXES
6161
- Improved the conversion of a "foreign" exception from an action
6262
into BuildError by making sure our defaults get applied even in
6363
corner cases. Fixes Issue #4530
64+
- The Clone() method now respects the variables argument (fixes #3590)
6465

6566
IMPROVEMENTS
6667
------------
@@ -85,6 +86,7 @@ DOCUMENTATION
8586
- Restructured API Docs build so main package contents are listed
8687
before contents of package submodules.
8788
- Updated manpage description of Command "builder" and function.
89+
- Updated the notes about reproducible builds with SCons and the example.
8890

8991

9092

@@ -101,6 +103,10 @@ DEVELOPMENT
101103
The repo-wide line-ending is now `lf`, with the exception of a few
102104
Windows-only files using `crlf` instead. Any files not already fitting
103105
this format have been explicitly converted.
106+
- The test runner now recognizes the unittest module's return code of 5,
107+
which means no tests were run. SCons/Script/MainTests.py currently
108+
has no tests, so this particular error code is expected - should not
109+
cause runtest to give up with an "unknown error code".
104110

105111

106112
Thanks to the following contributors listed below for their contributions to this release.

SCons/Environment.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,16 +1568,28 @@ def AppendUnique(self, delete_existing: bool=False, **kw) -> None:
15681568
self._dict[key] = dk + val
15691569
self.scanner_map_delete(kw)
15701570

1571-
def Clone(self, tools=[], toolpath=None, parse_flags = None, **kw):
1571+
def Clone(self, tools=[], toolpath=None, variables=None, parse_flags=None, **kw):
15721572
"""Return a copy of a construction Environment.
15731573
1574-
The copy is like a Python "deep copy"--that is, independent
1575-
copies are made recursively of each objects--except that
1576-
a reference is copied when an object is not deep-copyable
1577-
(like a function). There are no references to any mutable
1578-
objects in the original Environment.
1579-
"""
1574+
The copy is like a Python "deep copy": independent copies are made
1575+
recursively of each object, except that a reference is copied when
1576+
an object is not deep-copyable (like a function). There are no
1577+
references to any mutable objects in the original environment.
1578+
1579+
Unrecognized keyword arguments are taken as construction variable
1580+
assignments.
15801581
1582+
Arguments:
1583+
tools: list of tools to initialize.
1584+
toolpath: list of paths to search for tools.
1585+
variables: a :class:`~SCons.Variables.Variables` object to
1586+
use to populate construction variables from command-line
1587+
variables.
1588+
parse_flags: option strings to parse into construction variables.
1589+
1590+
.. versionadded:: 4.8.0
1591+
The optional *variables* parameter was added.
1592+
"""
15811593
builders = self._dict.get('BUILDERS', {})
15821594

15831595
clone = copy.copy(self)
@@ -1603,6 +1615,8 @@ def Clone(self, tools=[], toolpath=None, parse_flags = None, **kw):
16031615
for key, value in kw.items():
16041616
new[key] = SCons.Subst.scons_subst_once(value, self, key)
16051617
clone.Replace(**new)
1618+
if variables:
1619+
variables.Update(clone)
16061620

16071621
apply_tools(clone, tools, toolpath)
16081622

SCons/Environment.xml

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,11 +1079,12 @@ Clean(docdir, os.path.join(docdir, projectname))
10791079
</arguments>
10801080
<summary>
10811081
<para>
1082-
Returns a separate copy of a construction environment.
1083-
If there are any keyword arguments specified,
1084-
they are added to the returned copy,
1082+
Returns an independent copy of a &consenv;.
1083+
If there are any unrecognized keyword arguments specified,
1084+
they are added as &consvars; in the copy,
10851085
overwriting any existing values
1086-
for the keywords.
1086+
for those keywords.
1087+
See the manpage section "Construction Environments" for more details.
10871088
</para>
10881089

10891090
<para>
@@ -1096,8 +1097,9 @@ env3 = env.Clone(CCFLAGS='-g')
10961097
</example_commands>
10971098

10981099
<para>
1099-
Additionally, a list of tools and a toolpath may be specified, as in
1100-
the &f-link-Environment; constructor:
1100+
A list of <parameter>tools</parameter>
1101+
and a <parameter>toolpath</parameter> may be specified,
1102+
as in the &f-link-Environment; constructor:
11011103
</para>
11021104

11031105
<example_commands>
@@ -1110,7 +1112,7 @@ env4 = env.Clone(tools=['msvc', MyTool])
11101112
<para>
11111113
The
11121114
<parameter>parse_flags</parameter>
1113-
keyword argument is also recognized to allow merging command-line
1115+
keyword argument is also recognized, to allow merging command-line
11141116
style arguments into the appropriate construction
11151117
variables (see &f-link-env-MergeFlags;).
11161118
</para>
@@ -1119,6 +1121,17 @@ variables (see &f-link-env-MergeFlags;).
11191121
# create an environment for compiling programs that use wxWidgets
11201122
wx_env = env.Clone(parse_flags='!wx-config --cflags --cxxflags')
11211123
</example_commands>
1124+
1125+
<para>
1126+
The <parameter>variables</parameter>
1127+
keyword argument is also recognized, to allow (re)initializing
1128+
&consvars; from a <literal>Variables</literal> object.
1129+
</para>
1130+
1131+
<para>
1132+
<emphasis>Changed in version 4.8.0:</emphasis>
1133+
the <parameter>variables</parameter> parameter was added.
1134+
</para>
11221135
</summary>
11231136
</scons_function>
11241137

@@ -1760,7 +1773,7 @@ will print:
17601773
</arguments>
17611774
<summary>
17621775
<para>
1763-
Return a new construction environment
1776+
Return a new &consenv;
17641777
initialized with the specified
17651778
<parameter>key</parameter>=<replaceable>value</replaceable>
17661779
pairs.
@@ -1770,7 +1783,8 @@ The keyword arguments
17701783
<parameter>toolpath</parameter>,
17711784
<parameter>tools</parameter>
17721785
and <parameter>variables</parameter>
1773-
are also specially recognized.
1786+
are specially recognized and do not lead to
1787+
&consvar; creation.
17741788
See the manpage section "Construction Environments" for more details.
17751789
</para>
17761790
</summary>

packaging/etc/README.txt

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
This directory contains a number of scripts/files useful when building/packageing SCons
1+
This directory contains helpers for doing reproducible builds with SCons.
2+
3+
To force SCons to propagate SOURCE_DATE_EPOCH from the shell running SCons,
4+
the reproducible_site_init.py file can be installed (as site_init.py)
5+
in any site directory - either in the project itself, or more globally.
6+
See the manpage for default site directories or how to set your own path:
7+
https://scons.org/doc/production/HTML/scons-man.html#opt-site-dir.
8+
This code will make sure SOURCE_DATE_EPOCH is set in the execution
9+
environment, meaning any external commands run by SCons will have it
10+
in their environment. Any logic in your build system itself will still
11+
need to examine this variable.
12+
13+
The shell script reproducible_install.sh can be used to install the
14+
Python site file in your user site directory ($HOME/.scons/site_scons).
15+
It is careful to not overwrite any existing site_init.py there. This
16+
only works for a POSIX shell.
217

3-
To force SCons to propagate SOURCE_DATE_EPOCH from the shell running SCons we're providing
4-
a script to create a ~/.scons/site_scons/site_init.py.
5-
Note that reproducible_install.sh will NOT overwite an existing ~/.scons/site_scons/site_init.py
618
This supports https://reproducible-builds.org/specs/source-date-epoch/
7-
If you wanted to include this in your build tree you would place in site_scons/site_init.py relative
8-
to your SConstruct.
9-
* reproducible_install.sh
10-
* reproducible_site_init.py
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""
2-
Use this file as your ~/.site_scons/scons_init.py to enable reprodicble builds as described at
2+
Use this file as your site_init.py in a site directory,
3+
to enable reprodicble builds as described at
34
https://reproducible-builds.org/specs/source-date-epoch/
45
"""
56

@@ -8,17 +9,22 @@
89

910
old_init = SCons.Environment.Base.__init__
1011

11-
print("Adding logic to propagate SOURCE_DATE_EPOCH from the shell environment when building with SCons")
12+
print(
13+
"Adding logic to propagate SOURCE_DATE_EPOCH from the shell environment when building with SCons"
14+
)
1215

1316

1417
def new_init(self, **kw):
15-
"""
16-
This logic will add SOURCE_DATE_EPOCH to the execution environment used to run
17-
all the build commands.
18+
"""Replacement Environment initializer.
19+
20+
When this is monkey-patched into :class:`SCons.Environment.Base` it adds
21+
``SOURCE_DATE_EPOCH`` to the execution environment used to run
22+
all external build commands; the original iinitializer is called first.
1823
"""
1924
old_init(self, **kw)
20-
if 'SOURCE_DATE_EPOCH' in os.environ:
21-
self._dict['ENV']['SOURCE_DATE_EPOCH'] = os.environ['SOURCE_DATE_EPOCH']
25+
epoch = os.environ.get("SOURCE_DATE_EPOCH")
26+
if epoch is not None:
27+
self._dict["ENV"]["SOURCE_DATE_EPOCH"] = epoch
2228

2329

2430
SCons.Environment.Base.__init__ = new_init

runtest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ class SystemExecutor(RuntestBase):
417417
def execute(self, env):
418418
self.stderr, self.stdout, s = spawn_it(self.command_args, env)
419419
self.status = s
420-
if s < 0 or s > 2:
420+
if s < 0 or s > 2 and s != 5:
421421
sys.stdout.write("Unexpected exit status %d\n" % s)
422422

423423

test/Clone-Variables.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env python
2+
#
3+
# MIT License
4+
#
5+
# Copyright The SCons Foundation
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining
8+
# a copy of this software and associated documentation files (the
9+
# "Software"), to deal in the Software without restriction, including
10+
# without limitation the rights to use, copy, modify, merge, publish,
11+
# distribute, sublicense, and/or sell copies of the Software, and to
12+
# permit persons to whom the Software is furnished to do so, subject to
13+
# the following conditions:
14+
#
15+
# The above copyright notice and this permission notice shall be included
16+
# in all copies or substantial portions of the Software.
17+
#
18+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19+
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25+
26+
27+
"""
28+
Verify that Clone() respects the variables kwarg.
29+
30+
"""
31+
32+
import TestSCons
33+
34+
test = TestSCons.TestSCons()
35+
36+
test.write('SConstruct', """\
37+
vars = Variables()
38+
vars.Add(BoolVariable('MYTEST', 'help', default=False))
39+
40+
_ = DefaultEnvironment(tools=[])
41+
env = Environment(variables=vars, tools=[])
42+
print(f"MYTEST={env.Dictionary('MYTEST')}")
43+
env.Replace(MYTEST=True)
44+
print(f"MYTEST={env.Dictionary('MYTEST')}")
45+
env1 = env.Clone(variables=vars)
46+
print(f"MYTEST={env1.Dictionary('MYTEST')}")
47+
""")
48+
49+
expect = """\
50+
MYTEST=False
51+
MYTEST=True
52+
MYTEST=False
53+
"""
54+
55+
test.run(arguments = '-q -Q', stdout=expect)
56+
57+
test.pass_test()
58+
59+
# Local Variables:
60+
# tab-width:4
61+
# indent-tabs-mode:nil
62+
# End:
63+
# vim: set expandtab tabstop=4 shiftwidth=4:

0 commit comments

Comments
 (0)