updated scons to 0.97.0d20071212
This commit is contained in:
parent
a3652c6e66
commit
2357582cbb
173 changed files with 9806 additions and 4123 deletions
161
scons/scons
161
scons/scons
|
@ -1,161 +0,0 @@
|
||||||
#! /usr/bin/env python
|
|
||||||
#
|
|
||||||
# SCons - a Software Constructor
|
|
||||||
#
|
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
# a copy of this software and associated documentation files (the
|
|
||||||
# "Software"), to deal in the Software without restriction, including
|
|
||||||
# without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
# permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
# the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included
|
|
||||||
# in all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
||||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
||||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
# 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__ = "/home/scons/scons/branch.0/baseline/src/script/scons.py 0.97.D001 2007/05/17 11:35:19 knight"
|
|
||||||
|
|
||||||
__version__ = "0.97"
|
|
||||||
|
|
||||||
__build__ = "D001"
|
|
||||||
|
|
||||||
__buildsys__ = "roxbury"
|
|
||||||
|
|
||||||
__date__ = "2007/05/17 11:35:19"
|
|
||||||
|
|
||||||
__developer__ = "knight"
|
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import sys
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# BEGIN STANDARD SCons SCRIPT HEADER
|
|
||||||
#
|
|
||||||
# This is the cut-and-paste logic so that a self-contained script can
|
|
||||||
# interoperate correctly with different SCons versions and installation
|
|
||||||
# locations for the engine. If you modify anything in this section, you
|
|
||||||
# should also change other scripts that use this same header.
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Strip the script directory from sys.path() so on case-insensitive
|
|
||||||
# (WIN32) systems Python doesn't think that the "scons" script is the
|
|
||||||
# "SCons" package. Replace it with our own library directories
|
|
||||||
# (version-specific first, in case they installed by hand there,
|
|
||||||
# followed by generic) so we pick up the right version of the build
|
|
||||||
# engine modules if they're in either directory.
|
|
||||||
|
|
||||||
script_dir = sys.path[0]
|
|
||||||
|
|
||||||
if script_dir in sys.path:
|
|
||||||
sys.path.remove(script_dir)
|
|
||||||
|
|
||||||
libs = []
|
|
||||||
|
|
||||||
if os.environ.has_key("SCONS_LIB_DIR"):
|
|
||||||
libs.append(os.environ["SCONS_LIB_DIR"])
|
|
||||||
|
|
||||||
local = 'scons-local-' + __version__
|
|
||||||
if script_dir:
|
|
||||||
local = os.path.join(script_dir, local)
|
|
||||||
libs.append(os.path.abspath(local))
|
|
||||||
|
|
||||||
scons_version = 'scons-%s' % __version__
|
|
||||||
|
|
||||||
prefs = []
|
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
# sys.prefix is (likely) C:\Python*;
|
|
||||||
# check only C:\Python*.
|
|
||||||
prefs.append(sys.prefix)
|
|
||||||
prefs.append(os.path.join(sys.prefix, 'Lib', 'site-packages'))
|
|
||||||
else:
|
|
||||||
# On other (POSIX) platforms, things are more complicated due to
|
|
||||||
# the variety of path names and library locations. Try to be smart
|
|
||||||
# about it.
|
|
||||||
if script_dir == 'bin':
|
|
||||||
# script_dir is `pwd`/bin;
|
|
||||||
# check `pwd`/lib/scons*.
|
|
||||||
prefs.append(os.getcwd())
|
|
||||||
else:
|
|
||||||
if script_dir == '.' or script_dir == '':
|
|
||||||
script_dir = os.getcwd()
|
|
||||||
head, tail = os.path.split(script_dir)
|
|
||||||
if tail == "bin":
|
|
||||||
# script_dir is /foo/bin;
|
|
||||||
# check /foo/lib/scons*.
|
|
||||||
prefs.append(head)
|
|
||||||
|
|
||||||
head, tail = os.path.split(sys.prefix)
|
|
||||||
if tail == "usr":
|
|
||||||
# sys.prefix is /foo/usr;
|
|
||||||
# check /foo/usr/lib/scons* first,
|
|
||||||
# then /foo/usr/local/lib/scons*.
|
|
||||||
prefs.append(sys.prefix)
|
|
||||||
prefs.append(os.path.join(sys.prefix, "local"))
|
|
||||||
elif tail == "local":
|
|
||||||
h, t = os.path.split(head)
|
|
||||||
if t == "usr":
|
|
||||||
# sys.prefix is /foo/usr/local;
|
|
||||||
# check /foo/usr/local/lib/scons* first,
|
|
||||||
# then /foo/usr/lib/scons*.
|
|
||||||
prefs.append(sys.prefix)
|
|
||||||
prefs.append(head)
|
|
||||||
else:
|
|
||||||
# sys.prefix is /foo/local;
|
|
||||||
# check only /foo/local/lib/scons*.
|
|
||||||
prefs.append(sys.prefix)
|
|
||||||
else:
|
|
||||||
# sys.prefix is /foo (ends in neither /usr or /local);
|
|
||||||
# check only /foo/lib/scons*.
|
|
||||||
prefs.append(sys.prefix)
|
|
||||||
|
|
||||||
temp = map(lambda x: os.path.join(x, 'lib'), prefs)
|
|
||||||
temp.extend(map(lambda x: os.path.join(x,
|
|
||||||
'lib',
|
|
||||||
'python' + sys.version[:3],
|
|
||||||
'site-packages'),
|
|
||||||
prefs))
|
|
||||||
prefs = temp
|
|
||||||
|
|
||||||
# Add the parent directory of the current python's library to the
|
|
||||||
# preferences. On SuSE-91/AMD64, for example, this is /usr/lib64,
|
|
||||||
# not /usr/lib.
|
|
||||||
try:
|
|
||||||
libpath = os.__file__
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
while libpath:
|
|
||||||
libpath, tail = os.path.split(libpath)
|
|
||||||
if tail[:6] == "python":
|
|
||||||
break
|
|
||||||
if libpath:
|
|
||||||
# Python library is in /usr/libfoo/python*;
|
|
||||||
# check /usr/libfoo/scons*.
|
|
||||||
prefs.append(libpath)
|
|
||||||
|
|
||||||
# Look first for 'scons-__version__' in all of our preference libs,
|
|
||||||
# then for 'scons'.
|
|
||||||
libs.extend(map(lambda x: os.path.join(x, scons_version), prefs))
|
|
||||||
libs.extend(map(lambda x: os.path.join(x, 'scons'), prefs))
|
|
||||||
|
|
||||||
sys.path = libs + sys.path
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# END STANDARD SCons SCRIPT HEADER
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
import SCons.Script
|
|
||||||
SCons.Script.main()
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
Copyright and license for SCons - a software construction tool
|
||||||
|
|
||||||
|
This copyright and license do not apply to any other software
|
||||||
|
with which this software may have been included.
|
||||||
|
|
||||||
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
|
|
@ -1,28 +1,42 @@
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
# src/README.txt 0.97.D001 2007/05/17 11:35:19 knight
|
|
||||||
|
|
||||||
|
|
||||||
SCons - a software construction tool
|
SCons - a software construction tool
|
||||||
|
|
||||||
Version 0.97
|
This is the scons-README file for a version of SCons packaged for local
|
||||||
|
execution--that is, execution out of a specific local directory, without
|
||||||
|
having to install SCons as a system-wide utility.
|
||||||
|
|
||||||
|
You are likely reading this file in one of the following two situations:
|
||||||
|
|
||||||
This is a beta release of SCons, a tool for building software (and other
|
1) You have unpacked an scons-local-{version} package and are
|
||||||
files). SCons is implemented in Python, and its "configuration files"
|
examining the contents.
|
||||||
are actually Python scripts, allowing you to use the full power of a
|
|
||||||
real scripting language to solve build problems. You do not, however,
|
|
||||||
need to know Python to use SCons effectively.
|
|
||||||
|
|
||||||
See the RELEASE.txt file for notes about this specific release,
|
In this case, you are presumably interested in using this
|
||||||
including known problems. See the CHANGES.txt file for a list of
|
package to include a local copy of SCons with some other
|
||||||
changes since the previous release.
|
software that you package, so that you can use SCons to build
|
||||||
|
your software without forcing all of your users to have it fully
|
||||||
|
installed. Instructions for this can be found below.
|
||||||
|
|
||||||
|
If you are not looking to use SCons in this way, then please
|
||||||
|
use either the scons-{version} package to install SCons on your
|
||||||
|
system, or the scons-src-{version} package if you want the full
|
||||||
|
source to SCons, including its packaging code and underlying
|
||||||
|
tests and testing infrastructure.
|
||||||
|
|
||||||
|
2) This file was included in some other software package so that
|
||||||
|
the package could be built using SCons.
|
||||||
|
|
||||||
|
In this case, follow the instructions provided with the
|
||||||
|
rest of the software package for how to use SCons to build
|
||||||
|
and/or install the software. The file containing build and
|
||||||
|
installation instructions will typically be named README or
|
||||||
|
INSTALL.
|
||||||
|
|
||||||
LATEST VERSION
|
LATEST VERSION
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Before going further, you can check that this package you have is
|
Before going further, you can check for the latest version of the
|
||||||
the latest version by checking the SCons download page at:
|
scons-local package, or any SCons package, at the SCons download page:
|
||||||
|
|
||||||
http://www.scons.org/download.html
|
http://www.scons.org/download.html
|
||||||
|
|
||||||
|
@ -31,149 +45,93 @@ EXECUTION REQUIREMENTS
|
||||||
======================
|
======================
|
||||||
|
|
||||||
Running SCons requires Python version 1.5.2 or later. There should be
|
Running SCons requires Python version 1.5.2 or later. There should be
|
||||||
no other dependencies or requirements to run SCons. (There is, however,
|
no other dependencies or requirements to run SCons.
|
||||||
an additional requirement to *install* SCons from this particular
|
|
||||||
package; see the next section.)
|
|
||||||
|
|
||||||
By default, SCons knows how to search for available programming tools
|
The default SCons configuration assumes use of the Microsoft Visual C++
|
||||||
on various systems--see the SCons man page for details. You may,
|
compiler suite on WIN32 systems, and assumes a C compiler named 'cc',
|
||||||
of course, override the default SCons choices made by appropriate
|
a C++ compiler named 'c++', and a Fortran compiler named 'g77' (such
|
||||||
|
as found in the GNU C compiler suite) on any other type of system.
|
||||||
|
You may, of course, override these default values by appropriate
|
||||||
configuration of Environment construction variables.
|
configuration of Environment construction variables.
|
||||||
|
|
||||||
|
|
||||||
INSTALLATION REQUIREMENTS
|
|
||||||
=========================
|
|
||||||
|
|
||||||
Installing SCons from this package requires the Python distutils
|
|
||||||
package. The distutils package was not shipped as a standard part of
|
|
||||||
Python until Python version 1.6, so if your system is running Python
|
|
||||||
1.5.2, you may not have distutils installed. If you are running
|
|
||||||
Python version 1.6 or later, you should be fine.
|
|
||||||
|
|
||||||
NOTE TO RED HAT USERS: Red Hat shipped Python 1.5.2 as the default all
|
|
||||||
the way up to Red Hat Linux 7.3, so you probably do *not* have distutils
|
|
||||||
installed, unless you have already done so manually or are running Red
|
|
||||||
Hat 8.0 or later.
|
|
||||||
|
|
||||||
In this case, your options are:
|
|
||||||
|
|
||||||
-- (Recommended.) Install from a pre-packaged SCons package that
|
|
||||||
does not require distutils:
|
|
||||||
|
|
||||||
Red Hat Linux scons-0.97-1.noarch.rpm
|
|
||||||
|
|
||||||
Debian GNU/Linux scons_0.97-1_all.deb
|
|
||||||
(or use apt-get)
|
|
||||||
|
|
||||||
Windows scons-0.97.win32.exe
|
|
||||||
|
|
||||||
-- (Optional.) Download the latest distutils package from the
|
|
||||||
following URL:
|
|
||||||
|
|
||||||
http://www.python.org/sigs/distutils-sig/download.html
|
|
||||||
|
|
||||||
Install the distutils according to the instructions on the page.
|
|
||||||
You can then proceed to the next section to install SCons from
|
|
||||||
this package.
|
|
||||||
|
|
||||||
|
|
||||||
INSTALLATION
|
INSTALLATION
|
||||||
============
|
============
|
||||||
|
|
||||||
Assuming your system satisfies the installation requirements in the
|
Installation of this package should be as simple as unpacking the
|
||||||
previous section, install SCons from this package simply by running the
|
archive (either .tar.gz or .zip) in any directory (top-level or a
|
||||||
provided Python-standard setup script as follows:
|
subdirectory) within the software package with which you want to ship
|
||||||
|
SCons.
|
||||||
|
|
||||||
# python setup.py install
|
Once you have installed this package, you should write an SConstruct
|
||||||
|
file at the top level of your source tree to build your software as you
|
||||||
|
see fit.
|
||||||
|
|
||||||
By default, the above command will do the following:
|
Then modify the build/install instructions for your package to instruct
|
||||||
|
your users to execute SCons as follows (if you installed this package in
|
||||||
|
your top-level directory):
|
||||||
|
|
||||||
-- Install the version-numbered "scons-0.97" and "sconsign-0.97"
|
$ python scons.py
|
||||||
scripts in the default system script directory (/usr/bin or
|
|
||||||
C:\Python*\Scripts, for example). This can be disabled by
|
|
||||||
specifying the "--no-version-script" option on the command
|
|
||||||
line.
|
|
||||||
|
|
||||||
-- Install scripts named "scons" and "sconsign" scripts in the
|
Or (if, for example, you installed this package in a subdirectory named
|
||||||
default system script directory (/usr/bin or C:\Python*\Scripts,
|
"scons"):
|
||||||
for example). This can be disabled by specifying the
|
|
||||||
"--no-scons-script" option on the command line, which is useful
|
|
||||||
if you want to install and experiment with a new version before
|
|
||||||
making it the default on your system.
|
|
||||||
|
|
||||||
On UNIX or Linux systems, you can have the "scons" and "sconsign"
|
$ python scons/scons.py
|
||||||
scripts be hard links or symbolic links to the "scons-0.97" and
|
|
||||||
"sconsign-0.97" scripts by specifying the "--hardlink-scons"
|
|
||||||
or "--symlink-scons" options on the command line.
|
|
||||||
|
|
||||||
-- Install "scons-0.97.bat" and "scons.bat" wrapper scripts in the
|
That should be all you have to do. (If it isn't that simple, please let
|
||||||
Python prefix directory on Windows (C:\Python*, for example).
|
us know!)
|
||||||
This can be disabled by specifying the "--no-install-bat" option
|
|
||||||
on the command line.
|
|
||||||
|
|
||||||
On UNIX or Linux systems, the "--install-bat" option may be
|
|
||||||
specified to have "scons-0.97.bat" and "scons.bat" files
|
|
||||||
installed in the default system script directory, which is useful
|
|
||||||
if you want to install SCons in a shared file system directory
|
|
||||||
that can be used to execute SCons from both UNIX/Linux and
|
|
||||||
Windows systems.
|
|
||||||
|
|
||||||
-- Install the SCons build engine (a Python module) in an
|
CONTENTS OF THIS PACKAGE
|
||||||
appropriate version-numbered SCons library directory
|
========================
|
||||||
(/usr/lib/scons-0.97 or C:\Python*\scons-0.97, for example).
|
|
||||||
See below for more options related to installing the build
|
|
||||||
engine library.
|
|
||||||
|
|
||||||
-- Install the troff-format man pages in an appropriate directory
|
This scons-local package consists of the following:
|
||||||
on UNIX or Linux systems (/usr/share/man/man1 or /usr/man/man1,
|
|
||||||
for example). This can be disabled by specifying the
|
|
||||||
"--no-install-man" option on the command line. The man pages
|
|
||||||
can be installed on Windows systems by specifying the
|
|
||||||
"--install-man" option on the command line.
|
|
||||||
|
|
||||||
Note that, by default, SCons does not install its build engine library
|
scons-LICENSE
|
||||||
in the standard Python library directories. If you want to be able to
|
A copy of the copyright and terms under which SCons is
|
||||||
use the SCons library modules (the build engine) in other Python
|
distributed (the Open Source Initiative-approved MIT license).
|
||||||
scripts, specify the "--standard-lib" option on the command line, as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
# python setup.py install --standard-lib
|
A disclaimer has been added to the beginning to make clear that
|
||||||
|
this license applies only to SCons, and not to any separate
|
||||||
|
software you've written with which you're planning to package
|
||||||
|
SCons.
|
||||||
|
|
||||||
This will install the build engine in the standard Python library
|
scons-README
|
||||||
directory (/usr/lib/python*/site-packages or
|
What you're looking at right now.
|
||||||
C:\Python*\Lib\site-packages).
|
|
||||||
|
|
||||||
Alternatively, you can have SCons install its build engine library in a
|
scons-local-{version}/
|
||||||
hard-coded standalone library directory, instead of the default
|
The SCons build engine. This is structured as a Python
|
||||||
version-numbered directory, by specifying the "--standalone-lib" option
|
library.
|
||||||
on the command line, as follows:
|
|
||||||
|
|
||||||
# python setup.py install --standalone-lib
|
scons.py
|
||||||
|
The SCons script itself. The script sets up the Python
|
||||||
This is usually not recommended, however.
|
sys.path variable to use the build engine found in the
|
||||||
|
scons-local-{version}/ directory in preference to any other
|
||||||
Note that, to install SCons in any of the above system directories,
|
SCons build engine installed on your system.
|
||||||
you should have system installation privileges (that is, "root" or
|
|
||||||
"Administrator") when running the setup.py script. If you don't have
|
|
||||||
system installation privileges, you can use the --prefix option to
|
|
||||||
specify an alternate installation location, such as your home directory:
|
|
||||||
|
|
||||||
$ python setup.py install --prefix=$HOME
|
|
||||||
|
|
||||||
This will install SCons in the appropriate locations relative to
|
|
||||||
$HOME--that is, the scons script itself $HOME/bin and the associated
|
|
||||||
library in $HOME/lib/scons, for example.
|
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION
|
DOCUMENTATION
|
||||||
=============
|
=============
|
||||||
|
|
||||||
See the RELEASE.txt file for notes about this specific release,
|
Because this package is intended to be included with other software by
|
||||||
including known problems. See the CHANGES.txt file for a list of
|
experienced users, we have not included any SCons documentation in this
|
||||||
changes since the previous release.
|
package (other than this scons-README file you're reading right now).
|
||||||
|
|
||||||
The scons.1 man page is included in this package, and contains a section
|
If, however, you need documentation about SCons, then consult any of the
|
||||||
of small examples for getting started using SCons.
|
following from the corresponding scons-{version} or scons-src-{version}
|
||||||
|
package:
|
||||||
|
|
||||||
|
The RELEASE.txt file (src/RELEASE.txt file in the
|
||||||
|
scons-src-{version} package), which contains notes about this
|
||||||
|
specific release, including known problems.
|
||||||
|
|
||||||
|
The CHANGES.txt file (src/CHANGES.txt file in the
|
||||||
|
scons-src-{version} package), which contains a list of changes
|
||||||
|
since the previous release.
|
||||||
|
|
||||||
|
The scons.1 man page (doc/man/scons.1 in the scons-src-{version}
|
||||||
|
package), which contains a section of small examples for getting
|
||||||
|
started using SCons.
|
||||||
|
|
||||||
Additional documentation for SCons is available at:
|
Additional documentation for SCons is available at:
|
||||||
|
|
||||||
|
@ -184,8 +142,8 @@ LICENSING
|
||||||
=========
|
=========
|
||||||
|
|
||||||
SCons is distributed under the MIT license, a full copy of which is
|
SCons is distributed under the MIT license, a full copy of which is
|
||||||
available in the LICENSE.txt file. The MIT license is an approved Open
|
available in the scons-LICENSE file in this package. The MIT license is
|
||||||
Source license, which means:
|
an approved Open Source license, which means:
|
||||||
|
|
||||||
This software is OSI Certified Open Source Software. OSI
|
This software is OSI Certified Open Source Software. OSI
|
||||||
Certified is a certification mark of the Open Source Initiative.
|
Certified is a certification mark of the Open Source Initiative.
|
||||||
|
@ -199,51 +157,27 @@ available at:
|
||||||
REPORTING BUGS
|
REPORTING BUGS
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Please report bugs by following the detailed instructions on our Bug
|
You can report bugs either by following the "Tracker - Bugs" link
|
||||||
Submission page:
|
on the SCons project page:
|
||||||
|
|
||||||
http://scons.tigris.org/bug-submission.html
|
http://sourceforge.net/projects/scons/
|
||||||
|
|
||||||
You can also send mail to the SCons developers' mailing list:
|
or by sending mail to the SCons developers mailing list:
|
||||||
|
|
||||||
dev@scons.tigris.org
|
scons-devel@lists.sourceforge.net
|
||||||
|
|
||||||
But even if you send email to the mailing list please make sure that you
|
|
||||||
ALSO submit a bug report to the project page bug tracker, because bug
|
|
||||||
reports in email often get overlooked in the general flood of messages.
|
|
||||||
|
|
||||||
|
|
||||||
MAILING LISTS
|
MAILING LISTS
|
||||||
=============
|
=============
|
||||||
|
|
||||||
An active mailing list for users of SCons is available. You may send
|
A mailing list for users of SCons is available. You may send questions
|
||||||
questions or comments to the list at:
|
or comments to the list at:
|
||||||
|
|
||||||
users@scons.tigris.org
|
scons-users@lists.sourceforge.net
|
||||||
|
|
||||||
You may subscribe to the mailing list by sending email to:
|
You may subscribe to the scons-users mailing list at:
|
||||||
|
|
||||||
users-subscribe@scons.tigris.org
|
http://lists.sourceforge.net/lists/listinfo/scons-users
|
||||||
|
|
||||||
There is also a low-volume mailing list available for announcements
|
|
||||||
about SCons. Subscribe by sending email to:
|
|
||||||
|
|
||||||
announce-subscribe@scons.tigris.org
|
|
||||||
|
|
||||||
There are other mailing lists available for SCons developers, for
|
|
||||||
notification of SCons code changes, and for notification of updated
|
|
||||||
bug reports and project documents. Please see our mailing lists page
|
|
||||||
for details.
|
|
||||||
|
|
||||||
|
|
||||||
DONATIONS
|
|
||||||
=========
|
|
||||||
|
|
||||||
If you find SCons helpful, please consider making a donation (of cash,
|
|
||||||
software, or hardware) to support continued work on the project.
|
|
||||||
Information is available at:
|
|
||||||
|
|
||||||
http://www.scons.org/donate.html
|
|
||||||
|
|
||||||
|
|
||||||
FOR MORE INFORMATION
|
FOR MORE INFORMATION
|
||||||
|
@ -265,9 +199,6 @@ With plenty of help from the SCons Development team:
|
||||||
Chad Austin
|
Chad Austin
|
||||||
Charles Crain
|
Charles Crain
|
||||||
Steve Leblanc
|
Steve Leblanc
|
||||||
Greg Noel
|
|
||||||
Gary Oberbrunner
|
|
||||||
Anthony Roach
|
Anthony Roach
|
||||||
Greg Spencer
|
Terrel Shumway
|
||||||
Christoph Wiedemann
|
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@ other modules:
|
||||||
|
|
||||||
get_contents()
|
get_contents()
|
||||||
Fetches the "contents" of an Action for signature calculation.
|
Fetches the "contents" of an Action for signature calculation.
|
||||||
This is what the Sig/*.py subsystem uses to decide if a target
|
This is what gets MD5 checksumm'ed to decide if a target needs
|
||||||
needs to be rebuilt because its action changed.
|
to be rebuilt because its action changed.
|
||||||
|
|
||||||
genstring()
|
genstring()
|
||||||
Returns a string representation of the Action *without*
|
Returns a string representation of the Action *without*
|
||||||
|
@ -95,7 +95,7 @@ way for wrapping up the functions.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Action.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Action.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import dis
|
import dis
|
||||||
import os
|
import os
|
||||||
|
@ -287,6 +287,7 @@ class _ActionAction(ActionBase):
|
||||||
target = [target]
|
target = [target]
|
||||||
if not SCons.Util.is_List(source):
|
if not SCons.Util.is_List(source):
|
||||||
source = [source]
|
source = [source]
|
||||||
|
|
||||||
if exitstatfunc is _null: exitstatfunc = self.exitstatfunc
|
if exitstatfunc is _null: exitstatfunc = self.exitstatfunc
|
||||||
if presub is _null:
|
if presub is _null:
|
||||||
presub = self.presub
|
presub = self.presub
|
||||||
|
@ -329,12 +330,20 @@ class _ActionAction(ActionBase):
|
||||||
os.chdir(chdir)
|
os.chdir(chdir)
|
||||||
try:
|
try:
|
||||||
stat = self.execute(target, source, env)
|
stat = self.execute(target, source, env)
|
||||||
stat = exitstatfunc(stat)
|
if isinstance(stat, SCons.Errors.BuildError):
|
||||||
|
s = exitstatfunc(stat.status)
|
||||||
|
if s:
|
||||||
|
stat.status = s
|
||||||
|
else:
|
||||||
|
stat = s
|
||||||
|
else:
|
||||||
|
stat = exitstatfunc(stat)
|
||||||
finally:
|
finally:
|
||||||
if save_cwd:
|
if save_cwd:
|
||||||
os.chdir(save_cwd)
|
os.chdir(save_cwd)
|
||||||
if s and save_cwd:
|
if s and save_cwd:
|
||||||
print_func('os.chdir(%s)' % repr(save_cwd), target, source, env)
|
print_func('os.chdir(%s)' % repr(save_cwd), target, source, env)
|
||||||
|
|
||||||
return stat
|
return stat
|
||||||
|
|
||||||
|
|
||||||
|
@ -476,7 +485,11 @@ class CommandAction(_ActionAction):
|
||||||
cmd_line = escape_list(cmd_line, escape)
|
cmd_line = escape_list(cmd_line, escape)
|
||||||
result = spawn(shell, escape, cmd_line[0], cmd_line, ENV)
|
result = spawn(shell, escape, cmd_line[0], cmd_line, ENV)
|
||||||
if not ignore and result:
|
if not ignore and result:
|
||||||
return result
|
msg = "Error %s" % result
|
||||||
|
return SCons.Errors.BuildError(errstr=msg,
|
||||||
|
status=result,
|
||||||
|
action=self,
|
||||||
|
command=cmd_line)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def get_contents(self, target, source, env):
|
def get_contents(self, target, source, env):
|
||||||
|
@ -493,6 +506,22 @@ class CommandAction(_ActionAction):
|
||||||
cmd = str(cmd)
|
cmd = str(cmd)
|
||||||
return env.subst_target_source(cmd, SUBST_SIG, target, source)
|
return env.subst_target_source(cmd, SUBST_SIG, target, source)
|
||||||
|
|
||||||
|
def get_implicit_deps(self, target, source, env):
|
||||||
|
icd = env.get('IMPLICIT_COMMAND_DEPENDENCIES', True)
|
||||||
|
if SCons.Util.is_String(icd) and icd[:1] == '$':
|
||||||
|
icd = env.subst(icd)
|
||||||
|
if not icd or icd in ('0', 'None'):
|
||||||
|
return []
|
||||||
|
from SCons.Subst import SUBST_SIG
|
||||||
|
cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, target, source)
|
||||||
|
res = []
|
||||||
|
for cmd_line in cmd_list:
|
||||||
|
if cmd_line:
|
||||||
|
d = env.WhereIs(str(cmd_line[0]))
|
||||||
|
if d:
|
||||||
|
res.append(env.fs.File(d))
|
||||||
|
return res
|
||||||
|
|
||||||
class CommandGeneratorAction(ActionBase):
|
class CommandGeneratorAction(ActionBase):
|
||||||
"""Class for command-generator actions."""
|
"""Class for command-generator actions."""
|
||||||
def __init__(self, generator, *args, **kw):
|
def __init__(self, generator, *args, **kw):
|
||||||
|
@ -515,9 +544,11 @@ class CommandGeneratorAction(ActionBase):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
try:
|
try:
|
||||||
env = self.presub_env or {}
|
env = self.presub_env
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
env = {}
|
env = None
|
||||||
|
if env is None:
|
||||||
|
env = SCons.Defaults.DefaultEnvironment()
|
||||||
act = self._generate([], [], env, 1)
|
act = self._generate([], [], env, 1)
|
||||||
return str(act)
|
return str(act)
|
||||||
|
|
||||||
|
@ -538,6 +569,9 @@ class CommandGeneratorAction(ActionBase):
|
||||||
"""
|
"""
|
||||||
return self._generate(target, source, env, 1).get_contents(target, source, env)
|
return self._generate(target, source, env, 1).get_contents(target, source, env)
|
||||||
|
|
||||||
|
def get_implicit_deps(self, target, source, env):
|
||||||
|
return self._generate(target, source, env, 1).get_implicit_deps(target, source, env)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# A LazyAction is a kind of hybrid generator and command action for
|
# A LazyAction is a kind of hybrid generator and command action for
|
||||||
|
@ -666,9 +700,19 @@ class FunctionAction(_ActionAction):
|
||||||
# target file will appear).
|
# target file will appear).
|
||||||
try: filename = e.filename
|
try: filename = e.filename
|
||||||
except AttributeError: filename = None
|
except AttributeError: filename = None
|
||||||
raise SCons.Errors.BuildError(node=target,
|
result = SCons.Errors.BuildError(node=target,
|
||||||
errstr=e.strerror,
|
errstr=e.strerror,
|
||||||
filename=filename)
|
status=1,
|
||||||
|
filename=filename,
|
||||||
|
action=self,
|
||||||
|
command=self.strfunction(target, source, env))
|
||||||
|
else:
|
||||||
|
if result:
|
||||||
|
msg = "Error %s" % result
|
||||||
|
result = SCons.Errors.BuildError(errstr=msg,
|
||||||
|
status=result,
|
||||||
|
action=self,
|
||||||
|
command=self.strfunction(target, source, env))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_contents(self, target, source, env):
|
def get_contents(self, target, source, env):
|
||||||
|
@ -713,6 +757,9 @@ class FunctionAction(_ActionAction):
|
||||||
return contents + env.subst(string.join(map(lambda v: '${'+v+'}',
|
return contents + env.subst(string.join(map(lambda v: '${'+v+'}',
|
||||||
self.varlist)))
|
self.varlist)))
|
||||||
|
|
||||||
|
def get_implicit_deps(self, target, source, env):
|
||||||
|
return []
|
||||||
|
|
||||||
class ListAction(ActionBase):
|
class ListAction(ActionBase):
|
||||||
"""Class for lists of other actions."""
|
"""Class for lists of other actions."""
|
||||||
def __init__(self, list):
|
def __init__(self, list):
|
||||||
|
@ -756,6 +803,12 @@ class ListAction(ActionBase):
|
||||||
return stat
|
return stat
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def get_implicit_deps(self, target, source, env):
|
||||||
|
result = []
|
||||||
|
for act in self.list:
|
||||||
|
result.extend(act.get_implicit_deps(target, source, env))
|
||||||
|
return result
|
||||||
|
|
||||||
class ActionCaller:
|
class ActionCaller:
|
||||||
"""A class for delaying calling an Action function with specific
|
"""A class for delaying calling an Action function with specific
|
||||||
(positional and keyword) arguments until the Action is actually
|
(positional and keyword) arguments until the Action is actually
|
||||||
|
@ -790,8 +843,9 @@ class ActionCaller:
|
||||||
# was called by using this hard-coded value as a special return.
|
# was called by using this hard-coded value as a special return.
|
||||||
if s == '$__env__':
|
if s == '$__env__':
|
||||||
return env
|
return env
|
||||||
else:
|
elif SCons.Util.is_String(s):
|
||||||
return env.subst(s, 0, target, source)
|
return env.subst(s, 0, target, source)
|
||||||
|
return self.parent.convert(s)
|
||||||
def subst_args(self, target, source, env):
|
def subst_args(self, target, source, env):
|
||||||
return map(lambda x, self=self, t=target, s=source, e=env:
|
return map(lambda x, self=self, t=target, s=source, e=env:
|
||||||
self.subst(x, t, s, e),
|
self.subst(x, t, s, e),
|
||||||
|
@ -821,9 +875,10 @@ class ActionFactory:
|
||||||
called with and give them to the ActionCaller object we create,
|
called with and give them to the ActionCaller object we create,
|
||||||
so it can hang onto them until it needs them.
|
so it can hang onto them until it needs them.
|
||||||
"""
|
"""
|
||||||
def __init__(self, actfunc, strfunc):
|
def __init__(self, actfunc, strfunc, convert=lambda x: x):
|
||||||
self.actfunc = actfunc
|
self.actfunc = actfunc
|
||||||
self.strfunc = strfunc
|
self.strfunc = strfunc
|
||||||
|
self.convert = convert
|
||||||
def __call__(self, *args, **kw):
|
def __call__(self, *args, **kw):
|
||||||
ac = ActionCaller(self, args, kw)
|
ac = ActionCaller(self, args, kw)
|
||||||
action = Action(ac, strfunction=ac.strfunction)
|
action = Action(ac, strfunction=ac.strfunction)
|
|
@ -39,9 +39,6 @@ used by other modules:
|
||||||
variable. This also takes care of warning about possible mistakes
|
variable. This also takes care of warning about possible mistakes
|
||||||
in keyword arguments.
|
in keyword arguments.
|
||||||
|
|
||||||
targets()
|
|
||||||
Returns the list of targets for a specific builder instance.
|
|
||||||
|
|
||||||
add_emitter()
|
add_emitter()
|
||||||
Adds an emitter for a specific file suffix, used by some Tool
|
Adds an emitter for a specific file suffix, used by some Tool
|
||||||
modules to specify that (for example) a yacc invocation on a .y
|
modules to specify that (for example) a yacc invocation on a .y
|
||||||
|
@ -101,7 +98,7 @@ There are the following methods for internal use within this module:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Builder.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Builder.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
|
@ -367,6 +364,7 @@ class BuilderBase:
|
||||||
chdir = _null,
|
chdir = _null,
|
||||||
is_explicit = 1,
|
is_explicit = 1,
|
||||||
src_builder = [],
|
src_builder = [],
|
||||||
|
ensure_suffix = False,
|
||||||
**overrides):
|
**overrides):
|
||||||
if __debug__: logInstanceCreation(self, 'Builder.BuilderBase')
|
if __debug__: logInstanceCreation(self, 'Builder.BuilderBase')
|
||||||
self._memo = {}
|
self._memo = {}
|
||||||
|
@ -394,6 +392,7 @@ class BuilderBase:
|
||||||
|
|
||||||
self.set_suffix(suffix)
|
self.set_suffix(suffix)
|
||||||
self.set_src_suffix(src_suffix)
|
self.set_src_suffix(src_suffix)
|
||||||
|
self.ensure_suffix = ensure_suffix
|
||||||
|
|
||||||
self.target_factory = target_factory
|
self.target_factory = target_factory
|
||||||
self.source_factory = source_factory
|
self.source_factory = source_factory
|
||||||
|
@ -467,28 +466,28 @@ class BuilderBase:
|
||||||
executor.add_sources(slist)
|
executor.add_sources(slist)
|
||||||
return executor
|
return executor
|
||||||
|
|
||||||
|
def _adjustixes(self, files, pre, suf, ensure_suffix=False):
|
||||||
|
if not files:
|
||||||
|
return []
|
||||||
|
result = []
|
||||||
|
if not SCons.Util.is_List(files):
|
||||||
|
files = [files]
|
||||||
|
|
||||||
|
for f in files:
|
||||||
|
if SCons.Util.is_String(f):
|
||||||
|
f = SCons.Util.adjustixes(f, pre, suf, ensure_suffix)
|
||||||
|
result.append(f)
|
||||||
|
return result
|
||||||
|
|
||||||
def _create_nodes(self, env, target = None, source = None):
|
def _create_nodes(self, env, target = None, source = None):
|
||||||
"""Create and return lists of target and source nodes.
|
"""Create and return lists of target and source nodes.
|
||||||
"""
|
"""
|
||||||
def _adjustixes(files, pre, suf):
|
|
||||||
if not files:
|
|
||||||
return []
|
|
||||||
result = []
|
|
||||||
if not SCons.Util.is_List(files):
|
|
||||||
files = [files]
|
|
||||||
|
|
||||||
for f in files:
|
|
||||||
if SCons.Util.is_String(f):
|
|
||||||
f = SCons.Util.adjustixes(f, pre, suf)
|
|
||||||
result.append(f)
|
|
||||||
return result
|
|
||||||
|
|
||||||
src_suf = self.get_src_suffix(env)
|
src_suf = self.get_src_suffix(env)
|
||||||
|
|
||||||
target_factory = env.get_factory(self.target_factory)
|
target_factory = env.get_factory(self.target_factory)
|
||||||
source_factory = env.get_factory(self.source_factory)
|
source_factory = env.get_factory(self.source_factory)
|
||||||
|
|
||||||
source = _adjustixes(source, None, src_suf)
|
source = self._adjustixes(source, None, src_suf)
|
||||||
slist = env.arg2nodes(source, source_factory)
|
slist = env.arg2nodes(source, source_factory)
|
||||||
|
|
||||||
pre = self.get_prefix(env, slist)
|
pre = self.get_prefix(env, slist)
|
||||||
|
@ -505,7 +504,7 @@ class BuilderBase:
|
||||||
splitext = lambda S,self=self,env=env: self.splitext(S,env)
|
splitext = lambda S,self=self,env=env: self.splitext(S,env)
|
||||||
tlist = [ t_from_s(pre, suf, splitext) ]
|
tlist = [ t_from_s(pre, suf, splitext) ]
|
||||||
else:
|
else:
|
||||||
target = _adjustixes(target, pre, suf)
|
target = self._adjustixes(target, pre, suf, self.ensure_suffix)
|
||||||
tlist = env.arg2nodes(target, target_factory)
|
tlist = env.arg2nodes(target, target_factory)
|
||||||
|
|
||||||
if self.emitter:
|
if self.emitter:
|
||||||
|
@ -520,6 +519,9 @@ class BuilderBase:
|
||||||
t.builder_set(self)
|
t.builder_set(self)
|
||||||
new_targets.append(t)
|
new_targets.append(t)
|
||||||
|
|
||||||
|
orig_tlist = tlist[:]
|
||||||
|
orig_slist = slist[:]
|
||||||
|
|
||||||
target, source = self.emitter(target=tlist, source=slist, env=env)
|
target, source = self.emitter(target=tlist, source=slist, env=env)
|
||||||
|
|
||||||
# Now delete the temporary builders that we attached to any
|
# Now delete the temporary builders that we attached to any
|
||||||
|
@ -533,8 +535,10 @@ class BuilderBase:
|
||||||
|
|
||||||
# Have to call arg2nodes yet again, since it is legal for
|
# Have to call arg2nodes yet again, since it is legal for
|
||||||
# emitters to spit out strings as well as Node instances.
|
# emitters to spit out strings as well as Node instances.
|
||||||
tlist = env.arg2nodes(target, target_factory)
|
tlist = env.arg2nodes(target, target_factory,
|
||||||
slist = env.arg2nodes(source, source_factory)
|
target=orig_tlist, source=orig_slist)
|
||||||
|
slist = env.arg2nodes(source, source_factory,
|
||||||
|
target=orig_tlist, source=orig_slist)
|
||||||
|
|
||||||
return tlist, slist
|
return tlist, slist
|
||||||
|
|
||||||
|
@ -550,10 +554,10 @@ class BuilderBase:
|
||||||
if not tgt is None: tgt = [tgt]
|
if not tgt is None: tgt = [tgt]
|
||||||
if not src is None: src = [src]
|
if not src is None: src = [src]
|
||||||
result.extend(self._execute(env, tgt, src, overwarn))
|
result.extend(self._execute(env, tgt, src, overwarn))
|
||||||
return result
|
return SCons.Node.NodeList(result)
|
||||||
|
|
||||||
overwarn.warn()
|
overwarn.warn()
|
||||||
|
|
||||||
tlist, slist = self._create_nodes(env, target, source)
|
tlist, slist = self._create_nodes(env, target, source)
|
||||||
|
|
||||||
# Check for errors with the specified target/source lists.
|
# Check for errors with the specified target/source lists.
|
||||||
|
@ -647,13 +651,6 @@ class BuilderBase:
|
||||||
return ''
|
return ''
|
||||||
return ret[0]
|
return ret[0]
|
||||||
|
|
||||||
def targets(self, node):
|
|
||||||
"""Return the list of targets for this builder instance.
|
|
||||||
|
|
||||||
For most normal builders, this is just the supplied node.
|
|
||||||
"""
|
|
||||||
return [ node ]
|
|
||||||
|
|
||||||
def add_emitter(self, suffix, emitter):
|
def add_emitter(self, suffix, emitter):
|
||||||
"""Add a suffix-emitter mapping to this Builder.
|
"""Add a suffix-emitter mapping to this Builder.
|
||||||
|
|
||||||
|
@ -699,22 +696,16 @@ class BuilderBase:
|
||||||
for suf in bld.src_suffixes(env):
|
for suf in bld.src_suffixes(env):
|
||||||
sdict[suf] = bld
|
sdict[suf] = bld
|
||||||
return sdict
|
return sdict
|
||||||
|
|
||||||
def src_builder_sources(self, env, source, overwarn={}):
|
|
||||||
source_factory = env.get_factory(self.source_factory)
|
|
||||||
slist = env.arg2nodes(source, source_factory)
|
|
||||||
|
|
||||||
|
def src_builder_sources(self, env, source, overwarn={}):
|
||||||
sdict = self._get_sdict(env)
|
sdict = self._get_sdict(env)
|
||||||
|
|
||||||
src_suffixes = self.src_suffixes(env)
|
src_suffixes = self.src_suffixes(env)
|
||||||
|
|
||||||
lengths_dict = {}
|
lengths = list(set(map(len, src_suffixes)))
|
||||||
for l in map(len, src_suffixes):
|
|
||||||
lengths_dict[l] = None
|
|
||||||
lengths = lengths_dict.keys()
|
|
||||||
|
|
||||||
def match_src_suffix(node, src_suffixes=src_suffixes, lengths=lengths):
|
def match_src_suffix(name, src_suffixes=src_suffixes, lengths=lengths):
|
||||||
node_suffixes = map(lambda l, n=node: n.name[-l:], lengths)
|
node_suffixes = map(lambda l, n=name: n[-l:], lengths)
|
||||||
for suf in src_suffixes:
|
for suf in src_suffixes:
|
||||||
if suf in node_suffixes:
|
if suf in node_suffixes:
|
||||||
return suf
|
return suf
|
||||||
|
@ -722,25 +713,38 @@ class BuilderBase:
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
for snode in slist:
|
if SCons.Util.is_List(source):
|
||||||
match_suffix = match_src_suffix(snode)
|
source = SCons.Util.flatten(source)
|
||||||
|
else:
|
||||||
|
source = [source]
|
||||||
|
for s in source:
|
||||||
|
if SCons.Util.is_String(s):
|
||||||
|
match_suffix = match_src_suffix(s)
|
||||||
|
if not match_suffix and not '.' in s:
|
||||||
|
src_suf = self.get_src_suffix(env)
|
||||||
|
s = self._adjustixes(s, None, src_suf)[0]
|
||||||
|
else:
|
||||||
|
match_suffix = match_src_suffix(s.name)
|
||||||
if match_suffix:
|
if match_suffix:
|
||||||
try:
|
try:
|
||||||
bld = sdict[match_suffix]
|
bld = sdict[match_suffix]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
result.append(snode)
|
result.append(s)
|
||||||
else:
|
else:
|
||||||
tlist = bld._execute(env, None, [snode], overwarn)
|
tlist = bld._execute(env, None, [s], overwarn)
|
||||||
# If the subsidiary Builder returned more than one
|
# If the subsidiary Builder returned more than one
|
||||||
# target, then filter out any sources that this
|
# target, then filter out any sources that this
|
||||||
# Builder isn't capable of building.
|
# Builder isn't capable of building.
|
||||||
if len(tlist) > 1:
|
if len(tlist) > 1:
|
||||||
tlist = filter(match_src_suffix, tlist)
|
mss = lambda t, m=match_src_suffix: m(t.name)
|
||||||
|
tlist = filter(mss, tlist)
|
||||||
result.extend(tlist)
|
result.extend(tlist)
|
||||||
else:
|
else:
|
||||||
result.append(snode)
|
result.append(s)
|
||||||
|
|
||||||
return result
|
source_factory = env.get_factory(self.source_factory)
|
||||||
|
|
||||||
|
return env.arg2nodes(result, source_factory)
|
||||||
|
|
||||||
def _get_src_builders_key(self, env):
|
def _get_src_builders_key(self, env):
|
||||||
return id(env)
|
return id(env)
|
217
scons/scons-local-0.97.0d20071212/SCons/CacheDir.py
Normal file
217
scons/scons-local-0.97.0d20071212/SCons/CacheDir.py
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
# a copy of this software and associated documentation files (the
|
||||||
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
# without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
# the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included
|
||||||
|
# in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
# 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__ = "src/engine/SCons/CacheDir.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
__doc__ = """
|
||||||
|
CacheDir support
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
import stat
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
|
|
||||||
|
cache_debug = False
|
||||||
|
cache_force = False
|
||||||
|
cache_show = False
|
||||||
|
|
||||||
|
def CacheRetrieveFunc(target, source, env):
|
||||||
|
t = target[0]
|
||||||
|
fs = t.fs
|
||||||
|
cd = env.get_CacheDir()
|
||||||
|
cachedir, cachefile = cd.cachepath(t)
|
||||||
|
if not fs.exists(cachefile):
|
||||||
|
cd.CacheDebug('CacheRetrieve(%s): %s not in cache\n', t, cachefile)
|
||||||
|
return 1
|
||||||
|
cd.CacheDebug('CacheRetrieve(%s): retrieving from %s\n', t, cachefile)
|
||||||
|
if SCons.Action.execute_actions:
|
||||||
|
if fs.islink(cachefile):
|
||||||
|
fs.symlink(fs.readlink(cachefile), t.path)
|
||||||
|
else:
|
||||||
|
env.copy_from_cache(cachefile, t.path)
|
||||||
|
st = fs.stat(cachefile)
|
||||||
|
fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def CacheRetrieveString(target, source, env):
|
||||||
|
t = target[0]
|
||||||
|
fs = t.fs
|
||||||
|
cd = env.get_CacheDir()
|
||||||
|
cachedir, cachefile = cd.cachepath(t)
|
||||||
|
if t.fs.exists(cachefile):
|
||||||
|
return "Retrieved `%s' from cache" % t.path
|
||||||
|
return None
|
||||||
|
|
||||||
|
CacheRetrieve = SCons.Action.Action(CacheRetrieveFunc, CacheRetrieveString)
|
||||||
|
|
||||||
|
CacheRetrieveSilent = SCons.Action.Action(CacheRetrieveFunc, None)
|
||||||
|
|
||||||
|
def CachePushFunc(target, source, env):
|
||||||
|
t = target[0]
|
||||||
|
if t.nocache:
|
||||||
|
return
|
||||||
|
fs = t.fs
|
||||||
|
cd = env.get_CacheDir()
|
||||||
|
cachedir, cachefile = cd.cachepath(t)
|
||||||
|
if fs.exists(cachefile):
|
||||||
|
# Don't bother copying it if it's already there. Note that
|
||||||
|
# usually this "shouldn't happen" because if the file already
|
||||||
|
# existed in cache, we'd have retrieved the file from there,
|
||||||
|
# not built it. This can happen, though, in a race, if some
|
||||||
|
# other person running the same build pushes their copy to
|
||||||
|
# the cache after we decide we need to build it but before our
|
||||||
|
# build completes.
|
||||||
|
cd.CacheDebug('CachePush(%s): %s already exists in cache\n', t, cachefile)
|
||||||
|
return
|
||||||
|
|
||||||
|
cd.CacheDebug('CachePush(%s): pushing to %s\n', t, cachefile)
|
||||||
|
|
||||||
|
tempfile = cachefile+'.tmp'+str(os.getpid())
|
||||||
|
errfmt = "Unable to copy %s to cache. Cache file is %s"
|
||||||
|
|
||||||
|
if not fs.isdir(cachedir):
|
||||||
|
try:
|
||||||
|
fs.makedirs(cachedir)
|
||||||
|
except EnvironmentError:
|
||||||
|
# We may have received an exception because another process
|
||||||
|
# has beaten us creating the directory.
|
||||||
|
if not fs.isdir(cachedir):
|
||||||
|
msg = errfmt % (str(target), cachefile)
|
||||||
|
raise SCons.Errors.EnvironmentError, msg
|
||||||
|
|
||||||
|
try:
|
||||||
|
if fs.islink(t.path):
|
||||||
|
fs.symlink(fs.readlink(t.path), tempfile)
|
||||||
|
else:
|
||||||
|
fs.copy2(t.path, tempfile)
|
||||||
|
fs.rename(tempfile, cachefile)
|
||||||
|
st = fs.stat(t.path)
|
||||||
|
fs.chmod(cachefile, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
|
||||||
|
except EnvironmentError:
|
||||||
|
# It's possible someone else tried writing the file at the
|
||||||
|
# same time we did, or else that there was some problem like
|
||||||
|
# the CacheDir being on a separate file system that's full.
|
||||||
|
# In any case, inability to push a file to cache doesn't affect
|
||||||
|
# the correctness of the build, so just print a warning.
|
||||||
|
msg = errfmt % (str(target), cachefile)
|
||||||
|
SCons.Warnings.warn(SCons.Warnings.CacheWriteErrorWarning, msg)
|
||||||
|
|
||||||
|
CachePush = SCons.Action.Action(CachePushFunc, None)
|
||||||
|
|
||||||
|
class CacheDir:
|
||||||
|
|
||||||
|
def __init__(self, path):
|
||||||
|
try:
|
||||||
|
import hashlib
|
||||||
|
except ImportError:
|
||||||
|
msg = "No hashlib or MD5 module available, CacheDir() not supported"
|
||||||
|
SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg)
|
||||||
|
else:
|
||||||
|
self.path = path
|
||||||
|
|
||||||
|
def CacheDebugWrite(self, fmt, target, cachefile):
|
||||||
|
self.debugFP.write(fmt % (target, os.path.split(cachefile)[1]))
|
||||||
|
|
||||||
|
def CacheDebugQuiet(self, fmt, target, cachefile):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def CacheDebugInit(self, fmt, target, cachefile):
|
||||||
|
if cache_debug:
|
||||||
|
if cache_debug == '-':
|
||||||
|
self.debugFP = sys.stdout
|
||||||
|
else:
|
||||||
|
self.debugFP = open(cache_debug, 'w')
|
||||||
|
self.CacheDebug = self.CacheDebugWrite
|
||||||
|
self.CacheDebug(fmt, target, cachefile)
|
||||||
|
else:
|
||||||
|
self.CacheDebug = self.CacheDebugQuiet
|
||||||
|
|
||||||
|
CacheDebug = CacheDebugInit
|
||||||
|
|
||||||
|
def cachepath(self, node):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
sig = node.get_cachedir_bsig()
|
||||||
|
subdir = string.upper(sig[0])
|
||||||
|
dir = os.path.join(self.path, subdir)
|
||||||
|
return dir, os.path.join(dir, sig)
|
||||||
|
|
||||||
|
def retrieve(self, node):
|
||||||
|
"""
|
||||||
|
This method is called from multiple threads in a parallel build,
|
||||||
|
so only do thread safe stuff here. Do thread unsafe stuff in
|
||||||
|
built().
|
||||||
|
|
||||||
|
Note that there's a special trick here with the execute flag
|
||||||
|
(one that's not normally done for other actions). Basically
|
||||||
|
if the user requested a no_exec (-n) build, then
|
||||||
|
SCons.Action.execute_actions is set to 0 and when any action
|
||||||
|
is called, it does its showing but then just returns zero
|
||||||
|
instead of actually calling the action execution operation.
|
||||||
|
The problem for caching is that if the file does NOT exist in
|
||||||
|
cache then the CacheRetrieveString won't return anything to
|
||||||
|
show for the task, but the Action.__call__ won't call
|
||||||
|
CacheRetrieveFunc; instead it just returns zero, which makes
|
||||||
|
the code below think that the file *was* successfully
|
||||||
|
retrieved from the cache, therefore it doesn't do any
|
||||||
|
subsequent building. However, the CacheRetrieveString didn't
|
||||||
|
print anything because it didn't actually exist in the cache,
|
||||||
|
and no more build actions will be performed, so the user just
|
||||||
|
sees nothing. The fix is to tell Action.__call__ to always
|
||||||
|
execute the CacheRetrieveFunc and then have the latter
|
||||||
|
explicitly check SCons.Action.execute_actions itself.
|
||||||
|
"""
|
||||||
|
retrieved = False
|
||||||
|
|
||||||
|
if cache_show:
|
||||||
|
if CacheRetrieveSilent(node, [], node.get_build_env(), execute=1) == 0:
|
||||||
|
node.build(presub=0, execute=0)
|
||||||
|
retrieved = 1
|
||||||
|
else:
|
||||||
|
if CacheRetrieve(node, [], node.get_build_env(), execute=1) == 0:
|
||||||
|
retrieved = 1
|
||||||
|
if retrieved:
|
||||||
|
# Record build signature information, but don't
|
||||||
|
# push it out to cache. (We just got it from there!)
|
||||||
|
node.set_state(SCons.Node.executed)
|
||||||
|
SCons.Node.Node.built(node)
|
||||||
|
|
||||||
|
return retrieved
|
||||||
|
|
||||||
|
def push(self, node):
|
||||||
|
return CachePush(node, [], node.get_build_env())
|
||||||
|
|
||||||
|
def push_if_forced(self, node):
|
||||||
|
if cache_force:
|
||||||
|
return self.push(node)
|
||||||
|
|
||||||
|
class Null(SCons.Util.Null):
|
||||||
|
def repr(self):
|
||||||
|
return 'CacheDir.Null()'
|
||||||
|
def cachepath(self, node):
|
||||||
|
return None, None
|
||||||
|
def retrieve(self, node):
|
||||||
|
return False
|
|
@ -318,6 +318,102 @@ int main() {
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def CheckTypeSize(context, type_name, header = None, language = None, expect = None):
|
||||||
|
"""This check can be used to get the size of a given type, or to check whether
|
||||||
|
the type is of expected size.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- type : str
|
||||||
|
the type to check
|
||||||
|
- includes : sequence
|
||||||
|
list of headers to include in the test code before testing the type
|
||||||
|
- language : str
|
||||||
|
'C' or 'C++'
|
||||||
|
- expect : int
|
||||||
|
if given, will test wether the type has the given number of bytes.
|
||||||
|
If not given, will automatically find the size.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
status : int
|
||||||
|
0 if the check failed, or the found size of the type if the check succeeded."""
|
||||||
|
|
||||||
|
# Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
|
||||||
|
if context.headerfilename:
|
||||||
|
includetext = '#include "%s"' % context.headerfilename
|
||||||
|
else:
|
||||||
|
includetext = ''
|
||||||
|
|
||||||
|
if not header:
|
||||||
|
header = ""
|
||||||
|
|
||||||
|
lang, suffix, msg = _lang2suffix(language)
|
||||||
|
if msg:
|
||||||
|
context.Display("Cannot check for %s type: %s\n" % (type_name, msg))
|
||||||
|
return msg
|
||||||
|
|
||||||
|
src = includetext + header
|
||||||
|
if not expect is None:
|
||||||
|
# Only check if the given size is the right one
|
||||||
|
context.Display('Checking %s is %d bytes... ' % (type_name, expect))
|
||||||
|
|
||||||
|
# test code taken from autoconf: this is a pretty clever hack to find that
|
||||||
|
# a type is of a given size using only compilation. This speeds things up
|
||||||
|
# quite a bit compared to straightforward code using TryRun
|
||||||
|
src = src + r"""
|
||||||
|
typedef %s scons_check_type;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)];
|
||||||
|
test_array[0] = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# XXX: Try* vs CompileProg ?
|
||||||
|
st = context.TryCompile(src % (type_name, expect), suffix)
|
||||||
|
if st:
|
||||||
|
_Have(context, "SIZEOF_" + type_name, str(expect))
|
||||||
|
context.Display("yes\n")
|
||||||
|
return expect
|
||||||
|
else:
|
||||||
|
context.Display("no\n")
|
||||||
|
_LogFailed(context, src, st)
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
# Only check if the given size is the right one
|
||||||
|
context.Message('Checking size of %s ... ' % type_name)
|
||||||
|
|
||||||
|
# We have to be careful with the program we wish to test here since
|
||||||
|
# compilation will be attempted using the current environment's flags.
|
||||||
|
# So make sure that the program will compile without any warning. For
|
||||||
|
# example using: 'int main(int argc, char** argv)' will fail with the
|
||||||
|
# '-Wall -Werror' flags since the variables argc and argv would not be
|
||||||
|
# used in the program...
|
||||||
|
#
|
||||||
|
src = src + """
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
int main() {
|
||||||
|
printf("%d", (int)sizeof(""" + type_name + """));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
ret = context.TryRun(src, suffix)
|
||||||
|
st = ret[0]
|
||||||
|
try:
|
||||||
|
size = int(ret[1])
|
||||||
|
_Have(context, "SIZEOF_" + type_name, str(size))
|
||||||
|
context.Display("%d\n" % size)
|
||||||
|
except ValueError:
|
||||||
|
size = 0
|
||||||
|
_LogFailed(context, src, st)
|
||||||
|
context.Display(" Failed !\n")
|
||||||
|
if st:
|
||||||
|
return size
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
def CheckLib(context, libs, func_name = None, header = None,
|
def CheckLib(context, libs, func_name = None, header = None,
|
||||||
extra_libs = None, call = None, language = None, autoadd = 1):
|
extra_libs = None, call = None, language = None, autoadd = 1):
|
||||||
|
@ -462,7 +558,7 @@ def _Have(context, key, have):
|
||||||
key_up = re.sub('[^A-Z0-9_]', '_', key_up)
|
key_up = re.sub('[^A-Z0-9_]', '_', key_up)
|
||||||
context.havedict[key_up] = have
|
context.havedict[key_up] = have
|
||||||
if have == 1:
|
if have == 1:
|
||||||
line = "#define %s\n" % key_up
|
line = "#define %s 1\n" % key_up
|
||||||
elif have == 0:
|
elif have == 0:
|
||||||
line = "/* #undef %s */\n" % key_up
|
line = "/* #undef %s */\n" % key_up
|
||||||
elif type(have) == IntType:
|
elif type(have) == IntType:
|
|
@ -29,7 +29,7 @@ needed by most users.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Debug.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Debug.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import string
|
import string
|
||||||
|
@ -197,3 +197,4 @@ def Trace(msg, file=None, mode='w'):
|
||||||
# Assume we were passed an open file pointer.
|
# Assume we were passed an open file pointer.
|
||||||
fp = file
|
fp = file
|
||||||
fp.write(msg)
|
fp.write(msg)
|
||||||
|
fp.flush()
|
|
@ -32,7 +32,7 @@ from distutils.msvccompiler.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Defaults.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Defaults.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,9 +46,9 @@ import sys
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
|
import SCons.CacheDir
|
||||||
import SCons.Environment
|
import SCons.Environment
|
||||||
import SCons.PathList
|
import SCons.PathList
|
||||||
import SCons.Sig
|
|
||||||
import SCons.Subst
|
import SCons.Subst
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
|
||||||
|
@ -60,12 +60,40 @@ _default_env = None
|
||||||
|
|
||||||
# Lazily instantiate the default environment so the overhead of creating
|
# Lazily instantiate the default environment so the overhead of creating
|
||||||
# it doesn't apply when it's not needed.
|
# it doesn't apply when it's not needed.
|
||||||
|
def _fetch_DefaultEnvironment(*args, **kw):
|
||||||
|
"""
|
||||||
|
Returns the already-created default construction environment.
|
||||||
|
"""
|
||||||
|
global _default_env
|
||||||
|
return _default_env
|
||||||
|
|
||||||
def DefaultEnvironment(*args, **kw):
|
def DefaultEnvironment(*args, **kw):
|
||||||
|
"""
|
||||||
|
Initial public entry point for creating the default construction
|
||||||
|
Environment.
|
||||||
|
|
||||||
|
After creating the environment, we overwrite our name
|
||||||
|
(DefaultEnvironment) with the _fetch_DefaultEnvironment() function,
|
||||||
|
which more efficiently returns the initialized default construction
|
||||||
|
environment without checking for its existence.
|
||||||
|
|
||||||
|
(This function still exists with its _default_check because someone
|
||||||
|
else (*cough* Script/__init__.py *cough*) may keep a reference
|
||||||
|
to this function. So we can't use the fully functional idiom of
|
||||||
|
having the name originally be a something that *only* creates the
|
||||||
|
construction environment and then overwrites the name.)
|
||||||
|
"""
|
||||||
global _default_env
|
global _default_env
|
||||||
if not _default_env:
|
if not _default_env:
|
||||||
|
import SCons.Util
|
||||||
_default_env = apply(SCons.Environment.Environment, args, kw)
|
_default_env = apply(SCons.Environment.Environment, args, kw)
|
||||||
_default_env._build_signature = 1
|
if SCons.Util.md5:
|
||||||
_default_env._calc_module = SCons.Sig.default_module
|
_default_env.Decider('MD5')
|
||||||
|
else:
|
||||||
|
_default_env.Decider('timestamp-match')
|
||||||
|
global DefaultEnvironment
|
||||||
|
DefaultEnvironment = _fetch_DefaultEnvironment
|
||||||
|
_default_env._CacheDir = SCons.CacheDir.Null()
|
||||||
return _default_env
|
return _default_env
|
||||||
|
|
||||||
# Emitters for setting the shared attribute on object files,
|
# Emitters for setting the shared attribute on object files,
|
||||||
|
@ -104,9 +132,9 @@ LaTeXScan = SCons.Tool.LaTeXScanner
|
||||||
ObjSourceScan = SCons.Tool.SourceFileScanner
|
ObjSourceScan = SCons.Tool.SourceFileScanner
|
||||||
ProgScan = SCons.Tool.ProgramScanner
|
ProgScan = SCons.Tool.ProgramScanner
|
||||||
|
|
||||||
# This isn't really a tool scanner, so it doesn't quite belong with
|
# These aren't really tool scanners, so they don't quite belong with
|
||||||
# the rest of those in Tool/__init__.py, but I'm not sure where else it
|
# the rest of those in Tool/__init__.py, but I'm not sure where else
|
||||||
# should go. Leave it here for now.
|
# they should go. Leave them here for now.
|
||||||
import SCons.Scanner.Dir
|
import SCons.Scanner.Dir
|
||||||
DirScanner = SCons.Scanner.Dir.DirScanner()
|
DirScanner = SCons.Scanner.Dir.DirScanner()
|
||||||
DirEntryScanner = SCons.Scanner.Dir.DirEntryScanner()
|
DirEntryScanner = SCons.Scanner.Dir.DirEntryScanner()
|
||||||
|
@ -129,19 +157,28 @@ LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR")
|
||||||
# ways by creating ActionFactory instances.
|
# ways by creating ActionFactory instances.
|
||||||
ActionFactory = SCons.Action.ActionFactory
|
ActionFactory = SCons.Action.ActionFactory
|
||||||
|
|
||||||
Chmod = ActionFactory(os.chmod,
|
def chmod_func(path, mode):
|
||||||
|
return os.chmod(str(path), mode)
|
||||||
|
|
||||||
|
Chmod = ActionFactory(chmod_func,
|
||||||
lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
|
lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
|
||||||
|
|
||||||
def copy_func(dest, src):
|
def copy_func(dest, src):
|
||||||
if os.path.isfile(src):
|
if SCons.Util.is_List(src) and os.path.isdir(dest):
|
||||||
|
for file in src:
|
||||||
|
shutil.copy(file, dest)
|
||||||
|
return 0
|
||||||
|
elif os.path.isfile(src):
|
||||||
return shutil.copy(src, dest)
|
return shutil.copy(src, dest)
|
||||||
else:
|
else:
|
||||||
return shutil.copytree(src, dest, 1)
|
return shutil.copytree(src, dest, 1)
|
||||||
|
|
||||||
Copy = ActionFactory(copy_func,
|
Copy = ActionFactory(copy_func,
|
||||||
lambda dest, src: 'Copy("%s", "%s")' % (dest, src))
|
lambda dest, src: 'Copy("%s", "%s")' % (dest, src),
|
||||||
|
convert=str)
|
||||||
|
|
||||||
def delete_func(entry, must_exist=0):
|
def delete_func(entry, must_exist=0):
|
||||||
|
entry = str(entry)
|
||||||
if not must_exist and not os.path.exists(entry):
|
if not must_exist and not os.path.exists(entry):
|
||||||
return None
|
return None
|
||||||
if not os.path.exists(entry) or os.path.isfile(entry):
|
if not os.path.exists(entry) or os.path.isfile(entry):
|
||||||
|
@ -155,12 +192,15 @@ def delete_strfunc(entry, must_exist=0):
|
||||||
Delete = ActionFactory(delete_func, delete_strfunc)
|
Delete = ActionFactory(delete_func, delete_strfunc)
|
||||||
|
|
||||||
Mkdir = ActionFactory(os.makedirs,
|
Mkdir = ActionFactory(os.makedirs,
|
||||||
lambda dir: 'Mkdir("%s")' % dir)
|
lambda dir: 'Mkdir("%s")' % dir,
|
||||||
|
convert=str)
|
||||||
|
|
||||||
Move = ActionFactory(lambda dest, src: os.rename(src, dest),
|
Move = ActionFactory(lambda dest, src: os.rename(src, dest),
|
||||||
lambda dest, src: 'Move("%s", "%s")' % (dest, src))
|
lambda dest, src: 'Move("%s", "%s")' % (dest, src),
|
||||||
|
convert=str)
|
||||||
|
|
||||||
def touch_func(file):
|
def touch_func(file):
|
||||||
|
file = str(file)
|
||||||
mtime = int(time.time())
|
mtime = int(time.time())
|
||||||
if os.path.exists(file):
|
if os.path.exists(file):
|
||||||
atime = os.path.getatime(file)
|
atime = os.path.getatime(file)
|
||||||
|
@ -173,33 +213,6 @@ Touch = ActionFactory(touch_func,
|
||||||
lambda file: 'Touch("%s")' % file)
|
lambda file: 'Touch("%s")' % file)
|
||||||
|
|
||||||
# Internal utility functions
|
# Internal utility functions
|
||||||
def installFunc(dest, source, env):
|
|
||||||
"""Install a source file or directory into a destination by copying,
|
|
||||||
(including copying permission/mode bits)."""
|
|
||||||
|
|
||||||
if os.path.isdir(source):
|
|
||||||
if os.path.exists(dest):
|
|
||||||
if not os.path.isdir(dest):
|
|
||||||
raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source))
|
|
||||||
else:
|
|
||||||
parent = os.path.split(dest)[0]
|
|
||||||
if not os.path.exists(parent):
|
|
||||||
os.makedirs(parent)
|
|
||||||
shutil.copytree(source, dest)
|
|
||||||
else:
|
|
||||||
shutil.copy2(source, dest)
|
|
||||||
st = os.stat(source)
|
|
||||||
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def installStr(dest, source, env):
|
|
||||||
source = str(source)
|
|
||||||
if os.path.isdir(source):
|
|
||||||
type = 'directory'
|
|
||||||
else:
|
|
||||||
type = 'file'
|
|
||||||
return 'Install %s: "%s" as "%s"' % (type, source, dest)
|
|
||||||
|
|
||||||
def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
|
def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
|
||||||
"""
|
"""
|
||||||
|
@ -258,91 +271,46 @@ def _concat_ixes(prefix, list, suffix, env):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _stripixes(prefix, list, suffix, stripprefix, stripsuffix, env, c=None):
|
def _stripixes(prefix, list, suffix, stripprefix, stripsuffix, env, c=None):
|
||||||
"""This is a wrapper around _concat() that checks for the existence
|
"""
|
||||||
of prefixes or suffixes on list elements and strips them where it
|
This is a wrapper around _concat()/_concat_ixes() that checks for the
|
||||||
finds them. This is used by tools (like the GNU linker) that need
|
existence of prefixes or suffixes on list elements and strips them
|
||||||
to turn something like 'libfoo.a' into '-lfoo'."""
|
where it finds them. This is used by tools (like the GNU linker)
|
||||||
|
that need to turn something like 'libfoo.a' into '-lfoo'.
|
||||||
|
"""
|
||||||
|
|
||||||
if not callable(c):
|
if not list:
|
||||||
if callable(env["_concat"]):
|
return list
|
||||||
c = env["_concat"]
|
|
||||||
else:
|
|
||||||
c = _concat
|
|
||||||
def f(list, sp=stripprefix, ss=stripsuffix):
|
|
||||||
result = []
|
|
||||||
for l in list:
|
|
||||||
if isinstance(l, SCons.Node.FS.File):
|
|
||||||
result.append(l)
|
|
||||||
continue
|
|
||||||
if not SCons.Util.is_String(l):
|
|
||||||
l = str(l)
|
|
||||||
if l[:len(sp)] == sp:
|
|
||||||
l = l[len(sp):]
|
|
||||||
if l[-len(ss):] == ss:
|
|
||||||
l = l[:-len(ss)]
|
|
||||||
result.append(l)
|
|
||||||
return result
|
|
||||||
return c(prefix, list, suffix, env, f)
|
|
||||||
|
|
||||||
# This is an alternate _stripixes() function that passes all of our tests
|
if not callable(c):
|
||||||
# (as of 21 February 2007), like the current version above. It's more
|
env_c = env['_concat']
|
||||||
# straightforward because it does its manipulation directly, not using
|
if env_c != _concat and callable(env_c):
|
||||||
# the funky f call-back function to _concat(). (In this respect it's
|
# There's a custom _concat() method in the construction
|
||||||
# like the updated _defines() function below.)
|
# environment, and we've allowed people to set that in
|
||||||
#
|
# the past (see test/custom-concat.py), so preserve the
|
||||||
# The most convoluted thing is that it still uses a custom _concat()
|
# backwards compatibility.
|
||||||
# function if one was placed in the construction environment; there's
|
c = env_c
|
||||||
# a specific test for that functionality, but it might be worth getting
|
else:
|
||||||
# rid of.
|
c = _concat_ixes
|
||||||
#
|
|
||||||
# Since this work was done while trying to get 0.97 out the door
|
if SCons.Util.is_List(list):
|
||||||
# (just prior to 0.96.96), I decided to be cautious and leave the old
|
list = SCons.Util.flatten(list)
|
||||||
# function as is, to minimize the chance of other corner-case regressions.
|
|
||||||
# The updated version is captured here so we can uncomment it and start
|
lsp = len(stripprefix)
|
||||||
# using it at a less sensitive time in the development cycle (or when
|
lss = len(stripsuffix)
|
||||||
# it's clearly required to fix something).
|
stripped = []
|
||||||
#
|
for l in SCons.PathList.PathList(list).subst_path(env, None, None):
|
||||||
#def _stripixes(prefix, list, suffix, stripprefix, stripsuffix, env, c=None):
|
if isinstance(l, SCons.Node.FS.File):
|
||||||
# """
|
stripped.append(l)
|
||||||
# This is a wrapper around _concat()/_concat_ixes() that checks for the
|
continue
|
||||||
# existence of prefixes or suffixes on list elements and strips them
|
if not SCons.Util.is_String(l):
|
||||||
# where it finds them. This is used by tools (like the GNU linker)
|
l = str(l)
|
||||||
# that need to turn something like 'libfoo.a' into '-lfoo'.
|
if l[:lsp] == stripprefix:
|
||||||
# """
|
l = l[lsp:]
|
||||||
#
|
if l[-lss:] == stripsuffix:
|
||||||
# if not list:
|
l = l[:-lss]
|
||||||
# return list
|
stripped.append(l)
|
||||||
#
|
|
||||||
# if not callable(c):
|
return c(prefix, stripped, suffix, env)
|
||||||
# env_c = env['_concat']
|
|
||||||
# if env_c != _concat and callable(env_c):
|
|
||||||
# # There's a custom _concat() method in the construction
|
|
||||||
# # environment, and we've allowed people to set that in
|
|
||||||
# # the past (see test/custom-concat.py), so preserve the
|
|
||||||
# # backwards compatibility.
|
|
||||||
# c = env_c
|
|
||||||
# else:
|
|
||||||
# c = _concat_ixes
|
|
||||||
#
|
|
||||||
# if SCons.Util.is_List(list):
|
|
||||||
# list = SCons.Util.flatten(list)
|
|
||||||
#
|
|
||||||
# lsp = len(stripprefix)
|
|
||||||
# lss = len(stripsuffix)
|
|
||||||
# stripped = []
|
|
||||||
# for l in SCons.PathList.PathList(list).subst_path(env, None, None):
|
|
||||||
# if isinstance(l, SCons.Node.FS.File):
|
|
||||||
# stripped.append(l)
|
|
||||||
# continue
|
|
||||||
# if not SCons.Util.is_String(l):
|
|
||||||
# l = str(l)
|
|
||||||
# if l[:lsp] == stripprefix:
|
|
||||||
# l = l[lsp:]
|
|
||||||
# if l[-lss:] == stripsuffix:
|
|
||||||
# l = l[:-lss]
|
|
||||||
# stripped.append(l)
|
|
||||||
#
|
|
||||||
# return c(prefix, stripped, suffix, env)
|
|
||||||
|
|
||||||
def _defines(prefix, defs, suffix, env, c=_concat_ixes):
|
def _defines(prefix, defs, suffix, env, c=_concat_ixes):
|
||||||
"""A wrapper around _concat_ixes that turns a list or string
|
"""A wrapper around _concat_ixes that turns a list or string
|
||||||
|
@ -430,9 +398,6 @@ ConstructionEnvironment = {
|
||||||
'DSUFFIXES' : SCons.Tool.DSuffixes,
|
'DSUFFIXES' : SCons.Tool.DSuffixes,
|
||||||
'ENV' : {},
|
'ENV' : {},
|
||||||
'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
|
'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
|
||||||
'INSTALL' : installFunc,
|
|
||||||
'INSTALLSTR' : installStr,
|
|
||||||
'_installStr' : installStr,
|
|
||||||
'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes,
|
'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes,
|
||||||
'_concat' : _concat,
|
'_concat' : _concat,
|
||||||
'_defines' : _defines,
|
'_defines' : _defines,
|
|
@ -6,7 +6,7 @@ construction information to the build engine.
|
||||||
|
|
||||||
Keyword arguments supplied when the construction Environment
|
Keyword arguments supplied when the construction Environment
|
||||||
is created are construction variables used to initialize the
|
is created are construction variables used to initialize the
|
||||||
Environment
|
Environment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -32,12 +32,13 @@ Environment
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Environment.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Environment.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
import shlex
|
||||||
import string
|
import string
|
||||||
from UserDict import UserDict
|
from UserDict import UserDict
|
||||||
|
|
||||||
|
@ -53,7 +54,6 @@ import SCons.Node.FS
|
||||||
import SCons.Node.Python
|
import SCons.Node.Python
|
||||||
import SCons.Platform
|
import SCons.Platform
|
||||||
import SCons.SConsign
|
import SCons.SConsign
|
||||||
import SCons.Sig
|
|
||||||
import SCons.Subst
|
import SCons.Subst
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
@ -67,32 +67,13 @@ _null = _Null
|
||||||
CleanTargets = {}
|
CleanTargets = {}
|
||||||
CalculatorArgs = {}
|
CalculatorArgs = {}
|
||||||
|
|
||||||
|
semi_deepcopy = SCons.Util.semi_deepcopy
|
||||||
|
|
||||||
# Pull UserError into the global name space for the benefit of
|
# Pull UserError into the global name space for the benefit of
|
||||||
# Environment().SourceSignatures(), which has some import statements
|
# Environment().SourceSignatures(), which has some import statements
|
||||||
# which seem to mess up its ability to reference SCons directly.
|
# which seem to mess up its ability to reference SCons directly.
|
||||||
UserError = SCons.Errors.UserError
|
UserError = SCons.Errors.UserError
|
||||||
|
|
||||||
def installFunc(target, source, env):
|
|
||||||
"""Install a source file into a target using the function specified
|
|
||||||
as the INSTALL construction variable."""
|
|
||||||
try:
|
|
||||||
install = env['INSTALL']
|
|
||||||
except KeyError:
|
|
||||||
raise SCons.Errors.UserError('Missing INSTALL construction variable.')
|
|
||||||
return install(target[0].path, source[0].path, env)
|
|
||||||
|
|
||||||
def installString(target, source, env):
|
|
||||||
s = env.get('INSTALLSTR', '')
|
|
||||||
if callable(s):
|
|
||||||
return s(target[0].path, source[0].path, env)
|
|
||||||
else:
|
|
||||||
return env.subst_target_source(s, 0, target, source)
|
|
||||||
|
|
||||||
installAction = SCons.Action.Action(installFunc, installString)
|
|
||||||
|
|
||||||
InstallBuilder = SCons.Builder.Builder(action=installAction,
|
|
||||||
name='InstallBuilder')
|
|
||||||
|
|
||||||
def alias_builder(env, target, source):
|
def alias_builder(env, target, source):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -103,23 +84,6 @@ AliasBuilder = SCons.Builder.Builder(action = alias_builder,
|
||||||
is_explicit = None,
|
is_explicit = None,
|
||||||
name='AliasBuilder')
|
name='AliasBuilder')
|
||||||
|
|
||||||
def our_deepcopy(x):
|
|
||||||
"""deepcopy lists and dictionaries, and just copy the reference
|
|
||||||
for everything else."""
|
|
||||||
if SCons.Util.is_Dict(x):
|
|
||||||
copy = {}
|
|
||||||
for key in x.keys():
|
|
||||||
copy[key] = our_deepcopy(x[key])
|
|
||||||
elif SCons.Util.is_List(x):
|
|
||||||
copy = map(our_deepcopy, x)
|
|
||||||
try:
|
|
||||||
copy = x.__class__(copy)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
copy = x
|
|
||||||
return copy
|
|
||||||
|
|
||||||
def apply_tools(env, tools, toolpath):
|
def apply_tools(env, tools, toolpath):
|
||||||
# Store the toolpath in the Environment.
|
# Store the toolpath in the Environment.
|
||||||
if toolpath is not None:
|
if toolpath is not None:
|
||||||
|
@ -143,7 +107,7 @@ reserved_construction_var_names = \
|
||||||
['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']
|
['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']
|
||||||
|
|
||||||
def copy_non_reserved_keywords(dict):
|
def copy_non_reserved_keywords(dict):
|
||||||
result = our_deepcopy(dict)
|
result = semi_deepcopy(dict)
|
||||||
for k in result.keys():
|
for k in result.keys():
|
||||||
if k in reserved_construction_var_names:
|
if k in reserved_construction_var_names:
|
||||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning,
|
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning,
|
||||||
|
@ -161,8 +125,9 @@ def _set_BUILDERS(env, key, value):
|
||||||
for k in bd.keys():
|
for k in bd.keys():
|
||||||
del bd[k]
|
del bd[k]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
env._dict[key] = BuilderDict(kwbd, env)
|
bd = BuilderDict(kwbd, env)
|
||||||
env._dict[key].update(value)
|
env._dict[key] = bd
|
||||||
|
bd.update(value)
|
||||||
|
|
||||||
def _del_SCANNERS(env, key):
|
def _del_SCANNERS(env, key):
|
||||||
del env._dict[key]
|
del env._dict[key]
|
||||||
|
@ -172,13 +137,72 @@ def _set_SCANNERS(env, key, value):
|
||||||
env._dict[key] = value
|
env._dict[key] = value
|
||||||
env.scanner_map_delete()
|
env.scanner_map_delete()
|
||||||
|
|
||||||
class BuilderWrapper:
|
|
||||||
"""Wrapper class that associates an environment with a Builder at
|
|
||||||
instantiation."""
|
|
||||||
def __init__(self, env, builder):
|
|
||||||
self.env = env
|
|
||||||
self.builder = builder
|
|
||||||
|
|
||||||
|
|
||||||
|
# The following is partly based on code in a comment added by Peter
|
||||||
|
# Shannon at the following page (there called the "transplant" class):
|
||||||
|
#
|
||||||
|
# ASPN : Python Cookbook : Dynamically added methods to a class
|
||||||
|
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81732
|
||||||
|
#
|
||||||
|
# We had independently been using the idiom as BuilderWrapper, but
|
||||||
|
# factoring out the common parts into this base class, and making
|
||||||
|
# BuilderWrapper a subclass that overrides __call__() to enforce specific
|
||||||
|
# Builder calling conventions, simplified some of our higher-layer code.
|
||||||
|
|
||||||
|
class MethodWrapper:
|
||||||
|
"""
|
||||||
|
A generic Wrapper class that associates a method (which can
|
||||||
|
actually be any callable) with an object. As part of creating this
|
||||||
|
MethodWrapper object an attribute with the specified (by default,
|
||||||
|
the name of the supplied method) is added to the underlying object.
|
||||||
|
When that new "method" is called, our __call__() method adds the
|
||||||
|
object as the first argument, simulating the Python behavior of
|
||||||
|
supplying "self" on method calls.
|
||||||
|
|
||||||
|
We hang on to the name by which the method was added to the underlying
|
||||||
|
base class so that we can provide a method to "clone" ourselves onto
|
||||||
|
a new underlying object being copied (without which we wouldn't need
|
||||||
|
to save that info).
|
||||||
|
"""
|
||||||
|
def __init__(self, object, method, name=None):
|
||||||
|
if name is None:
|
||||||
|
name = method.__name__
|
||||||
|
self.object = object
|
||||||
|
self.method = method
|
||||||
|
self.name = name
|
||||||
|
setattr(self.object, name, self)
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
nargs = (self.object,) + args
|
||||||
|
return apply(self.method, nargs, kwargs)
|
||||||
|
|
||||||
|
def clone(self, new_object):
|
||||||
|
"""
|
||||||
|
Returns an object that re-binds the underlying "method" to
|
||||||
|
the specified new object.
|
||||||
|
"""
|
||||||
|
return self.__class__(new_object, self.method, self.name)
|
||||||
|
|
||||||
|
class BuilderWrapper(MethodWrapper):
|
||||||
|
"""
|
||||||
|
A MethodWrapper subclass that that associates an environment with
|
||||||
|
a Builder.
|
||||||
|
|
||||||
|
This mainly exists to wrap the __call__() function so that all calls
|
||||||
|
to Builders can have their argument lists massaged in the same way
|
||||||
|
(treat a lone argument as the source, treat two arguments as target
|
||||||
|
then source, make sure both target and source are lists) without
|
||||||
|
having to have cut-and-paste code to do it.
|
||||||
|
|
||||||
|
As a bit of obsessive backwards compatibility, we also intercept
|
||||||
|
attempts to get or set the "env" or "builder" attributes, which were
|
||||||
|
the names we used before we put the common functionality into the
|
||||||
|
MethodWrapper base class. We'll keep this around for a while in case
|
||||||
|
people shipped Tool modules that reached into the wrapper (like the
|
||||||
|
Tool/qt.py module does, or did). There shouldn't be a lot attribute
|
||||||
|
fetching or setting on these, so a little extra work shouldn't hurt.
|
||||||
|
"""
|
||||||
def __call__(self, target=None, source=_null, *args, **kw):
|
def __call__(self, target=None, source=_null, *args, **kw):
|
||||||
if source is _null:
|
if source is _null:
|
||||||
source = target
|
source = target
|
||||||
|
@ -187,7 +211,29 @@ class BuilderWrapper:
|
||||||
target = [target]
|
target = [target]
|
||||||
if not source is None and not SCons.Util.is_List(source):
|
if not source is None and not SCons.Util.is_List(source):
|
||||||
source = [source]
|
source = [source]
|
||||||
return apply(self.builder, (self.env, target, source) + args, kw)
|
return apply(MethodWrapper.__call__, (self, target, source) + args, kw)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<BuilderWrapper %s>' % repr(self.name)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.__repr__()
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
if name == 'env':
|
||||||
|
return self.object
|
||||||
|
elif name == 'builder':
|
||||||
|
return self.method
|
||||||
|
else:
|
||||||
|
return self.__dict__[name]
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
if name == 'env':
|
||||||
|
self.object = value
|
||||||
|
elif name == 'builder':
|
||||||
|
self.method = value
|
||||||
|
else:
|
||||||
|
self.__dict__[name] = value
|
||||||
|
|
||||||
# This allows a Builder to be executed directly
|
# This allows a Builder to be executed directly
|
||||||
# through the Environment to which it's attached.
|
# through the Environment to which it's attached.
|
||||||
|
@ -196,9 +242,9 @@ class BuilderWrapper:
|
||||||
# But we do have a unit test for this, and can't
|
# But we do have a unit test for this, and can't
|
||||||
# yet rule out that it would be useful in the
|
# yet rule out that it would be useful in the
|
||||||
# future, so leave it for now.
|
# future, so leave it for now.
|
||||||
def execute(self, **kw):
|
#def execute(self, **kw):
|
||||||
kw['env'] = self.env
|
# kw['env'] = self.env
|
||||||
apply(self.builder.execute, (), kw)
|
# apply(self.builder.execute, (), kw)
|
||||||
|
|
||||||
class BuilderDict(UserDict):
|
class BuilderDict(UserDict):
|
||||||
"""This is a dictionary-like class used by an Environment to hold
|
"""This is a dictionary-like class used by an Environment to hold
|
||||||
|
@ -212,28 +258,18 @@ class BuilderDict(UserDict):
|
||||||
self.env = env
|
self.env = env
|
||||||
UserDict.__init__(self, dict)
|
UserDict.__init__(self, dict)
|
||||||
|
|
||||||
|
def __semi_deepcopy__(self):
|
||||||
|
return self.__class__(self.data, self.env)
|
||||||
|
|
||||||
def __setitem__(self, item, val):
|
def __setitem__(self, item, val):
|
||||||
UserDict.__setitem__(self, item, val)
|
|
||||||
try:
|
try:
|
||||||
self.setenvattr(item, val)
|
method = getattr(self.env, item).method
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Have to catch this because sometimes __setitem__ gets
|
|
||||||
# called out of __init__, when we don't have an env
|
|
||||||
# attribute yet, nor do we want one!
|
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
def setenvattr(self, item, val):
|
self.env.RemoveMethod(method)
|
||||||
"""Set the corresponding environment attribute for this Builder.
|
UserDict.__setitem__(self, item, val)
|
||||||
|
BuilderWrapper(self.env, val, item)
|
||||||
If the value is already a BuilderWrapper, we pull the builder
|
|
||||||
out of it and make another one, so that making a copy of an
|
|
||||||
existing BuilderDict is guaranteed separate wrappers for each
|
|
||||||
Builder + Environment pair."""
|
|
||||||
try:
|
|
||||||
builder = val.builder
|
|
||||||
except AttributeError:
|
|
||||||
builder = val
|
|
||||||
setattr(self.env, item, BuilderWrapper(self.env, builder))
|
|
||||||
|
|
||||||
def __delitem__(self, item):
|
def __delitem__(self, item):
|
||||||
UserDict.__delitem__(self, item)
|
UserDict.__delitem__(self, item)
|
||||||
|
@ -276,11 +312,12 @@ class SubstitutionEnvironment:
|
||||||
"""Initialization of an underlying SubstitutionEnvironment class.
|
"""Initialization of an underlying SubstitutionEnvironment class.
|
||||||
"""
|
"""
|
||||||
if __debug__: logInstanceCreation(self, 'Environment.SubstitutionEnvironment')
|
if __debug__: logInstanceCreation(self, 'Environment.SubstitutionEnvironment')
|
||||||
self.fs = SCons.Node.FS.default_fs or SCons.Node.FS.FS()
|
self.fs = SCons.Node.FS.get_default_fs()
|
||||||
self.ans = SCons.Node.Alias.default_ans
|
self.ans = SCons.Node.Alias.default_ans
|
||||||
self.lookup_list = SCons.Node.arg2nodes_lookups
|
self.lookup_list = SCons.Node.arg2nodes_lookups
|
||||||
self._dict = kw.copy()
|
self._dict = kw.copy()
|
||||||
self._init_special()
|
self._init_special()
|
||||||
|
self.added_methods = []
|
||||||
#self._memo = {}
|
#self._memo = {}
|
||||||
|
|
||||||
def _init_special(self):
|
def _init_special(self):
|
||||||
|
@ -327,7 +364,7 @@ class SubstitutionEnvironment:
|
||||||
def items(self):
|
def items(self):
|
||||||
return self._dict.items()
|
return self._dict.items()
|
||||||
|
|
||||||
def arg2nodes(self, args, node_factory=_null, lookup_list=_null):
|
def arg2nodes(self, args, node_factory=_null, lookup_list=_null, **kw):
|
||||||
if node_factory is _null:
|
if node_factory is _null:
|
||||||
node_factory = self.fs.File
|
node_factory = self.fs.File
|
||||||
if lookup_list is _null:
|
if lookup_list is _null:
|
||||||
|
@ -351,7 +388,9 @@ class SubstitutionEnvironment:
|
||||||
break
|
break
|
||||||
if not n is None:
|
if not n is None:
|
||||||
if SCons.Util.is_String(n):
|
if SCons.Util.is_String(n):
|
||||||
n = self.subst(n, raw=1)
|
# n = self.subst(n, raw=1, **kw)
|
||||||
|
kw['raw'] = 1
|
||||||
|
n = apply(self.subst, (n,), kw)
|
||||||
if node_factory:
|
if node_factory:
|
||||||
n = node_factory(n)
|
n = node_factory(n)
|
||||||
if SCons.Util.is_List(n):
|
if SCons.Util.is_List(n):
|
||||||
|
@ -359,14 +398,16 @@ class SubstitutionEnvironment:
|
||||||
else:
|
else:
|
||||||
nodes.append(n)
|
nodes.append(n)
|
||||||
elif node_factory:
|
elif node_factory:
|
||||||
v = node_factory(self.subst(v, raw=1))
|
# v = node_factory(self.subst(v, raw=1, **kw))
|
||||||
|
kw['raw'] = 1
|
||||||
|
v = node_factory(apply(self.subst, (v,), kw))
|
||||||
if SCons.Util.is_List(v):
|
if SCons.Util.is_List(v):
|
||||||
nodes.extend(v)
|
nodes.extend(v)
|
||||||
else:
|
else:
|
||||||
nodes.append(v)
|
nodes.append(v)
|
||||||
else:
|
else:
|
||||||
nodes.append(v)
|
nodes.append(v)
|
||||||
|
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
def gvars(self):
|
def gvars(self):
|
||||||
|
@ -473,6 +514,23 @@ class SubstitutionEnvironment:
|
||||||
raise OSError("'%s' exited %d" % (command, status))
|
raise OSError("'%s' exited %d" % (command, status))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def AddMethod(self, function, name=None):
|
||||||
|
"""
|
||||||
|
Adds the specified function as a method of this construction
|
||||||
|
environment with the specified name. If the name is omitted,
|
||||||
|
the default name is the name of the function itself.
|
||||||
|
"""
|
||||||
|
method = MethodWrapper(self, function, name)
|
||||||
|
self.added_methods.append(method)
|
||||||
|
|
||||||
|
def RemoveMethod(self, function):
|
||||||
|
"""
|
||||||
|
Removes the specified function's MethodWrapper from the
|
||||||
|
added_methods list, so we don't re-bind it when making a clone.
|
||||||
|
"""
|
||||||
|
is_not_func = lambda dm, f=function: not dm.method is f
|
||||||
|
self.added_methods = filter(is_not_func, self.added_methods)
|
||||||
|
|
||||||
def Override(self, overrides):
|
def Override(self, overrides):
|
||||||
"""
|
"""
|
||||||
Produce a modified environment whose variables are overriden by
|
Produce a modified environment whose variables are overriden by
|
||||||
|
@ -564,7 +622,7 @@ class SubstitutionEnvironment:
|
||||||
# -R dir (deprecated linker rpath)
|
# -R dir (deprecated linker rpath)
|
||||||
# IBM compilers may also accept -qframeworkdir=foo
|
# IBM compilers may also accept -qframeworkdir=foo
|
||||||
|
|
||||||
params = string.split(arg)
|
params = shlex.split(arg)
|
||||||
append_next_arg_to = None # for multi-word args
|
append_next_arg_to = None # for multi-word args
|
||||||
for arg in params:
|
for arg in params:
|
||||||
if append_next_arg_to:
|
if append_next_arg_to:
|
||||||
|
@ -705,6 +763,29 @@ class SubstitutionEnvironment:
|
||||||
self[key] = t
|
self[key] = t
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
# Used by the FindSourceFiles() method, below.
|
||||||
|
# Stuck here for support of pre-2.2 Python versions.
|
||||||
|
def build_source(ss, result):
|
||||||
|
for s in ss:
|
||||||
|
if isinstance(s, SCons.Node.FS.Dir):
|
||||||
|
build_source(s.all_children(), result)
|
||||||
|
elif s.has_builder():
|
||||||
|
build_source(s.sources, result)
|
||||||
|
elif isinstance(s.disambiguate(), SCons.Node.FS.File):
|
||||||
|
result.append(s)
|
||||||
|
|
||||||
|
def default_decide_source(dependency, target, prev_ni):
|
||||||
|
f = SCons.Defaults.DefaultEnvironment().decide_source
|
||||||
|
return f(dependency, target, prev_ni)
|
||||||
|
|
||||||
|
def default_decide_target(dependency, target, prev_ni):
|
||||||
|
f = SCons.Defaults.DefaultEnvironment().decide_target
|
||||||
|
return f(dependency, target, prev_ni)
|
||||||
|
|
||||||
|
def default_copy_from_cache(src, dst):
|
||||||
|
f = SCons.Defaults.DefaultEnvironment().copy_from_cache
|
||||||
|
return f(src, dst)
|
||||||
|
|
||||||
class Base(SubstitutionEnvironment):
|
class Base(SubstitutionEnvironment):
|
||||||
"""Base class for "real" construction Environments. These are the
|
"""Base class for "real" construction Environments. These are the
|
||||||
primary objects used to communicate dependency and construction
|
primary objects used to communicate dependency and construction
|
||||||
|
@ -752,11 +833,23 @@ class Base(SubstitutionEnvironment):
|
||||||
"""
|
"""
|
||||||
if __debug__: logInstanceCreation(self, 'Environment.Base')
|
if __debug__: logInstanceCreation(self, 'Environment.Base')
|
||||||
self._memo = {}
|
self._memo = {}
|
||||||
self.fs = SCons.Node.FS.default_fs or SCons.Node.FS.FS()
|
self.fs = SCons.Node.FS.get_default_fs()
|
||||||
self.ans = SCons.Node.Alias.default_ans
|
self.ans = SCons.Node.Alias.default_ans
|
||||||
self.lookup_list = SCons.Node.arg2nodes_lookups
|
self.lookup_list = SCons.Node.arg2nodes_lookups
|
||||||
self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment)
|
self._dict = semi_deepcopy(SCons.Defaults.ConstructionEnvironment)
|
||||||
self._init_special()
|
self._init_special()
|
||||||
|
self.added_methods = []
|
||||||
|
|
||||||
|
# We don't use AddMethod, or define these as methods in this
|
||||||
|
# class, because we *don't* want these functions to be bound
|
||||||
|
# methods. They need to operate independently so that the
|
||||||
|
# settings will work properly regardless of whether a given
|
||||||
|
# target ends up being built with a Base environment or an
|
||||||
|
# OverrideEnvironment or what have you.
|
||||||
|
self.decide_target = default_decide_target
|
||||||
|
self.decide_source = default_decide_source
|
||||||
|
|
||||||
|
self.copy_from_cache = default_copy_from_cache
|
||||||
|
|
||||||
self._dict['BUILDERS'] = BuilderDict(self._dict['BUILDERS'], self)
|
self._dict['BUILDERS'] = BuilderDict(self._dict['BUILDERS'], self)
|
||||||
|
|
||||||
|
@ -787,6 +880,8 @@ class Base(SubstitutionEnvironment):
|
||||||
# reserved variable name like TARGETS.
|
# reserved variable name like TARGETS.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
SCons.Tool.Initializers(self)
|
||||||
|
|
||||||
if tools is None:
|
if tools is None:
|
||||||
tools = self._dict.get('TOOLS', None)
|
tools = self._dict.get('TOOLS', None)
|
||||||
if tools is None:
|
if tools is None:
|
||||||
|
@ -812,16 +907,13 @@ class Base(SubstitutionEnvironment):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_calculator(self):
|
def get_CacheDir(self):
|
||||||
try:
|
try:
|
||||||
module = self._calc_module
|
return self._CacheDir
|
||||||
c = apply(SCons.Sig.Calculator, (module,), CalculatorArgs)
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Note that we're calling get_calculator() here, so the
|
cd = SCons.Defaults.DefaultEnvironment()._CacheDir
|
||||||
# DefaultEnvironment() must have a _calc_module attribute
|
self._CacheDir = cd
|
||||||
# to avoid infinite recursion.
|
return cd
|
||||||
c = SCons.Defaults.DefaultEnvironment().get_calculator()
|
|
||||||
return c
|
|
||||||
|
|
||||||
def get_factory(self, factory, default='File'):
|
def get_factory(self, factory, default='File'):
|
||||||
"""Return a factory function for creating Nodes for this
|
"""Return a factory function for creating Nodes for this
|
||||||
|
@ -883,7 +975,7 @@ class Base(SubstitutionEnvironment):
|
||||||
self._memo['_gsm'] = result
|
self._memo['_gsm'] = result
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_scanner(self, skey):
|
def get_scanner(self, skey):
|
||||||
"""Find the appropriate scanner given a key (usually a file suffix).
|
"""Find the appropriate scanner given a key (usually a file suffix).
|
||||||
"""
|
"""
|
||||||
|
@ -903,13 +995,21 @@ class Base(SubstitutionEnvironment):
|
||||||
"""
|
"""
|
||||||
self._dict.update(dict)
|
self._dict.update(dict)
|
||||||
|
|
||||||
def use_build_signature(self):
|
def get_src_sig_type(self):
|
||||||
try:
|
try:
|
||||||
return self._build_signature
|
return self.src_sig_type
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
b = SCons.Defaults.DefaultEnvironment()._build_signature
|
t = SCons.Defaults.DefaultEnvironment().src_sig_type
|
||||||
self._build_signature = b
|
self.src_sig_type = t
|
||||||
return b
|
return t
|
||||||
|
|
||||||
|
def get_tgt_sig_type(self):
|
||||||
|
try:
|
||||||
|
return self.tgt_sig_type
|
||||||
|
except AttributeError:
|
||||||
|
t = SCons.Defaults.DefaultEnvironment().tgt_sig_type
|
||||||
|
self.tgt_sig_type = t
|
||||||
|
return t
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# Public methods for manipulating an Environment. These begin with
|
# Public methods for manipulating an Environment. These begin with
|
||||||
|
@ -978,7 +1078,11 @@ class Base(SubstitutionEnvironment):
|
||||||
try:
|
try:
|
||||||
update_dict(val)
|
update_dict(val)
|
||||||
except (AttributeError, TypeError, ValueError):
|
except (AttributeError, TypeError, ValueError):
|
||||||
orig[val] = None
|
if SCons.Util.is_Dict(val):
|
||||||
|
for k, v in val.items():
|
||||||
|
orig[k] = v
|
||||||
|
else:
|
||||||
|
orig[val] = None
|
||||||
self.scanner_map_delete(kw)
|
self.scanner_map_delete(kw)
|
||||||
|
|
||||||
def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
|
def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
|
||||||
|
@ -994,7 +1098,7 @@ class Base(SubstitutionEnvironment):
|
||||||
orig = self._dict[envname][name]
|
orig = self._dict[envname][name]
|
||||||
|
|
||||||
nv = SCons.Util.AppendPath(orig, newpath, sep)
|
nv = SCons.Util.AppendPath(orig, newpath, sep)
|
||||||
|
|
||||||
if not self._dict.has_key(envname):
|
if not self._dict.has_key(envname):
|
||||||
self._dict[envname] = {}
|
self._dict[envname] = {}
|
||||||
|
|
||||||
|
@ -1037,29 +1141,95 @@ class Base(SubstitutionEnvironment):
|
||||||
objects in the original Environment.
|
objects in the original Environment.
|
||||||
"""
|
"""
|
||||||
clone = copy.copy(self)
|
clone = copy.copy(self)
|
||||||
clone._dict = our_deepcopy(self._dict)
|
clone._dict = semi_deepcopy(self._dict)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cbd = clone._dict['BUILDERS']
|
cbd = clone._dict['BUILDERS']
|
||||||
clone._dict['BUILDERS'] = BuilderDict(cbd, clone)
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
clone._dict['BUILDERS'] = BuilderDict(cbd, clone)
|
||||||
|
|
||||||
|
clone.added_methods = []
|
||||||
|
for mw in self.added_methods:
|
||||||
|
clone.added_methods.append(mw.clone(clone))
|
||||||
|
|
||||||
clone._memo = {}
|
clone._memo = {}
|
||||||
|
|
||||||
apply_tools(clone, tools, toolpath)
|
# Apply passed-in variables before the tools
|
||||||
|
# so the tools can use the new variables
|
||||||
# Apply passed-in variables after the new tools.
|
|
||||||
kw = copy_non_reserved_keywords(kw)
|
kw = copy_non_reserved_keywords(kw)
|
||||||
new = {}
|
new = {}
|
||||||
for key, value in kw.items():
|
for key, value in kw.items():
|
||||||
new[key] = SCons.Subst.scons_subst_once(value, self, key)
|
new[key] = SCons.Subst.scons_subst_once(value, self, key)
|
||||||
apply(clone.Replace, (), new)
|
apply(clone.Replace, (), new)
|
||||||
|
|
||||||
|
apply_tools(clone, tools, toolpath)
|
||||||
|
|
||||||
|
# apply them again in case the tools overwrote them
|
||||||
|
apply(clone.Replace, (), new)
|
||||||
|
|
||||||
if __debug__: logInstanceCreation(self, 'Environment.EnvironmentClone')
|
if __debug__: logInstanceCreation(self, 'Environment.EnvironmentClone')
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
def Copy(self, *args, **kw):
|
def Copy(self, *args, **kw):
|
||||||
return apply(self.Clone, args, kw)
|
return apply(self.Clone, args, kw)
|
||||||
|
|
||||||
|
def _changed_build(self, dependency, target, prev_ni):
|
||||||
|
if dependency.changed_state(target, prev_ni):
|
||||||
|
return 1
|
||||||
|
return self.decide_source(dependency, target, prev_ni)
|
||||||
|
|
||||||
|
def _changed_content(self, dependency, target, prev_ni):
|
||||||
|
return dependency.changed_content(target, prev_ni)
|
||||||
|
|
||||||
|
def _changed_source(self, dependency, target, prev_ni):
|
||||||
|
target_env = dependency.get_build_env()
|
||||||
|
type = target_env.get_tgt_sig_type()
|
||||||
|
if type == 'source':
|
||||||
|
return target_env.decide_source(dependency, target, prev_ni)
|
||||||
|
else:
|
||||||
|
return target_env.decide_target(dependency, target, prev_ni)
|
||||||
|
|
||||||
|
def _changed_timestamp_then_content(self, dependency, target, prev_ni):
|
||||||
|
return dependency.changed_timestamp_then_content(target, prev_ni)
|
||||||
|
|
||||||
|
def _changed_timestamp_newer(self, dependency, target, prev_ni):
|
||||||
|
return dependency.changed_timestamp_newer(target, prev_ni)
|
||||||
|
|
||||||
|
def _changed_timestamp_match(self, dependency, target, prev_ni):
|
||||||
|
return dependency.changed_timestamp_match(target, prev_ni)
|
||||||
|
|
||||||
|
def _copy_from_cache(self, src, dst):
|
||||||
|
return self.fs.copy(src, dst)
|
||||||
|
|
||||||
|
def _copy2_from_cache(self, src, dst):
|
||||||
|
return self.fs.copy2(src, dst)
|
||||||
|
|
||||||
|
def Decider(self, function):
|
||||||
|
copy_function = self._copy2_from_cache
|
||||||
|
if function in ('MD5', 'content'):
|
||||||
|
if not SCons.Util.md5:
|
||||||
|
raise UserError, "MD5 signatures are not available in this version of Python."
|
||||||
|
function = self._changed_content
|
||||||
|
elif function == 'MD5-timestamp':
|
||||||
|
function = self._changed_timestamp_then_content
|
||||||
|
elif function in ('timestamp-newer', 'make'):
|
||||||
|
function = self._changed_timestamp_newer
|
||||||
|
copy_function = self._copy_from_cache
|
||||||
|
elif function == 'timestamp-match':
|
||||||
|
function = self._changed_timestamp_match
|
||||||
|
elif not callable(function):
|
||||||
|
raise UserError, "Unknown Decider value %s" % repr(function)
|
||||||
|
|
||||||
|
# We don't use AddMethod because we don't want to turn the
|
||||||
|
# function, which only expects three arguments, into a bound
|
||||||
|
# method, which would add self as an initial, fourth argument.
|
||||||
|
self.decide_target = function
|
||||||
|
self.decide_source = function
|
||||||
|
|
||||||
|
self.copy_from_cache = copy_function
|
||||||
|
|
||||||
def Detect(self, progs):
|
def Detect(self, progs):
|
||||||
"""Return the first available program in progs.
|
"""Return the first available program in progs.
|
||||||
"""
|
"""
|
||||||
|
@ -1110,7 +1280,7 @@ class Base(SubstitutionEnvironment):
|
||||||
|
|
||||||
for path in paths:
|
for path in paths:
|
||||||
dir,name = os.path.split(str(path))
|
dir,name = os.path.split(str(path))
|
||||||
if name[:len(prefix)] == prefix and name[-len(suffix):] == suffix:
|
if name[:len(prefix)] == prefix and name[-len(suffix):] == suffix:
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def ParseConfig(self, command, function=None, unique=1):
|
def ParseConfig(self, command, function=None, unique=1):
|
||||||
|
@ -1233,7 +1403,11 @@ class Base(SubstitutionEnvironment):
|
||||||
try:
|
try:
|
||||||
update_dict(val)
|
update_dict(val)
|
||||||
except (AttributeError, TypeError, ValueError):
|
except (AttributeError, TypeError, ValueError):
|
||||||
orig[val] = None
|
if SCons.Util.is_Dict(val):
|
||||||
|
for k, v in val.items():
|
||||||
|
orig[k] = v
|
||||||
|
else:
|
||||||
|
orig[val] = None
|
||||||
self.scanner_map_delete(kw)
|
self.scanner_map_delete(kw)
|
||||||
|
|
||||||
def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
|
def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
|
||||||
|
@ -1249,7 +1423,7 @@ class Base(SubstitutionEnvironment):
|
||||||
orig = self._dict[envname][name]
|
orig = self._dict[envname][name]
|
||||||
|
|
||||||
nv = SCons.Util.PrependPath(orig, newpath, sep)
|
nv = SCons.Util.PrependPath(orig, newpath, sep)
|
||||||
|
|
||||||
if not self._dict.has_key(envname):
|
if not self._dict.has_key(envname):
|
||||||
self._dict[envname] = {}
|
self._dict[envname] = {}
|
||||||
|
|
||||||
|
@ -1288,13 +1462,15 @@ class Base(SubstitutionEnvironment):
|
||||||
with new construction variables and/or values.
|
with new construction variables and/or values.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
kwbd = our_deepcopy(kw['BUILDERS'])
|
kwbd = kw['BUILDERS']
|
||||||
del kw['BUILDERS']
|
|
||||||
self.__setitem__('BUILDERS', kwbd)
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
kwbd = semi_deepcopy(kwbd)
|
||||||
|
del kw['BUILDERS']
|
||||||
|
self.__setitem__('BUILDERS', kwbd)
|
||||||
kw = copy_non_reserved_keywords(kw)
|
kw = copy_non_reserved_keywords(kw)
|
||||||
self._update(our_deepcopy(kw))
|
self._update(semi_deepcopy(kw))
|
||||||
self.scanner_map_delete(kw)
|
self.scanner_map_delete(kw)
|
||||||
|
|
||||||
def ReplaceIxes(self, path, old_prefix, old_suffix, new_prefix, new_suffix):
|
def ReplaceIxes(self, path, old_prefix, old_suffix, new_prefix, new_suffix):
|
||||||
|
@ -1453,7 +1629,7 @@ class Base(SubstitutionEnvironment):
|
||||||
def AlwaysBuild(self, *targets):
|
def AlwaysBuild(self, *targets):
|
||||||
tlist = []
|
tlist = []
|
||||||
for t in targets:
|
for t in targets:
|
||||||
tlist.extend(self.arg2nodes(t, self.fs.File))
|
tlist.extend(self.arg2nodes(t, self.fs.Entry))
|
||||||
for t in tlist:
|
for t in tlist:
|
||||||
t.set_always_build()
|
t.set_always_build()
|
||||||
return tlist
|
return tlist
|
||||||
|
@ -1468,7 +1644,11 @@ class Base(SubstitutionEnvironment):
|
||||||
return apply(SCons.Builder.Builder, [], nkw)
|
return apply(SCons.Builder.Builder, [], nkw)
|
||||||
|
|
||||||
def CacheDir(self, path):
|
def CacheDir(self, path):
|
||||||
self.fs.CacheDir(self.subst(path))
|
import SCons.CacheDir
|
||||||
|
if path is None:
|
||||||
|
self._CacheDir = SCons.CacheDir.Null()
|
||||||
|
else:
|
||||||
|
self._CacheDir = SCons.CacheDir.CacheDir(self.subst(path))
|
||||||
|
|
||||||
def Clean(self, targets, files):
|
def Clean(self, targets, files):
|
||||||
global CleanTargets
|
global CleanTargets
|
||||||
|
@ -1551,7 +1731,11 @@ class Base(SubstitutionEnvironment):
|
||||||
"""Directly execute an action through an Environment
|
"""Directly execute an action through an Environment
|
||||||
"""
|
"""
|
||||||
action = apply(self.Action, (action,) + args, kw)
|
action = apply(self.Action, (action,) + args, kw)
|
||||||
return action([], [], self)
|
result = action([], [], self)
|
||||||
|
if isinstance(result, SCons.Errors.BuildError):
|
||||||
|
return result.status
|
||||||
|
else:
|
||||||
|
return result
|
||||||
|
|
||||||
def File(self, name, *args, **kw):
|
def File(self, name, *args, **kw):
|
||||||
"""
|
"""
|
||||||
|
@ -1573,6 +1757,9 @@ class Base(SubstitutionEnvironment):
|
||||||
else:
|
else:
|
||||||
return result[0]
|
return result[0]
|
||||||
|
|
||||||
|
def Glob(self, pattern, ondisk=True, source=False, strings=False):
|
||||||
|
return self.fs.Glob(self.subst(pattern), ondisk, source, strings)
|
||||||
|
|
||||||
def Ignore(self, target, dependency):
|
def Ignore(self, target, dependency):
|
||||||
"""Ignore a dependency."""
|
"""Ignore a dependency."""
|
||||||
tlist = self.arg2nodes(target, self.fs.Entry)
|
tlist = self.arg2nodes(target, self.fs.Entry)
|
||||||
|
@ -1581,50 +1768,6 @@ class Base(SubstitutionEnvironment):
|
||||||
t.add_ignore(dlist)
|
t.add_ignore(dlist)
|
||||||
return tlist
|
return tlist
|
||||||
|
|
||||||
def Install(self, dir, source):
|
|
||||||
"""Install specified files in the given directory."""
|
|
||||||
try:
|
|
||||||
dnodes = self.arg2nodes(dir, self.fs.Dir)
|
|
||||||
except TypeError:
|
|
||||||
fmt = "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?"
|
|
||||||
raise SCons.Errors.UserError, fmt % str(dir)
|
|
||||||
try:
|
|
||||||
sources = self.arg2nodes(source, self.fs.Entry)
|
|
||||||
except TypeError:
|
|
||||||
if SCons.Util.is_List(source):
|
|
||||||
s = repr(map(str, source))
|
|
||||||
else:
|
|
||||||
s = str(source)
|
|
||||||
fmt = "Source `%s' of Install() is neither a file nor a directory. Install() source must be one or more files or directories"
|
|
||||||
raise SCons.Errors.UserError, fmt % s
|
|
||||||
tgt = []
|
|
||||||
for dnode in dnodes:
|
|
||||||
for src in sources:
|
|
||||||
# Prepend './' so the lookup doesn't interpret an initial
|
|
||||||
# '#' on the file name portion as meaning the Node should
|
|
||||||
# be relative to the top-level SConstruct directory.
|
|
||||||
target = self.fs.Entry('.'+os.sep+src.name, dnode)
|
|
||||||
tgt.extend(InstallBuilder(self, target, src))
|
|
||||||
return tgt
|
|
||||||
|
|
||||||
def InstallAs(self, target, source):
|
|
||||||
"""Install sources as targets."""
|
|
||||||
sources = self.arg2nodes(source, self.fs.Entry)
|
|
||||||
targets = self.arg2nodes(target, self.fs.Entry)
|
|
||||||
if len(sources) != len(targets):
|
|
||||||
if not SCons.Util.is_List(target):
|
|
||||||
target = [target]
|
|
||||||
if not SCons.Util.is_List(source):
|
|
||||||
source = [source]
|
|
||||||
t = repr(map(str, target))
|
|
||||||
s = repr(map(str, source))
|
|
||||||
fmt = "Target (%s) and source (%s) lists of InstallAs() must be the same length."
|
|
||||||
raise SCons.Errors.UserError, fmt % (t, s)
|
|
||||||
result = []
|
|
||||||
for src, tgt in map(lambda x, y: (x, y), sources, targets):
|
|
||||||
result.extend(InstallBuilder(self, tgt, src))
|
|
||||||
return result
|
|
||||||
|
|
||||||
def Literal(self, string):
|
def Literal(self, string):
|
||||||
return SCons.Subst.Literal(string)
|
return SCons.Subst.Literal(string)
|
||||||
|
|
||||||
|
@ -1652,6 +1795,16 @@ class Base(SubstitutionEnvironment):
|
||||||
dirs = self.arg2nodes(list(dirs), self.fs.Dir)
|
dirs = self.arg2nodes(list(dirs), self.fs.Dir)
|
||||||
apply(self.fs.Repository, dirs, kw)
|
apply(self.fs.Repository, dirs, kw)
|
||||||
|
|
||||||
|
def Requires(self, target, prerequisite):
|
||||||
|
"""Specify that 'prerequisite' must be built before 'target',
|
||||||
|
(but 'target' does not actually depend on 'prerequisite'
|
||||||
|
and need not be rebuilt if it changes)."""
|
||||||
|
tlist = self.arg2nodes(target, self.fs.Entry)
|
||||||
|
plist = self.arg2nodes(prerequisite, self.fs.Entry)
|
||||||
|
for t in tlist:
|
||||||
|
t.add_prerequisite(plist)
|
||||||
|
return tlist
|
||||||
|
|
||||||
def Scanner(self, *args, **kw):
|
def Scanner(self, *args, **kw):
|
||||||
nargs = []
|
nargs = []
|
||||||
for arg in args:
|
for arg in args:
|
||||||
|
@ -1669,7 +1822,7 @@ class Base(SubstitutionEnvironment):
|
||||||
SCons.SConsign.File(name, dbm_module)
|
SCons.SConsign.File(name, dbm_module)
|
||||||
|
|
||||||
def SideEffect(self, side_effect, target):
|
def SideEffect(self, side_effect, target):
|
||||||
"""Tell scons that side_effects are built as side
|
"""Tell scons that side_effects are built as side
|
||||||
effects of building targets."""
|
effects of building targets."""
|
||||||
side_effects = self.arg2nodes(side_effect, self.fs.Entry)
|
side_effects = self.arg2nodes(side_effect, self.fs.Entry)
|
||||||
targets = self.arg2nodes(target, self.fs.Entry)
|
targets = self.arg2nodes(target, self.fs.Entry)
|
||||||
|
@ -1693,21 +1846,15 @@ class Base(SubstitutionEnvironment):
|
||||||
|
|
||||||
def SourceSignatures(self, type):
|
def SourceSignatures(self, type):
|
||||||
type = self.subst(type)
|
type = self.subst(type)
|
||||||
|
self.src_sig_type = type
|
||||||
if type == 'MD5':
|
if type == 'MD5':
|
||||||
try:
|
if not SCons.Util.md5:
|
||||||
import SCons.Sig.MD5
|
raise UserError, "MD5 signatures are not available in this version of Python."
|
||||||
except ImportError:
|
self.decide_source = self._changed_content
|
||||||
msg = "No MD5 module available, using time stamps"
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg)
|
|
||||||
import SCons.Sig.TimeStamp
|
|
||||||
self._calc_module = SCons.Sig.TimeStamp
|
|
||||||
else:
|
|
||||||
self._calc_module = SCons.Sig.MD5
|
|
||||||
elif type == 'timestamp':
|
elif type == 'timestamp':
|
||||||
import SCons.Sig.TimeStamp
|
self.decide_source = self._changed_timestamp_match
|
||||||
self._calc_module = SCons.Sig.TimeStamp
|
|
||||||
else:
|
else:
|
||||||
raise UserError, "Unknown source signature type '%s'"%type
|
raise UserError, "Unknown source signature type '%s'" % type
|
||||||
|
|
||||||
def Split(self, arg):
|
def Split(self, arg):
|
||||||
"""This function converts a string or list into a list of strings
|
"""This function converts a string or list into a list of strings
|
||||||
|
@ -1729,18 +1876,66 @@ class Base(SubstitutionEnvironment):
|
||||||
|
|
||||||
def TargetSignatures(self, type):
|
def TargetSignatures(self, type):
|
||||||
type = self.subst(type)
|
type = self.subst(type)
|
||||||
if type == 'build':
|
self.tgt_sig_type = type
|
||||||
self._build_signature = 1
|
if type in ('MD5', 'content'):
|
||||||
elif type == 'content':
|
if not SCons.Util.md5:
|
||||||
self._build_signature = 0
|
raise UserError, "MD5 signatures are not available in this version of Python."
|
||||||
|
self.decide_target = self._changed_content
|
||||||
|
elif type == 'timestamp':
|
||||||
|
self.decide_target = self._changed_timestamp_match
|
||||||
|
elif type == 'build':
|
||||||
|
self.decide_target = self._changed_build
|
||||||
|
elif type == 'source':
|
||||||
|
self.decide_target = self._changed_source
|
||||||
else:
|
else:
|
||||||
raise SCons.Errors.UserError, "Unknown target signature type '%s'"%type
|
raise UserError, "Unknown target signature type '%s'"%type
|
||||||
|
|
||||||
def Value(self, value, built_value=None):
|
def Value(self, value, built_value=None):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
return SCons.Node.Python.Value(value, built_value)
|
return SCons.Node.Python.Value(value, built_value)
|
||||||
|
|
||||||
|
def FindSourceFiles(self, node='.'):
|
||||||
|
""" returns a list of all source files.
|
||||||
|
"""
|
||||||
|
node = self.arg2nodes(node, self.fs.Entry)[0]
|
||||||
|
|
||||||
|
sources = []
|
||||||
|
# Uncomment this and get rid of the global definition when we
|
||||||
|
# drop support for pre-2.2 Python versions.
|
||||||
|
#def build_source(ss, result):
|
||||||
|
# for s in ss:
|
||||||
|
# if isinstance(s, SCons.Node.FS.Dir):
|
||||||
|
# build_source(s.all_children(), result)
|
||||||
|
# elif s.has_builder():
|
||||||
|
# build_source(s.sources, result)
|
||||||
|
# elif isinstance(s.disambiguate(), SCons.Node.FS.File):
|
||||||
|
# result.append(s)
|
||||||
|
build_source(node.all_children(), sources)
|
||||||
|
|
||||||
|
# now strip the build_node from the sources by calling the srcnode
|
||||||
|
# function
|
||||||
|
def get_final_srcnode(file):
|
||||||
|
srcnode = file.srcnode()
|
||||||
|
while srcnode != file.srcnode():
|
||||||
|
srcnode = file.srcnode()
|
||||||
|
return srcnode
|
||||||
|
|
||||||
|
# get the final srcnode for all nodes, this means stripping any
|
||||||
|
# attached build node.
|
||||||
|
map( get_final_srcnode, sources )
|
||||||
|
|
||||||
|
# remove duplicates
|
||||||
|
return list(set(sources))
|
||||||
|
|
||||||
|
def FindInstalledFiles(self):
|
||||||
|
""" returns the list of all targets of the Install and InstallAs Builder.
|
||||||
|
"""
|
||||||
|
from SCons.Tool import install
|
||||||
|
if install._UNIQUE_INSTALLED_FILES is None:
|
||||||
|
install._UNIQUE_INSTALLED_FILES = SCons.Util.uniquer_hashables(install._INSTALLED_FILES)
|
||||||
|
return install._UNIQUE_INSTALLED_FILES
|
||||||
|
|
||||||
class OverrideEnvironment(Base):
|
class OverrideEnvironment(Base):
|
||||||
"""A proxy that overrides variables in a wrapped construction
|
"""A proxy that overrides variables in a wrapped construction
|
||||||
environment by returning values from an overrides dictionary in
|
environment by returning values from an overrides dictionary in
|
||||||
|
@ -1839,7 +2034,7 @@ class OverrideEnvironment(Base):
|
||||||
# Overridden public construction environment methods.
|
# Overridden public construction environment methods.
|
||||||
def Replace(self, **kw):
|
def Replace(self, **kw):
|
||||||
kw = copy_non_reserved_keywords(kw)
|
kw = copy_non_reserved_keywords(kw)
|
||||||
self.__dict__['overrides'].update(our_deepcopy(kw))
|
self.__dict__['overrides'].update(semi_deepcopy(kw))
|
||||||
|
|
||||||
# The entry point that will be used by the external world
|
# The entry point that will be used by the external world
|
||||||
# to refer to a construction environment. This allows the wrapper
|
# to refer to a construction environment. This allows the wrapper
|
|
@ -28,15 +28,21 @@ and user errors in SCons.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Errors.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Errors.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BuildError(Exception):
|
class BuildError(Exception):
|
||||||
def __init__(self, node=None, errstr="Unknown error", filename=None, *args):
|
def __init__(self, node=None, errstr="Unknown error", status=0,
|
||||||
|
filename=None, executor=None, action=None, command=None,
|
||||||
|
*args):
|
||||||
self.node = node
|
self.node = node
|
||||||
self.errstr = errstr
|
self.errstr = errstr
|
||||||
|
self.status = status
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
self.executor = executor
|
||||||
|
self.action = action
|
||||||
|
self.command = command
|
||||||
apply(Exception.__init__, (self,) + args)
|
apply(Exception.__init__, (self,) + args)
|
||||||
|
|
||||||
class InternalError(Exception):
|
class InternalError(Exception):
|
||||||
|
@ -48,6 +54,9 @@ class UserError(Exception):
|
||||||
class StopError(Exception):
|
class StopError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class EnvironmentError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
class ExplicitExit(Exception):
|
class ExplicitExit(Exception):
|
||||||
def __init__(self, node=None, status=None, *args):
|
def __init__(self, node=None, status=None, *args):
|
||||||
self.node = node
|
self.node = node
|
|
@ -28,11 +28,12 @@ Nodes.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Executor.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Executor.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
||||||
from SCons.Debug import logInstanceCreation
|
from SCons.Debug import logInstanceCreation
|
||||||
|
import SCons.Errors
|
||||||
import SCons.Memoize
|
import SCons.Memoize
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ class Executor:
|
||||||
self.overridelist = overridelist
|
self.overridelist = overridelist
|
||||||
self.targets = targets
|
self.targets = targets
|
||||||
self.sources = sources[:]
|
self.sources = sources[:]
|
||||||
|
self.sources_need_sorting = False
|
||||||
self.builder_kw = builder_kw
|
self.builder_kw = builder_kw
|
||||||
self._memo = {}
|
self._memo = {}
|
||||||
|
|
||||||
|
@ -74,10 +76,17 @@ class Executor:
|
||||||
def get_action_list(self):
|
def get_action_list(self):
|
||||||
return self.pre_actions + self.action_list + self.post_actions
|
return self.pre_actions + self.action_list + self.post_actions
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountValue('get_build_env'))
|
||||||
|
|
||||||
def get_build_env(self):
|
def get_build_env(self):
|
||||||
"""Fetch or create the appropriate build Environment
|
"""Fetch or create the appropriate build Environment
|
||||||
for this Executor.
|
for this Executor.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
return self._memo['get_build_env']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Create the build environment instance with appropriate
|
# Create the build environment instance with appropriate
|
||||||
# overrides. These get evaluated against the current
|
# overrides. These get evaluated against the current
|
||||||
# environment's construction variables so that users can
|
# environment's construction variables so that users can
|
||||||
|
@ -91,42 +100,49 @@ class Executor:
|
||||||
env = self.env or SCons.Defaults.DefaultEnvironment()
|
env = self.env or SCons.Defaults.DefaultEnvironment()
|
||||||
build_env = env.Override(overrides)
|
build_env = env.Override(overrides)
|
||||||
|
|
||||||
|
self._memo['get_build_env'] = build_env
|
||||||
|
|
||||||
return build_env
|
return build_env
|
||||||
|
|
||||||
def get_build_scanner_path(self, scanner):
|
def get_build_scanner_path(self, scanner):
|
||||||
"""Fetch the scanner path for this executor's targets
|
"""Fetch the scanner path for this executor's targets and sources.
|
||||||
and sources.
|
|
||||||
"""
|
"""
|
||||||
env = self.get_build_env()
|
env = self.get_build_env()
|
||||||
try:
|
try:
|
||||||
cwd = self.targets[0].cwd
|
cwd = self.targets[0].cwd
|
||||||
except (IndexError, AttributeError):
|
except (IndexError, AttributeError):
|
||||||
cwd = None
|
cwd = None
|
||||||
return scanner.path(env, cwd, self.targets, self.sources)
|
return scanner.path(env, cwd, self.targets, self.get_sources())
|
||||||
|
|
||||||
def get_kw(self, kw={}):
|
def get_kw(self, kw={}):
|
||||||
result = self.builder_kw.copy()
|
result = self.builder_kw.copy()
|
||||||
result.update(kw)
|
result.update(kw)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def do_nothing(self, target, exitstatfunc, kw):
|
def do_nothing(self, target, kw):
|
||||||
pass
|
return 0
|
||||||
|
|
||||||
def do_execute(self, target, exitstatfunc, kw):
|
def do_execute(self, target, kw):
|
||||||
"""Actually execute the action list."""
|
"""Actually execute the action list."""
|
||||||
env = self.get_build_env()
|
env = self.get_build_env()
|
||||||
kw = self.get_kw(kw)
|
kw = self.get_kw(kw)
|
||||||
|
status = 0
|
||||||
for act in self.get_action_list():
|
for act in self.get_action_list():
|
||||||
apply(act,
|
status = apply(act, (self.targets, self.get_sources(), env), kw)
|
||||||
(self.targets, self.sources, env, exitstatfunc),
|
if isinstance(status, SCons.Errors.BuildError):
|
||||||
kw)
|
status.executor = self
|
||||||
|
raise status
|
||||||
|
elif status:
|
||||||
|
msg = "Error %s" % status
|
||||||
|
raise SCons.Errors.BuildError(errstr=msg, executor=self, action=act)
|
||||||
|
return status
|
||||||
|
|
||||||
# use extra indirection because with new-style objects (Python 2.2
|
# use extra indirection because with new-style objects (Python 2.2
|
||||||
# and above) we can't override special methods, and nullify() needs
|
# and above) we can't override special methods, and nullify() needs
|
||||||
# to be able to do this.
|
# to be able to do this.
|
||||||
|
|
||||||
def __call__(self, target, exitstatfunc, **kw):
|
def __call__(self, target, **kw):
|
||||||
self.do_execute(target, exitstatfunc, kw)
|
return self.do_execute(target, kw)
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
self._memo = {}
|
self._memo = {}
|
||||||
|
@ -135,8 +151,14 @@ class Executor:
|
||||||
"""Add source files to this Executor's list. This is necessary
|
"""Add source files to this Executor's list. This is necessary
|
||||||
for "multi" Builders that can be called repeatedly to build up
|
for "multi" Builders that can be called repeatedly to build up
|
||||||
a source file list for a given target."""
|
a source file list for a given target."""
|
||||||
slist = filter(lambda x, s=self.sources: x not in s, sources)
|
self.sources.extend(sources)
|
||||||
self.sources.extend(slist)
|
self.sources_need_sorting = True
|
||||||
|
|
||||||
|
def get_sources(self):
|
||||||
|
if self.sources_need_sorting:
|
||||||
|
self.sources = SCons.Util.uniquer_hashables(self.sources)
|
||||||
|
self.sources_need_sorting = False
|
||||||
|
return self.sources
|
||||||
|
|
||||||
def add_pre_action(self, action):
|
def add_pre_action(self, action):
|
||||||
self.pre_actions.append(action)
|
self.pre_actions.append(action)
|
||||||
|
@ -148,7 +170,7 @@ class Executor:
|
||||||
|
|
||||||
def my_str(self):
|
def my_str(self):
|
||||||
env = self.get_build_env()
|
env = self.get_build_env()
|
||||||
get = lambda action, t=self.targets, s=self.sources, e=env: \
|
get = lambda action, t=self.targets, s=self.get_sources(), e=env: \
|
||||||
action.genstring(t, s, e)
|
action.genstring(t, s, e)
|
||||||
return string.join(map(get, self.get_action_list()), "\n")
|
return string.join(map(get, self.get_action_list()), "\n")
|
||||||
|
|
||||||
|
@ -173,7 +195,7 @@ class Executor:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
env = self.get_build_env()
|
env = self.get_build_env()
|
||||||
get = lambda action, t=self.targets, s=self.sources, e=env: \
|
get = lambda action, t=self.targets, s=self.get_sources(), e=env: \
|
||||||
action.get_contents(t, s, e)
|
action.get_contents(t, s, e)
|
||||||
result = string.join(map(get, self.get_action_list()), "")
|
result = string.join(map(get, self.get_action_list()), "")
|
||||||
self._memo['get_contents'] = result
|
self._memo['get_contents'] = result
|
||||||
|
@ -191,7 +213,7 @@ class Executor:
|
||||||
|
|
||||||
def scan_sources(self, scanner):
|
def scan_sources(self, scanner):
|
||||||
if self.sources:
|
if self.sources:
|
||||||
self.scan(scanner, self.sources)
|
self.scan(scanner, self.get_sources())
|
||||||
|
|
||||||
def scan(self, scanner, node_list):
|
def scan(self, scanner, node_list):
|
||||||
"""Scan a list of this Executor's files (targets or sources) for
|
"""Scan a list of this Executor's files (targets or sources) for
|
||||||
|
@ -218,17 +240,20 @@ class Executor:
|
||||||
scanner_list = map(select_specific_scanner, scanner_list)
|
scanner_list = map(select_specific_scanner, scanner_list)
|
||||||
scanner_list = filter(remove_null_scanners, scanner_list)
|
scanner_list = filter(remove_null_scanners, scanner_list)
|
||||||
scanner_path_list = map(add_scanner_path, scanner_list)
|
scanner_path_list = map(add_scanner_path, scanner_list)
|
||||||
|
|
||||||
deps = []
|
deps = []
|
||||||
for node, scanner, path in scanner_path_list:
|
for node, scanner, path in scanner_path_list:
|
||||||
deps.extend(node.get_implicit_deps(env, scanner, path))
|
deps.extend(node.get_implicit_deps(env, scanner, path))
|
||||||
|
|
||||||
|
deps.extend(self.get_implicit_deps())
|
||||||
|
|
||||||
for tgt in self.targets:
|
for tgt in self.targets:
|
||||||
tgt.add_to_implicit(deps)
|
tgt.add_to_implicit(deps)
|
||||||
|
|
||||||
def get_missing_sources(self):
|
def get_missing_sources(self):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
return filter(lambda s: s.missing(), self.sources)
|
return filter(lambda s: s.missing(), self.get_sources())
|
||||||
|
|
||||||
def _get_unignored_sources_key(self, ignore=()):
|
def _get_unignored_sources_key(self, ignore=()):
|
||||||
return tuple(ignore)
|
return tuple(ignore)
|
||||||
|
@ -248,9 +273,12 @@ class Executor:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
sourcelist = self.sources
|
sourcelist = self.get_sources()
|
||||||
if ignore:
|
if ignore:
|
||||||
sourcelist = filter(lambda s, i=ignore: not s in i, sourcelist)
|
idict = {}
|
||||||
|
for i in ignore:
|
||||||
|
idict[i] = 1
|
||||||
|
sourcelist = filter(lambda s, i=idict: not i.has_key(s), sourcelist)
|
||||||
|
|
||||||
memo_dict[ignore] = sourcelist
|
memo_dict[ignore] = sourcelist
|
||||||
|
|
||||||
|
@ -280,6 +308,15 @@ class Executor:
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_implicit_deps(self):
|
||||||
|
"""Return the executor's implicit dependencies, i.e. the nodes of
|
||||||
|
the commands to be executed."""
|
||||||
|
result = []
|
||||||
|
build_env = self.get_build_env()
|
||||||
|
for act in self.get_action_list():
|
||||||
|
result.extend(act.get_implicit_deps(self.targets, self.get_sources(), build_env))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
_Executor = Executor
|
_Executor = Executor
|
||||||
|
|
||||||
|
@ -296,9 +333,15 @@ class Null(_Executor):
|
||||||
kw['action'] = []
|
kw['action'] = []
|
||||||
apply(_Executor.__init__, (self,), kw)
|
apply(_Executor.__init__, (self,), kw)
|
||||||
def get_build_env(self):
|
def get_build_env(self):
|
||||||
class NullEnvironment:
|
import SCons.Util
|
||||||
def get_scanner(self, key):
|
class NullEnvironment(SCons.Util.Null):
|
||||||
return None
|
#def get_scanner(self, key):
|
||||||
|
# return None
|
||||||
|
#def changed_since_last_build(self, dependency, target, prev_ni):
|
||||||
|
# return dependency.changed_since_last_buld(target, prev_ni)
|
||||||
|
def get_CacheDir(self):
|
||||||
|
import SCons.CacheDir
|
||||||
|
return SCons.CacheDir.Null()
|
||||||
return NullEnvironment()
|
return NullEnvironment()
|
||||||
def get_build_scanner_path(self):
|
def get_build_scanner_path(self):
|
||||||
return None
|
return None
|
|
@ -29,7 +29,7 @@ stop, and wait on jobs.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Job.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Job.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
|
@ -76,6 +76,9 @@ class Jobs:
|
||||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
self.job.cleanup()
|
||||||
|
|
||||||
class Serial:
|
class Serial:
|
||||||
"""This class is used to execute tasks in series, and is more efficient
|
"""This class is used to execute tasks in series, and is more efficient
|
||||||
than Parallel, but is only appropriate for non-parallel builds. Only
|
than Parallel, but is only appropriate for non-parallel builds. Only
|
||||||
|
@ -122,6 +125,8 @@ class Serial:
|
||||||
|
|
||||||
task.postprocess()
|
task.postprocess()
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
pass
|
||||||
|
|
||||||
# Trap import failure so that everything in the Job module but the
|
# Trap import failure so that everything in the Job module but the
|
||||||
# Parallel class (and its dependent classes) will work if the interpreter
|
# Parallel class (and its dependent classes) will work if the interpreter
|
||||||
|
@ -148,6 +153,12 @@ else:
|
||||||
while 1:
|
while 1:
|
||||||
task = self.requestQueue.get()
|
task = self.requestQueue.get()
|
||||||
|
|
||||||
|
if not task:
|
||||||
|
# The "None" value is used as a sentinel by
|
||||||
|
# ThreadPool.cleanup(). This indicates that there
|
||||||
|
# are no more tasks, so we should quit.
|
||||||
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
task.execute()
|
task.execute()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -170,8 +181,10 @@ else:
|
||||||
self.resultsQueue = Queue.Queue(0)
|
self.resultsQueue = Queue.Queue(0)
|
||||||
|
|
||||||
# Create worker threads
|
# Create worker threads
|
||||||
|
self.workers = []
|
||||||
for _ in range(num):
|
for _ in range(num):
|
||||||
Worker(self.requestQueue, self.resultsQueue)
|
worker = Worker(self.requestQueue, self.resultsQueue)
|
||||||
|
self.workers.append(worker)
|
||||||
|
|
||||||
def put(self, obj):
|
def put(self, obj):
|
||||||
"""Put task into request queue."""
|
"""Put task into request queue."""
|
||||||
|
@ -182,7 +195,36 @@ else:
|
||||||
return self.resultsQueue.get(block)
|
return self.resultsQueue.get(block)
|
||||||
|
|
||||||
def preparation_failed(self, obj):
|
def preparation_failed(self, obj):
|
||||||
self.resultsQueue.put((obj, 0))
|
self.resultsQueue.put((obj, False))
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
"""
|
||||||
|
Shuts down the thread pool, giving each worker thread a
|
||||||
|
chance to shut down gracefully.
|
||||||
|
"""
|
||||||
|
# For each worker thread, put a sentinel "None" value
|
||||||
|
# on the requestQueue (indicating that there's no work
|
||||||
|
# to be done) so that each worker thread will get one and
|
||||||
|
# terminate gracefully.
|
||||||
|
for _ in self.workers:
|
||||||
|
self.requestQueue.put(None)
|
||||||
|
|
||||||
|
# Wait for all of the workers to terminate.
|
||||||
|
#
|
||||||
|
# If we don't do this, later Python versions (2.4, 2.5) often
|
||||||
|
# seem to raise exceptions during shutdown. This happens
|
||||||
|
# in requestQueue.get(), as an assertion failure that
|
||||||
|
# requestQueue.not_full is notified while not acquired,
|
||||||
|
# seemingly because the main thread has shut down (or is
|
||||||
|
# in the process of doing so) while the workers are still
|
||||||
|
# trying to pull sentinels off the requestQueue.
|
||||||
|
#
|
||||||
|
# Normally these terminations should happen fairly quickly,
|
||||||
|
# but we'll stick a one-second timeout on here just in case
|
||||||
|
# someone gets hung.
|
||||||
|
for worker in self.workers:
|
||||||
|
worker.join(1.0)
|
||||||
|
self.workers = []
|
||||||
|
|
||||||
class Parallel:
|
class Parallel:
|
||||||
"""This class is used to execute tasks in parallel, and is somewhat
|
"""This class is used to execute tasks in parallel, and is somewhat
|
||||||
|
@ -261,3 +303,6 @@ else:
|
||||||
|
|
||||||
if self.tp.resultsQueue.empty():
|
if self.tp.resultsQueue.empty():
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
self.tp.cleanup()
|
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Memoize.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Memoize.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
__doc__ = """Memoizer
|
__doc__ = """Memoizer
|
||||||
|
|
|
@ -30,7 +30,7 @@ This creates a hash of global Aliases (dummy targets).
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Node/Alias.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Node/Alias.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import string
|
import string
|
||||||
import UserDict
|
import UserDict
|
||||||
|
@ -57,10 +57,13 @@ class AliasNameSpace(UserDict.UserDict):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class AliasNodeInfo(SCons.Node.NodeInfoBase):
|
class AliasNodeInfo(SCons.Node.NodeInfoBase):
|
||||||
pass
|
current_version_id = 1
|
||||||
|
field_list = ['csig']
|
||||||
|
def str_to_node(self, s):
|
||||||
|
return default_ans.Alias(s)
|
||||||
|
|
||||||
class AliasBuildInfo(SCons.Node.BuildInfoBase):
|
class AliasBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
pass
|
current_version_id = 1
|
||||||
|
|
||||||
class Alias(SCons.Node.Node):
|
class Alias(SCons.Node.Node):
|
||||||
|
|
||||||
|
@ -74,8 +77,11 @@ class Alias(SCons.Node.Node):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def make_ready(self):
|
||||||
|
self.get_csig()
|
||||||
|
|
||||||
really_build = SCons.Node.Node.build
|
really_build = SCons.Node.Node.build
|
||||||
current = SCons.Node.Node.children_are_up_to_date
|
is_up_to_date = SCons.Node.Node.children_are_up_to_date
|
||||||
|
|
||||||
def is_under(self, dir):
|
def is_under(self, dir):
|
||||||
# Make Alias nodes get built regardless of
|
# Make Alias nodes get built regardless of
|
||||||
|
@ -85,9 +91,9 @@ class Alias(SCons.Node.Node):
|
||||||
|
|
||||||
def get_contents(self):
|
def get_contents(self):
|
||||||
"""The contents of an alias is the concatenation
|
"""The contents of an alias is the concatenation
|
||||||
of all the contents of its sources"""
|
of the content signatures of all its sources."""
|
||||||
contents = map(lambda n: n.get_contents(), self.children())
|
childsigs = map(lambda n: n.get_csig(), self.children())
|
||||||
return string.join(contents, '')
|
return string.join(childsigs, '')
|
||||||
|
|
||||||
def sconsign(self):
|
def sconsign(self):
|
||||||
"""An Alias is not recorded in .sconsign files"""
|
"""An Alias is not recorded in .sconsign files"""
|
||||||
|
@ -97,6 +103,13 @@ class Alias(SCons.Node.Node):
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
def changed_since_last_build(self, target, prev_ni):
|
||||||
|
cur_csig = self.get_csig()
|
||||||
|
try:
|
||||||
|
return cur_csig != prev_ni.csig
|
||||||
|
except AttributeError:
|
||||||
|
return 1
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
"""A "builder" for aliases."""
|
"""A "builder" for aliases."""
|
||||||
pass
|
pass
|
||||||
|
@ -107,6 +120,25 @@ class Alias(SCons.Node.Node):
|
||||||
self.reset_executor()
|
self.reset_executor()
|
||||||
self.build = self.really_build
|
self.build = self.really_build
|
||||||
|
|
||||||
|
def get_csig(self):
|
||||||
|
"""
|
||||||
|
Generate a node's content signature, the digested signature
|
||||||
|
of its content.
|
||||||
|
|
||||||
|
node - the node
|
||||||
|
cache - alternate node to use for the signature cache
|
||||||
|
returns - the content signature
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self.ninfo.csig
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
contents = self.get_contents()
|
||||||
|
csig = SCons.Util.MD5signature(contents)
|
||||||
|
self.get_ninfo().csig = csig
|
||||||
|
return csig
|
||||||
|
|
||||||
default_ans = AliasNameSpace()
|
default_ans = AliasNameSpace()
|
||||||
|
|
||||||
SCons.Node.arg2nodes_lookups.append(default_ans.lookup)
|
SCons.Node.arg2nodes_lookups.append(default_ans.lookup)
|
File diff suppressed because it is too large
Load diff
|
@ -27,15 +27,20 @@ Python nodes.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Node/Python.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Node/Python.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Node
|
import SCons.Node
|
||||||
|
|
||||||
class ValueNodeInfo(SCons.Node.NodeInfoBase):
|
class ValueNodeInfo(SCons.Node.NodeInfoBase):
|
||||||
pass
|
current_version_id = 1
|
||||||
|
|
||||||
|
field_list = ['csig']
|
||||||
|
|
||||||
|
def str_to_node(self, s):
|
||||||
|
return Value(s)
|
||||||
|
|
||||||
class ValueBuildInfo(SCons.Node.BuildInfoBase):
|
class ValueBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
pass
|
current_version_id = 1
|
||||||
|
|
||||||
class Value(SCons.Node.Node):
|
class Value(SCons.Node.Node):
|
||||||
"""A class for Python variables, typically passed on the command line
|
"""A class for Python variables, typically passed on the command line
|
||||||
|
@ -54,11 +59,14 @@ class Value(SCons.Node.Node):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
|
def make_ready(self):
|
||||||
|
self.get_csig()
|
||||||
|
|
||||||
def build(self, **kw):
|
def build(self, **kw):
|
||||||
if not hasattr(self, 'built_value'):
|
if not hasattr(self, 'built_value'):
|
||||||
apply (SCons.Node.Node.build, (self,), kw)
|
apply (SCons.Node.Node.build, (self,), kw)
|
||||||
|
|
||||||
current = SCons.Node.Node.children_are_up_to_date
|
is_up_to_date = SCons.Node.Node.children_are_up_to_date
|
||||||
|
|
||||||
def is_under(self, dir):
|
def is_under(self, dir):
|
||||||
# Make Value nodes get built regardless of
|
# Make Value nodes get built regardless of
|
||||||
|
@ -88,17 +96,21 @@ class Value(SCons.Node.Node):
|
||||||
contents = contents + kid.get_contents()
|
contents = contents + kid.get_contents()
|
||||||
return contents
|
return contents
|
||||||
|
|
||||||
|
def changed_since_last_build(self, target, prev_ni):
|
||||||
|
cur_csig = self.get_csig()
|
||||||
|
try:
|
||||||
|
return cur_csig != prev_ni.csig
|
||||||
|
except AttributeError:
|
||||||
|
return 1
|
||||||
|
|
||||||
def get_csig(self, calc=None):
|
def get_csig(self, calc=None):
|
||||||
"""Because we're a Python value node and don't have a real
|
"""Because we're a Python value node and don't have a real
|
||||||
timestamp, we get to ignore the calculator and just use the
|
timestamp, we get to ignore the calculator and just use the
|
||||||
value contents."""
|
value contents."""
|
||||||
try:
|
try:
|
||||||
binfo = self.binfo
|
return self.ninfo.csig
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
binfo = self.binfo = self.new_binfo()
|
pass
|
||||||
try:
|
contents = self.get_contents()
|
||||||
return binfo.ninfo.csig
|
self.get_ninfo().csig = contents
|
||||||
except AttributeError:
|
return contents
|
||||||
binfo.ninfo.csig = self.get_contents()
|
|
||||||
self.store_info(binfo)
|
|
||||||
return binfo.ninfo.csig
|
|
|
@ -42,7 +42,7 @@ be able to depend on any other type of "thing."
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Node/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Node/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
|
@ -53,9 +53,13 @@ import UserList
|
||||||
from SCons.Debug import logInstanceCreation
|
from SCons.Debug import logInstanceCreation
|
||||||
import SCons.Executor
|
import SCons.Executor
|
||||||
import SCons.Memoize
|
import SCons.Memoize
|
||||||
import SCons.SConsign
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
from SCons.Debug import Trace
|
||||||
|
|
||||||
|
def classname(obj):
|
||||||
|
return string.split(str(obj.__class__), '.')[-1]
|
||||||
|
|
||||||
# Node states
|
# Node states
|
||||||
#
|
#
|
||||||
# These are in "priority" order, so that the maximum value for any
|
# These are in "priority" order, so that the maximum value for any
|
||||||
|
@ -103,38 +107,53 @@ class NodeInfoBase:
|
||||||
Node subclasses should subclass NodeInfoBase to provide their own
|
Node subclasses should subclass NodeInfoBase to provide their own
|
||||||
logic for dealing with their own Node-specific signature information.
|
logic for dealing with their own Node-specific signature information.
|
||||||
"""
|
"""
|
||||||
|
current_version_id = 1
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
"""A null initializer so that subclasses have a superclass
|
# Create an object attribute from the class attribute so it ends up
|
||||||
initialization method to call for future use.
|
# in the pickled data in the .sconsign file.
|
||||||
"""
|
self._version_id = self.current_version_id
|
||||||
pass
|
|
||||||
def __cmp__(self, other):
|
|
||||||
return cmp(self.__dict__, other.__dict__)
|
|
||||||
def update(self, node):
|
def update(self, node):
|
||||||
pass
|
|
||||||
def merge(self, other):
|
|
||||||
for key, val in other.__dict__.items():
|
|
||||||
self.__dict__[key] = val
|
|
||||||
def prepare_dependencies(self):
|
|
||||||
pass
|
|
||||||
def format(self):
|
|
||||||
try:
|
try:
|
||||||
field_list = self.field_list
|
field_list = self.field_list
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
field_list = self.__dict__.keys()
|
return
|
||||||
field_list.sort()
|
for f in field_list:
|
||||||
|
try:
|
||||||
|
delattr(self, f)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
func = getattr(node, 'get_' + f)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
setattr(self, f, func())
|
||||||
|
def convert(self, node, val):
|
||||||
|
pass
|
||||||
|
def merge(self, other):
|
||||||
|
self.__dict__.update(other.__dict__)
|
||||||
|
def format(self, field_list=None, names=0):
|
||||||
|
if field_list is None:
|
||||||
|
try:
|
||||||
|
field_list = self.field_list
|
||||||
|
except AttributeError:
|
||||||
|
field_list = self.__dict__.keys()
|
||||||
|
field_list.sort()
|
||||||
fields = []
|
fields = []
|
||||||
for field in field_list:
|
for field in field_list:
|
||||||
try:
|
try:
|
||||||
f = getattr(self, field)
|
f = getattr(self, field)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
f = None
|
f = None
|
||||||
fields.append(str(f))
|
f = str(f)
|
||||||
return string.join(fields, " ")
|
if names:
|
||||||
|
f = field + ': ' + f
|
||||||
|
fields.append(f)
|
||||||
|
return fields
|
||||||
|
|
||||||
class BuildInfoBase:
|
class BuildInfoBase:
|
||||||
"""
|
"""
|
||||||
The generic base clasee for build information for a Node.
|
The generic base class for build information for a Node.
|
||||||
|
|
||||||
This is what gets stored in a .sconsign file for each target file.
|
This is what gets stored in a .sconsign file for each target file.
|
||||||
It contains a NodeInfo instance for this node (signature information
|
It contains a NodeInfo instance for this node (signature information
|
||||||
|
@ -142,22 +161,17 @@ class BuildInfoBase:
|
||||||
generic build stuff we have to track: sources, explicit dependencies,
|
generic build stuff we have to track: sources, explicit dependencies,
|
||||||
implicit dependencies, and action information.
|
implicit dependencies, and action information.
|
||||||
"""
|
"""
|
||||||
|
current_version_id = 1
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.ninfo = node.NodeInfo(node)
|
# Create an object attribute from the class attribute so it ends up
|
||||||
|
# in the pickled data in the .sconsign file.
|
||||||
|
self._version_id = self.current_version_id
|
||||||
self.bsourcesigs = []
|
self.bsourcesigs = []
|
||||||
self.bdependsigs = []
|
self.bdependsigs = []
|
||||||
self.bimplicitsigs = []
|
self.bimplicitsigs = []
|
||||||
self.bactsig = None
|
self.bactsig = None
|
||||||
def __cmp__(self, other):
|
|
||||||
return cmp(self.ninfo, other.ninfo)
|
|
||||||
def merge(self, other):
|
def merge(self, other):
|
||||||
for key, val in other.__dict__.items():
|
self.__dict__.update(other.__dict__)
|
||||||
try:
|
|
||||||
merge = self.__dict__[key].merge
|
|
||||||
except (AttributeError, KeyError):
|
|
||||||
self.__dict__[key] = val
|
|
||||||
else:
|
|
||||||
merge(val)
|
|
||||||
|
|
||||||
class Node:
|
class Node:
|
||||||
"""The base Node class, for entities that we know how to
|
"""The base Node class, for entities that we know how to
|
||||||
|
@ -193,6 +207,7 @@ class Node:
|
||||||
self.depends_dict = {}
|
self.depends_dict = {}
|
||||||
self.ignore = [] # dependencies to ignore
|
self.ignore = [] # dependencies to ignore
|
||||||
self.ignore_dict = {}
|
self.ignore_dict = {}
|
||||||
|
self.prerequisites = SCons.Util.UniqueList()
|
||||||
self.implicit = None # implicit (scanned) dependencies (None means not scanned yet)
|
self.implicit = None # implicit (scanned) dependencies (None means not scanned yet)
|
||||||
self.waiting_parents = {}
|
self.waiting_parents = {}
|
||||||
self.waiting_s_e = {}
|
self.waiting_s_e = {}
|
||||||
|
@ -225,10 +240,18 @@ class Node:
|
||||||
def get_suffix(self):
|
def get_suffix(self):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountValue('get_build_env'))
|
||||||
|
|
||||||
def get_build_env(self):
|
def get_build_env(self):
|
||||||
"""Fetch the appropriate Environment to build this node.
|
"""Fetch the appropriate Environment to build this node.
|
||||||
"""
|
"""
|
||||||
return self.get_executor().get_build_env()
|
try:
|
||||||
|
return self._memo['get_build_env']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
result = self.get_executor().get_build_env()
|
||||||
|
self._memo['get_build_env'] = result
|
||||||
|
return result
|
||||||
|
|
||||||
def get_build_scanner_path(self, scanner):
|
def get_build_scanner_path(self, scanner):
|
||||||
"""Fetch the appropriate scanner path for this node."""
|
"""Fetch the appropriate scanner path for this node."""
|
||||||
|
@ -286,19 +309,64 @@ class Node:
|
||||||
"""
|
"""
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
#
|
||||||
|
# Taskmaster interface subsystem
|
||||||
|
#
|
||||||
|
|
||||||
|
def make_ready(self):
|
||||||
|
"""Get a Node ready for evaluation.
|
||||||
|
|
||||||
|
This is called before the Taskmaster decides if the Node is
|
||||||
|
up-to-date or not. Overriding this method allows for a Node
|
||||||
|
subclass to be disambiguated if necessary, or for an implicit
|
||||||
|
source builder to be attached.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def prepare(self):
|
||||||
|
"""Prepare for this Node to be built.
|
||||||
|
|
||||||
|
This is called after the Taskmaster has decided that the Node
|
||||||
|
is out-of-date and must be rebuilt, but before actually calling
|
||||||
|
the method to build the Node.
|
||||||
|
|
||||||
|
This default implemenation checks that all children either exist
|
||||||
|
or are derived, and initializes the BuildInfo structure that
|
||||||
|
will hold the information about how this node is, uh, built.
|
||||||
|
|
||||||
|
Overriding this method allows for for a Node subclass to remove
|
||||||
|
the underlying file from the file system. Note that subclass
|
||||||
|
methods should call this base class method to get the child
|
||||||
|
check and the BuildInfo structure.
|
||||||
|
"""
|
||||||
|
l = self.depends
|
||||||
|
if not self.implicit is None:
|
||||||
|
l = l + self.implicit
|
||||||
|
missing_sources = self.get_executor().get_missing_sources() \
|
||||||
|
+ filter(lambda c: c.missing(), l)
|
||||||
|
if missing_sources:
|
||||||
|
desc = "Source `%s' not found, needed by target `%s'." % (missing_sources[0], self)
|
||||||
|
raise SCons.Errors.StopError, desc
|
||||||
|
|
||||||
|
self.binfo = self.get_binfo()
|
||||||
|
|
||||||
def build(self, **kw):
|
def build(self, **kw):
|
||||||
"""Actually build the node.
|
"""Actually build the node.
|
||||||
|
|
||||||
|
This is called by the Taskmaster after it's decided that the
|
||||||
|
Node is out-of-date and must be rebuilt, and after the prepare()
|
||||||
|
method has gotten everything, uh, prepared.
|
||||||
|
|
||||||
This method is called from multiple threads in a parallel build,
|
This method is called from multiple threads in a parallel build,
|
||||||
so only do thread safe stuff here. Do thread unsafe stuff in
|
so only do thread safe stuff here. Do thread unsafe stuff
|
||||||
built().
|
in built().
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def exitstatfunc(stat, node=self):
|
try:
|
||||||
if stat:
|
apply(self.get_executor(), (self,), kw)
|
||||||
msg = "Error %d" % stat
|
except SCons.Errors.BuildError, e:
|
||||||
raise SCons.Errors.BuildError(node=node, errstr=msg)
|
e.node = self
|
||||||
executor = self.get_executor()
|
raise
|
||||||
apply(executor, (self, exitstatfunc), kw)
|
|
||||||
|
|
||||||
def built(self):
|
def built(self):
|
||||||
"""Called just after this node is successfully built."""
|
"""Called just after this node is successfully built."""
|
||||||
|
@ -309,28 +377,26 @@ class Node:
|
||||||
parent.implicit = None
|
parent.implicit = None
|
||||||
parent.del_binfo()
|
parent.del_binfo()
|
||||||
|
|
||||||
try:
|
|
||||||
new = self.binfo
|
|
||||||
except AttributeError:
|
|
||||||
# Node arrived here without build info; apparently it
|
|
||||||
# doesn't need it, so don't bother calculating or storing
|
|
||||||
# it.
|
|
||||||
new = None
|
|
||||||
|
|
||||||
# Reset this Node's cached state since it was just built and
|
|
||||||
# various state has changed.
|
|
||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
if new:
|
self.ninfo.update(self)
|
||||||
# It had build info, so it should be stored in the signature
|
|
||||||
# cache. However, if the build info included a content
|
def visited(self):
|
||||||
# signature then it must be recalculated before being stored.
|
"""Called just after this node has been visited (with or
|
||||||
if hasattr(new.ninfo, 'csig'):
|
without a build)."""
|
||||||
self.get_csig()
|
try:
|
||||||
else:
|
binfo = self.binfo
|
||||||
new.ninfo.update(self)
|
except AttributeError:
|
||||||
self.binfo = new
|
# Apparently this node doesn't need build info, so
|
||||||
self.store_info(self.binfo)
|
# don't bother calculating or storing it.
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.ninfo.update(self)
|
||||||
|
self.store_info()
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
def add_to_waiting_s_e(self, node):
|
def add_to_waiting_s_e(self, node):
|
||||||
self.waiting_s_e[node] = 1
|
self.waiting_s_e[node] = 1
|
||||||
|
@ -367,27 +433,33 @@ class Node:
|
||||||
can be re-evaluated by interfaces that do continuous integration
|
can be re-evaluated by interfaces that do continuous integration
|
||||||
builds).
|
builds).
|
||||||
"""
|
"""
|
||||||
|
# Note in case it's important in the future: We also used to clear
|
||||||
|
# the build information (the lists of dependencies) here like this:
|
||||||
|
#
|
||||||
|
# self.del_binfo()
|
||||||
|
#
|
||||||
|
# But we now rely on the fact that we're going to look at that
|
||||||
|
# once before the build, and then store the results in the
|
||||||
|
# .sconsign file after the build.
|
||||||
self.clear_memoized_values()
|
self.clear_memoized_values()
|
||||||
|
self.ninfo = self.new_ninfo()
|
||||||
self.executor_cleanup()
|
self.executor_cleanup()
|
||||||
self.del_binfo()
|
|
||||||
try:
|
try:
|
||||||
delattr(self, '_calculated_sig')
|
delattr(self, '_calculated_sig')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
self.includes = None
|
self.includes = None
|
||||||
self.found_includes = {}
|
self.found_includes = {}
|
||||||
self.implicit = None
|
|
||||||
|
|
||||||
def clear_memoized_values(self):
|
def clear_memoized_values(self):
|
||||||
self._memo = {}
|
self._memo = {}
|
||||||
|
|
||||||
def visited(self):
|
|
||||||
"""Called just after this node has been visited
|
|
||||||
without requiring a build.."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def builder_set(self, builder):
|
def builder_set(self, builder):
|
||||||
self.builder = builder
|
self.builder = builder
|
||||||
|
try:
|
||||||
|
del self.executor
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def has_builder(self):
|
def has_builder(self):
|
||||||
"""Return whether this Node has a builder or not.
|
"""Return whether this Node has a builder or not.
|
||||||
|
@ -405,8 +477,7 @@ class Node:
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# There was no explicit builder for this Node, so initialize
|
# There was no explicit builder for this Node, so initialize
|
||||||
# the self.builder attribute to None now.
|
# the self.builder attribute to None now.
|
||||||
self.builder = None
|
b = self.builder = None
|
||||||
b = self.builder
|
|
||||||
return not b is None
|
return not b is None
|
||||||
|
|
||||||
def set_explicit(self, is_explicit):
|
def set_explicit(self, is_explicit):
|
||||||
|
@ -446,14 +517,6 @@ class Node:
|
||||||
"""
|
"""
|
||||||
return self.has_builder() or self.side_effect
|
return self.has_builder() or self.side_effect
|
||||||
|
|
||||||
def is_pseudo_derived(self):
|
|
||||||
"""
|
|
||||||
Returns true iff this node is built, but should use a source path
|
|
||||||
when duplicate=0 and should contribute a content signature (i.e.
|
|
||||||
source signature) when used as a source for other derived files.
|
|
||||||
"""
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def alter_targets(self):
|
def alter_targets(self):
|
||||||
"""Return a list of alternate targets for this Node.
|
"""Return a list of alternate targets for this Node.
|
||||||
"""
|
"""
|
||||||
|
@ -552,40 +615,33 @@ class Node:
|
||||||
return
|
return
|
||||||
|
|
||||||
build_env = self.get_build_env()
|
build_env = self.get_build_env()
|
||||||
|
executor = self.get_executor()
|
||||||
|
|
||||||
# Here's where we implement --implicit-cache.
|
# Here's where we implement --implicit-cache.
|
||||||
if implicit_cache and not implicit_deps_changed:
|
if implicit_cache and not implicit_deps_changed:
|
||||||
implicit = self.get_stored_implicit()
|
implicit = self.get_stored_implicit()
|
||||||
if implicit is not None:
|
if implicit is not None:
|
||||||
factory = build_env.get_factory(self.builder.source_factory)
|
# We now add the implicit dependencies returned from the
|
||||||
nodes = []
|
# stored .sconsign entry to have already been converted
|
||||||
for i in implicit:
|
# to Nodes for us. (We used to run them through a
|
||||||
try:
|
# source_factory function here.)
|
||||||
n = factory(i)
|
|
||||||
except TypeError:
|
# Update all of the targets with them. This
|
||||||
# The implicit dependency was cached as one type
|
# essentially short-circuits an N*M scan of the
|
||||||
# of Node last time, but the configuration has
|
# sources for each individual target, which is a hell
|
||||||
# changed (probably) and it's a different type
|
# of a lot more efficient.
|
||||||
# this time. Just ignore the mismatch and go
|
for tgt in executor.targets:
|
||||||
# with what our current configuration says the
|
tgt.add_to_implicit(implicit)
|
||||||
# Node is.
|
|
||||||
pass
|
if implicit_deps_unchanged or self.is_up_to_date():
|
||||||
else:
|
|
||||||
nodes.append(n)
|
|
||||||
self._add_child(self.implicit, self.implicit_dict, nodes)
|
|
||||||
calc = build_env.get_calculator()
|
|
||||||
if implicit_deps_unchanged or self.current(calc):
|
|
||||||
return
|
return
|
||||||
# one of this node's sources has changed, so
|
# one of this node's sources has changed,
|
||||||
# we need to recalculate the implicit deps,
|
# so we must recalculate the implicit deps:
|
||||||
# and the bsig:
|
|
||||||
self.implicit = []
|
self.implicit = []
|
||||||
self.implicit_dict = {}
|
self.implicit_dict = {}
|
||||||
self._children_reset()
|
self._children_reset()
|
||||||
self.del_binfo()
|
self.del_binfo()
|
||||||
|
|
||||||
executor = self.get_executor()
|
|
||||||
|
|
||||||
# Have the executor scan the sources.
|
# Have the executor scan the sources.
|
||||||
executor.scan_sources(self.builder.source_scanner)
|
executor.scan_sources(self.builder.source_scanner)
|
||||||
|
|
||||||
|
@ -620,65 +676,24 @@ class Node:
|
||||||
NodeInfo = NodeInfoBase
|
NodeInfo = NodeInfoBase
|
||||||
BuildInfo = BuildInfoBase
|
BuildInfo = BuildInfoBase
|
||||||
|
|
||||||
def calculator(self):
|
|
||||||
import SCons.Defaults
|
|
||||||
|
|
||||||
env = self.env or SCons.Defaults.DefaultEnvironment()
|
|
||||||
return env.get_calculator()
|
|
||||||
|
|
||||||
memoizer_counters.append(SCons.Memoize.CountValue('calc_signature'))
|
|
||||||
|
|
||||||
def calc_signature(self, calc=None):
|
|
||||||
"""
|
|
||||||
Select and calculate the appropriate build signature for a node.
|
|
||||||
|
|
||||||
self - the node
|
|
||||||
calc - the signature calculation module
|
|
||||||
returns - the signature
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return self._memo['calc_signature']
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
if self.is_derived():
|
|
||||||
import SCons.Defaults
|
|
||||||
|
|
||||||
env = self.env or SCons.Defaults.DefaultEnvironment()
|
|
||||||
if env.use_build_signature():
|
|
||||||
result = self.get_bsig(calc)
|
|
||||||
else:
|
|
||||||
result = self.get_csig(calc)
|
|
||||||
elif not self.rexists():
|
|
||||||
result = None
|
|
||||||
else:
|
|
||||||
result = self.get_csig(calc)
|
|
||||||
self._memo['calc_signature'] = result
|
|
||||||
return result
|
|
||||||
|
|
||||||
def new_ninfo(self):
|
def new_ninfo(self):
|
||||||
return self.NodeInfo(self)
|
ninfo = self.NodeInfo(self)
|
||||||
|
return ninfo
|
||||||
|
|
||||||
|
def get_ninfo(self):
|
||||||
|
try:
|
||||||
|
return self.ninfo
|
||||||
|
except AttributeError:
|
||||||
|
self.ninfo = self.new_ninfo()
|
||||||
|
return self.ninfo
|
||||||
|
|
||||||
def new_binfo(self):
|
def new_binfo(self):
|
||||||
return self.BuildInfo(self)
|
binfo = self.BuildInfo(self)
|
||||||
|
return binfo
|
||||||
|
|
||||||
def get_binfo(self):
|
def get_binfo(self):
|
||||||
try:
|
|
||||||
return self.binfo
|
|
||||||
except AttributeError:
|
|
||||||
self.binfo = self.new_binfo()
|
|
||||||
return self.binfo
|
|
||||||
|
|
||||||
def del_binfo(self):
|
|
||||||
"""Delete the build info from this node."""
|
|
||||||
try:
|
|
||||||
delattr(self, 'binfo')
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def gen_binfo(self, calc=None, scan=1):
|
|
||||||
"""
|
"""
|
||||||
Generate a node's build signature, the digested signatures
|
Fetch a node's build information.
|
||||||
of its dependency files and build information.
|
|
||||||
|
|
||||||
node - the node whose sources will be collected
|
node - the node whose sources will be collected
|
||||||
cache - alternate node to use for the signature cache
|
cache - alternate node to use for the signature cache
|
||||||
|
@ -689,21 +704,17 @@ class Node:
|
||||||
already built and updated by someone else, if that's
|
already built and updated by someone else, if that's
|
||||||
what's wanted.
|
what's wanted.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
return self.binfo
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
if calc is None:
|
binfo = self.new_binfo()
|
||||||
calc = self.calculator()
|
self.binfo = binfo
|
||||||
|
|
||||||
binfo = self.get_binfo()
|
|
||||||
|
|
||||||
if scan:
|
|
||||||
self.scan()
|
|
||||||
|
|
||||||
executor = self.get_executor()
|
executor = self.get_executor()
|
||||||
def calc_signature(node, calc=calc):
|
|
||||||
return node.calc_signature(calc)
|
|
||||||
|
|
||||||
sources = executor.get_unignored_sources(self.ignore)
|
sources = executor.get_unignored_sources(self.ignore)
|
||||||
sourcesigs = executor.process_sources(calc_signature, self.ignore)
|
|
||||||
|
|
||||||
depends = self.depends
|
depends = self.depends
|
||||||
implicit = self.implicit or []
|
implicit = self.implicit or []
|
||||||
|
@ -712,15 +723,16 @@ class Node:
|
||||||
depends = filter(self.do_not_ignore, depends)
|
depends = filter(self.do_not_ignore, depends)
|
||||||
implicit = filter(self.do_not_ignore, implicit)
|
implicit = filter(self.do_not_ignore, implicit)
|
||||||
|
|
||||||
dependsigs = map(calc_signature, depends)
|
def get_ninfo(node):
|
||||||
implicitsigs = map(calc_signature, implicit)
|
return node.get_ninfo()
|
||||||
|
|
||||||
sigs = sourcesigs + dependsigs + implicitsigs
|
sourcesigs = map(get_ninfo, sources)
|
||||||
|
dependsigs = map(get_ninfo, depends)
|
||||||
|
implicitsigs = map(get_ninfo, implicit)
|
||||||
|
|
||||||
if self.has_builder():
|
if self.has_builder():
|
||||||
binfo.bact = str(executor)
|
binfo.bact = str(executor)
|
||||||
binfo.bactsig = calc.module.signature(executor)
|
binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())
|
||||||
sigs.append(binfo.bactsig)
|
|
||||||
|
|
||||||
binfo.bsources = sources
|
binfo.bsources = sources
|
||||||
binfo.bdepends = depends
|
binfo.bdepends = depends
|
||||||
|
@ -730,33 +742,34 @@ class Node:
|
||||||
binfo.bdependsigs = dependsigs
|
binfo.bdependsigs = dependsigs
|
||||||
binfo.bimplicitsigs = implicitsigs
|
binfo.bimplicitsigs = implicitsigs
|
||||||
|
|
||||||
binfo.ninfo.bsig = calc.module.collect(filter(None, sigs))
|
|
||||||
|
|
||||||
return binfo
|
return binfo
|
||||||
|
|
||||||
def get_bsig(self, calc=None):
|
def del_binfo(self):
|
||||||
binfo = self.get_binfo()
|
"""Delete the build info from this node."""
|
||||||
try:
|
try:
|
||||||
return binfo.ninfo.bsig
|
delattr(self, 'binfo')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self.binfo = self.gen_binfo(calc)
|
pass
|
||||||
return self.binfo.ninfo.bsig
|
|
||||||
|
|
||||||
def get_csig(self, calc=None):
|
def get_csig(self):
|
||||||
binfo = self.get_binfo()
|
|
||||||
try:
|
try:
|
||||||
return binfo.ninfo.csig
|
return self.ninfo.csig
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if calc is None:
|
ninfo = self.get_ninfo()
|
||||||
calc = self.calculator()
|
ninfo.csig = SCons.Util.MD5signature(self.get_contents())
|
||||||
csig = binfo.ninfo.csig = calc.module.signature(self)
|
return self.ninfo.csig
|
||||||
return csig
|
|
||||||
|
|
||||||
def store_info(self, obj):
|
def get_cachedir_csig(self):
|
||||||
|
return self.get_csig()
|
||||||
|
|
||||||
|
def store_info(self):
|
||||||
"""Make the build signature permanent (that is, store it in the
|
"""Make the build signature permanent (that is, store it in the
|
||||||
.sconsign file or equivalent)."""
|
.sconsign file or equivalent)."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def do_not_store_info(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def get_stored_info(self):
|
def get_stored_info(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -800,23 +813,8 @@ class Node:
|
||||||
|
|
||||||
def missing(self):
|
def missing(self):
|
||||||
return not self.is_derived() and \
|
return not self.is_derived() and \
|
||||||
not self.is_pseudo_derived() and \
|
|
||||||
not self.linked and \
|
not self.linked and \
|
||||||
not self.rexists()
|
not self.rexists()
|
||||||
|
|
||||||
def prepare(self):
|
|
||||||
"""Prepare for this Node to be created.
|
|
||||||
The default implemenation checks that all children either exist
|
|
||||||
or are derived.
|
|
||||||
"""
|
|
||||||
l = self.depends
|
|
||||||
if not self.implicit is None:
|
|
||||||
l = l + self.implicit
|
|
||||||
missing_sources = self.get_executor().get_missing_sources() \
|
|
||||||
+ filter(lambda c: c.missing(), l)
|
|
||||||
if missing_sources:
|
|
||||||
desc = "Source `%s' not found, needed by target `%s'." % (missing_sources[0], self)
|
|
||||||
raise SCons.Errors.StopError, desc
|
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
"""Remove this Node: no-op by default."""
|
"""Remove this Node: no-op by default."""
|
||||||
|
@ -834,6 +832,11 @@ class Node:
|
||||||
s = str(e)
|
s = str(e)
|
||||||
raise SCons.Errors.UserError("attempted to add a non-Node dependency to %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
|
raise SCons.Errors.UserError("attempted to add a non-Node dependency to %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
|
||||||
|
|
||||||
|
def add_prerequisite(self, prerequisite):
|
||||||
|
"""Adds prerequisites"""
|
||||||
|
self.prerequisites.extend(prerequisite)
|
||||||
|
self._children_reset()
|
||||||
|
|
||||||
def add_ignore(self, depend):
|
def add_ignore(self, depend):
|
||||||
"""Adds dependencies to ignore."""
|
"""Adds dependencies to ignore."""
|
||||||
try:
|
try:
|
||||||
|
@ -861,11 +864,11 @@ class Node:
|
||||||
def _add_child(self, collection, dict, child):
|
def _add_child(self, collection, dict, child):
|
||||||
"""Adds 'child' to 'collection', first checking 'dict' to see
|
"""Adds 'child' to 'collection', first checking 'dict' to see
|
||||||
if it's already present."""
|
if it's already present."""
|
||||||
if type(child) is not type([]):
|
#if type(child) is not type([]):
|
||||||
child = [child]
|
# child = [child]
|
||||||
for c in child:
|
#for c in child:
|
||||||
if not isinstance(c, Node):
|
# if not isinstance(c, Node):
|
||||||
raise TypeError, c
|
# raise TypeError, c
|
||||||
added = None
|
added = None
|
||||||
for c in child:
|
for c in child:
|
||||||
if not dict.has_key(c):
|
if not dict.has_key(c):
|
||||||
|
@ -883,7 +886,7 @@ class Node:
|
||||||
def _children_reset(self):
|
def _children_reset(self):
|
||||||
self.clear_memoized_values()
|
self.clear_memoized_values()
|
||||||
# We need to let the Executor clear out any calculated
|
# We need to let the Executor clear out any calculated
|
||||||
# bsig info that it's cached so we can re-calculate it.
|
# build info that it's cached so we can re-calculate it.
|
||||||
self.executor_cleanup()
|
self.executor_cleanup()
|
||||||
|
|
||||||
def do_not_ignore(self, node):
|
def do_not_ignore(self, node):
|
||||||
|
@ -944,19 +947,107 @@ class Node:
|
||||||
def get_state(self):
|
def get_state(self):
|
||||||
return self.state
|
return self.state
|
||||||
|
|
||||||
def current(self, calc=None):
|
def state_has_changed(self, target, prev_ni):
|
||||||
|
return (self.state != SCons.Node.up_to_date)
|
||||||
|
|
||||||
|
def get_env(self):
|
||||||
|
env = self.env
|
||||||
|
if not env:
|
||||||
|
import SCons.Defaults
|
||||||
|
env = SCons.Defaults.DefaultEnvironment()
|
||||||
|
return env
|
||||||
|
|
||||||
|
def changed_since_last_build(self, target, prev_ni):
|
||||||
|
"""
|
||||||
|
|
||||||
|
Must be overridden in a specific subclass to return True if this
|
||||||
|
Node (a dependency) has changed since the last time it was used
|
||||||
|
to build the specified target. prev_ni is this Node's state (for
|
||||||
|
example, its file timestamp, length, maybe content signature)
|
||||||
|
as of the last time the target was built.
|
||||||
|
|
||||||
|
Note that this method is called through the dependency, not the
|
||||||
|
target, because a dependency Node must be able to use its own
|
||||||
|
logic to decide if it changed. For example, File Nodes need to
|
||||||
|
obey if we're configured to use timestamps, but Python Value Nodes
|
||||||
|
never use timestamps and always use the content. If this method
|
||||||
|
were called through the target, then each Node's implementation
|
||||||
|
of this method would have to have more complicated logic to
|
||||||
|
handle all the different Node types on which it might depend.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def Decider(self, function):
|
||||||
|
SCons.Util.AddMethod(self, function, 'changed_since_last_build')
|
||||||
|
|
||||||
|
def changed(self, node=None):
|
||||||
|
"""
|
||||||
|
Returns if the node is up-to-date with respect to the BuildInfo
|
||||||
|
stored last time it was built. The default behavior is to compare
|
||||||
|
it against our own previously stored BuildInfo, but the stored
|
||||||
|
BuildInfo from another Node (typically one in a Repository)
|
||||||
|
can be used instead.
|
||||||
|
|
||||||
|
Note that we now *always* check every dependency. We used to
|
||||||
|
short-circuit the check by returning as soon as we detected
|
||||||
|
any difference, but we now rely on checking every dependency
|
||||||
|
to make sure that any necessary Node information (for example,
|
||||||
|
the content signature of an #included .h file) is updated.
|
||||||
|
"""
|
||||||
|
t = 0
|
||||||
|
if t: Trace('changed(%s [%s], %s)' % (self, classname(self), node))
|
||||||
|
if node is None:
|
||||||
|
node = self
|
||||||
|
|
||||||
|
result = False
|
||||||
|
|
||||||
|
bi = node.get_stored_info().binfo
|
||||||
|
then = bi.bsourcesigs + bi.bdependsigs + bi.bimplicitsigs
|
||||||
|
children = self.children()
|
||||||
|
|
||||||
|
diff = len(children) - len(then)
|
||||||
|
if diff:
|
||||||
|
# The old and new dependency lists are different lengths.
|
||||||
|
# This always indicates that the Node must be rebuilt.
|
||||||
|
# We also extend the old dependency list with enough None
|
||||||
|
# entries to equal the new dependency list, for the benefit
|
||||||
|
# of the loop below that updates node information.
|
||||||
|
then.extend([None] * diff)
|
||||||
|
result = True
|
||||||
|
|
||||||
|
for child, prev_ni in zip(children, then):
|
||||||
|
if child.changed_since_last_build(self, prev_ni):
|
||||||
|
if t: Trace(': %s changed' % child)
|
||||||
|
result = True
|
||||||
|
|
||||||
|
contents = self.get_executor().get_contents()
|
||||||
|
if self.has_builder():
|
||||||
|
import SCons.Util
|
||||||
|
newsig = SCons.Util.MD5signature(contents)
|
||||||
|
if bi.bactsig != newsig:
|
||||||
|
if t: Trace(': bactsig %s != newsig %s' % (bi.bactsig, newsig))
|
||||||
|
result = True
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
if t: Trace(': up to date')
|
||||||
|
|
||||||
|
if t: Trace('\n')
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def is_up_to_date(self):
|
||||||
"""Default check for whether the Node is current: unknown Node
|
"""Default check for whether the Node is current: unknown Node
|
||||||
subtypes are always out of date, so they will always get built."""
|
subtypes are always out of date, so they will always get built."""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def children_are_up_to_date(self, calc=None):
|
def children_are_up_to_date(self):
|
||||||
"""Alternate check for whether the Node is current: If all of
|
"""Alternate check for whether the Node is current: If all of
|
||||||
our children were up-to-date, then this Node was up-to-date, too.
|
our children were up-to-date, then this Node was up-to-date, too.
|
||||||
|
|
||||||
The SCons.Node.Alias and SCons.Node.Python.Value subclasses
|
The SCons.Node.Alias and SCons.Node.Python.Value subclasses
|
||||||
rebind their current() method to this method."""
|
rebind their current() method to this method."""
|
||||||
# Allow the children to calculate their signatures.
|
# Allow the children to calculate their signatures.
|
||||||
self.binfo = self.gen_binfo(calc)
|
self.binfo = self.get_binfo()
|
||||||
if self.always_build:
|
if self.always_build:
|
||||||
return None
|
return None
|
||||||
state = 0
|
state = 0
|
||||||
|
@ -1046,32 +1137,29 @@ class Node:
|
||||||
if not self.exists():
|
if not self.exists():
|
||||||
return "building `%s' because it doesn't exist\n" % self
|
return "building `%s' because it doesn't exist\n" % self
|
||||||
|
|
||||||
|
if self.always_build:
|
||||||
|
return "rebuilding `%s' because AlwaysBuild() is specified\n" % self
|
||||||
|
|
||||||
old = self.get_stored_info()
|
old = self.get_stored_info()
|
||||||
if old is None:
|
if old is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
old = old.binfo
|
||||||
old.prepare_dependencies()
|
old.prepare_dependencies()
|
||||||
|
|
||||||
def dictify(result, kids, sigs):
|
|
||||||
for k, s in zip(kids, sigs):
|
|
||||||
result[k] = s
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
osig = {}
|
old_bkids = old.bsources + old.bdepends + old.bimplicit
|
||||||
dictify(osig, old.bsources, old.bsourcesigs)
|
old_bkidsigs = old.bsourcesigs + old.bdependsigs + old.bimplicitsigs
|
||||||
dictify(osig, old.bdepends, old.bdependsigs)
|
|
||||||
dictify(osig, old.bimplicit, old.bimplicitsigs)
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return "Cannot explain why `%s' is being rebuilt: No previous build information found\n" % self
|
return "Cannot explain why `%s' is being rebuilt: No previous build information found\n" % self
|
||||||
|
|
||||||
new = self.get_binfo()
|
new = self.get_binfo()
|
||||||
|
|
||||||
nsig = {}
|
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
||||||
dictify(nsig, new.bsources, new.bsourcesigs)
|
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
|
||||||
dictify(nsig, new.bdepends, new.bdependsigs)
|
|
||||||
dictify(nsig, new.bimplicit, new.bimplicitsigs)
|
|
||||||
|
|
||||||
old_bkids = old.bsources + old.bdepends + old.bimplicit
|
osig = dict(zip(old_bkids, old_bkidsigs))
|
||||||
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
nsig = dict(zip(new_bkids, new_bkidsigs))
|
||||||
|
|
||||||
# The sources and dependencies we'll want to report are all stored
|
# The sources and dependencies we'll want to report are all stored
|
||||||
# as relative paths to this target's directory, but we want to
|
# as relative paths to this target's directory, but we want to
|
||||||
|
@ -1092,7 +1180,7 @@ class Node:
|
||||||
for k in new_bkids:
|
for k in new_bkids:
|
||||||
if not k in old_bkids:
|
if not k in old_bkids:
|
||||||
lines.append("`%s' is a new dependency\n" % stringify(k))
|
lines.append("`%s' is a new dependency\n" % stringify(k))
|
||||||
elif osig[k] != nsig[k]:
|
elif k.changed_since_last_build(self, osig[k]):
|
||||||
lines.append("`%s' changed\n" % stringify(k))
|
lines.append("`%s' changed\n" % stringify(k))
|
||||||
|
|
||||||
if len(lines) == 0 and old_bkids != new_bkids:
|
if len(lines) == 0 and old_bkids != new_bkids:
|
||||||
|
@ -1124,19 +1212,18 @@ class Node:
|
||||||
lines = ["%s:\n" % preamble] + lines
|
lines = ["%s:\n" % preamble] + lines
|
||||||
return string.join(lines, ' '*11)
|
return string.join(lines, ' '*11)
|
||||||
|
|
||||||
l = [1]
|
|
||||||
ul = UserList.UserList([2])
|
|
||||||
try:
|
try:
|
||||||
l.extend(ul)
|
[].extend(UserList.UserList([]))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
# Python 1.5.2 doesn't allow a list to be extended by list-like
|
||||||
|
# objects (such as UserList instances), so just punt and use
|
||||||
|
# real lists.
|
||||||
def NodeList(l):
|
def NodeList(l):
|
||||||
return l
|
return l
|
||||||
else:
|
else:
|
||||||
class NodeList(UserList.UserList):
|
class NodeList(UserList.UserList):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(map(str, self.data))
|
return str(map(str, self.data))
|
||||||
del l
|
|
||||||
del ul
|
|
||||||
|
|
||||||
def get_children(node, parent): return node.children()
|
def get_children(node, parent): return node.children()
|
||||||
def ignore_cycle(node, stack): pass
|
def ignore_cycle(node, stack): pass
|
|
@ -34,7 +34,7 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/BoolOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Options/BoolOption.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
__all__ = ('BoolOption')
|
__all__ = ('BoolOption')
|
||||||
|
|
|
@ -37,7 +37,7 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/EnumOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Options/EnumOption.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
__all__ = ('EnumOption',)
|
__all__ = ('EnumOption',)
|
||||||
|
|
|
@ -47,7 +47,7 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/ListOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Options/ListOption.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
# Know Bug: This should behave like a Set-Type, but does not really,
|
# Know Bug: This should behave like a Set-Type, but does not really,
|
||||||
# since elements can occur twice.
|
# since elements can occur twice.
|
|
@ -50,7 +50,7 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/PackageOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Options/PackageOption.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
__all__ = ('PackageOption')
|
__all__ = ('PackageOption')
|
||||||
|
|
|
@ -68,7 +68,7 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/PathOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Options/PathOption.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -128,7 +128,12 @@ class _PathOptionClass:
|
||||||
"""
|
"""
|
||||||
if validator is None:
|
if validator is None:
|
||||||
validator = self.PathExists
|
validator = self.PathExists
|
||||||
return (key, '%s ( /path/to/%s )' % (help, key), default,
|
|
||||||
validator, None)
|
if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key):
|
||||||
|
return (key, '%s ( /path/to/%s )' % (help, key[0]), default,
|
||||||
|
validator, None)
|
||||||
|
else:
|
||||||
|
return (key, '%s ( /path/to/%s )' % (help, key), default,
|
||||||
|
validator, None)
|
||||||
|
|
||||||
PathOption = _PathOptionClass()
|
PathOption = _PathOptionClass()
|
|
@ -27,10 +27,13 @@ customizable variables to an SCons build.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Options/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import string
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
@ -44,31 +47,49 @@ from PathOption import PathOption # okay
|
||||||
|
|
||||||
|
|
||||||
class Options:
|
class Options:
|
||||||
|
instance=None
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Holds all the options, updates the environment with the variables,
|
Holds all the options, updates the environment with the variables,
|
||||||
and renders the help text.
|
and renders the help text.
|
||||||
"""
|
"""
|
||||||
def __init__(self, files=None, args={}):
|
def __init__(self, files=[], args={}, is_global=1):
|
||||||
"""
|
"""
|
||||||
files - [optional] List of option configuration files to load
|
files - [optional] List of option configuration files to load
|
||||||
(backward compatibility) If a single string is passed it is
|
(backward compatibility) If a single string is passed it is
|
||||||
automatically placed in a file list
|
automatically placed in a file list
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.options = []
|
self.options = []
|
||||||
self.args = args
|
self.args = args
|
||||||
self.files = None
|
if not SCons.Util.is_List(files):
|
||||||
if SCons.Util.is_String(files):
|
if files:
|
||||||
self.files = [ files ]
|
files = [ files ]
|
||||||
elif files:
|
else:
|
||||||
self.files = files
|
files = []
|
||||||
|
self.files = files
|
||||||
|
self.unknown = {}
|
||||||
|
|
||||||
|
# create the singleton instance
|
||||||
|
if is_global:
|
||||||
|
self=Options.instance
|
||||||
|
|
||||||
|
if not Options.instance:
|
||||||
|
Options.instance=self
|
||||||
|
|
||||||
def _do_add(self, key, help="", default=None, validator=None, converter=None):
|
def _do_add(self, key, help="", default=None, validator=None, converter=None):
|
||||||
class Option:
|
class Option:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
option = Option()
|
option = Option()
|
||||||
option.key = key
|
|
||||||
|
# if we get a list or a tuple, we take the first element as the
|
||||||
|
# option key and store the remaining in aliases.
|
||||||
|
if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key):
|
||||||
|
option.key = key[0]
|
||||||
|
option.aliases = key[1:]
|
||||||
|
else:
|
||||||
|
option.key = key
|
||||||
|
option.aliases = [ key ]
|
||||||
option.help = help
|
option.help = help
|
||||||
option.default = default
|
option.default = default
|
||||||
option.validator = validator
|
option.validator = validator
|
||||||
|
@ -111,7 +132,7 @@ class Options:
|
||||||
|
|
||||||
Each list element is a tuple/list of arguments to be passed on
|
Each list element is a tuple/list of arguments to be passed on
|
||||||
to the underlying method for adding options.
|
to the underlying method for adding options.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
opt.AddOptions(
|
opt.AddOptions(
|
||||||
('debug', '', 0),
|
('debug', '', 0),
|
||||||
|
@ -139,19 +160,34 @@ class Options:
|
||||||
values[option.key] = option.default
|
values[option.key] = option.default
|
||||||
|
|
||||||
# next set the value specified in the options file
|
# next set the value specified in the options file
|
||||||
if self.files:
|
for filename in self.files:
|
||||||
for filename in self.files:
|
if os.path.exists(filename):
|
||||||
if os.path.exists(filename):
|
dir = os.path.split(os.path.abspath(filename))[0]
|
||||||
execfile(filename, values)
|
if dir:
|
||||||
|
sys.path.insert(0, dir)
|
||||||
|
try:
|
||||||
|
values['__name__'] = filename
|
||||||
|
execfile(filename, {}, values)
|
||||||
|
finally:
|
||||||
|
if dir:
|
||||||
|
del sys.path[0]
|
||||||
|
del values['__name__']
|
||||||
|
|
||||||
# finally set the values specified on the command line
|
# set the values specified on the command line
|
||||||
if args is None:
|
if args is None:
|
||||||
args = self.args
|
args = self.args
|
||||||
values.update(args)
|
|
||||||
|
for arg, value in args.items():
|
||||||
|
added = False
|
||||||
|
for option in self.options:
|
||||||
|
if arg in option.aliases + [ option.key ]:
|
||||||
|
values[option.key] = value
|
||||||
|
added = True
|
||||||
|
if not added:
|
||||||
|
self.unknown[arg] = value
|
||||||
|
|
||||||
# put the variables in the environment:
|
# put the variables in the environment:
|
||||||
# (don't copy over variables that are not declared
|
# (don't copy over variables that are not declared as options)
|
||||||
# as options)
|
|
||||||
for option in self.options:
|
for option in self.options:
|
||||||
try:
|
try:
|
||||||
env[option.key] = values[option.key]
|
env[option.key] = values[option.key]
|
||||||
|
@ -176,6 +212,13 @@ class Options:
|
||||||
if option.validator and values.has_key(option.key):
|
if option.validator and values.has_key(option.key):
|
||||||
option.validator(option.key, env.subst('${%s}'%option.key), env)
|
option.validator(option.key, env.subst('${%s}'%option.key), env)
|
||||||
|
|
||||||
|
def UnknownOptions(self):
|
||||||
|
"""
|
||||||
|
Returns any options in the specified arguments lists that
|
||||||
|
were not known, declared options in this object.
|
||||||
|
"""
|
||||||
|
return self.unknown
|
||||||
|
|
||||||
def Save(self, filename, env):
|
def Save(self, filename, env):
|
||||||
"""
|
"""
|
||||||
Saves all the options in the given file. This file can
|
Saves all the options in the given file. This file can
|
||||||
|
@ -204,7 +247,7 @@ class Options:
|
||||||
# Convert stuff that has a repr() that
|
# Convert stuff that has a repr() that
|
||||||
# cannot be evaluated into a string
|
# cannot be evaluated into a string
|
||||||
value = SCons.Util.to_String(value)
|
value = SCons.Util.to_String(value)
|
||||||
|
|
||||||
defaultVal = env.subst(SCons.Util.to_String(option.default))
|
defaultVal = env.subst(SCons.Util.to_String(option.default))
|
||||||
if option.converter:
|
if option.converter:
|
||||||
defaultVal = option.converter(defaultVal)
|
defaultVal = option.converter(defaultVal)
|
||||||
|
@ -238,12 +281,19 @@ class Options:
|
||||||
actual = env.subst('${%s}' % opt.key)
|
actual = env.subst('${%s}' % opt.key)
|
||||||
else:
|
else:
|
||||||
actual = None
|
actual = None
|
||||||
return self.FormatOptionHelpText(env, opt.key, opt.help, opt.default, actual)
|
return self.FormatOptionHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases)
|
||||||
lines = filter(None, map(format, options))
|
lines = filter(None, map(format, options))
|
||||||
|
|
||||||
return string.join(lines, '')
|
return string.join(lines, '')
|
||||||
|
|
||||||
format = '\n%s: %s\n default: %s\n actual: %s\n'
|
format = '\n%s: %s\n default: %s\n actual: %s\n'
|
||||||
|
format_ = '\n%s: %s\n default: %s\n actual: %s\n aliases: %s\n'
|
||||||
|
|
||||||
|
def FormatOptionHelpText(self, env, key, help, default, actual, aliases=[]):
|
||||||
|
# Don't display the key name itself as an alias.
|
||||||
|
aliases = filter(lambda a, k=key: a != k, aliases)
|
||||||
|
if len(aliases)==0:
|
||||||
|
return self.format % (key, help, default, actual)
|
||||||
|
else:
|
||||||
|
return self.format_ % (key, help, default, actual, aliases)
|
||||||
|
|
||||||
def FormatOptionHelpText(self, env, key, help, default, actual):
|
|
||||||
return self.format % (key, help, default, actual)
|
|
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/PathList.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/PathList.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
__doc__ = """SCons.PathList
|
__doc__ = """SCons.PathList
|
||||||
|
|
||||||
|
@ -138,7 +138,8 @@ class _PathList:
|
||||||
value = string.join(map(str, value), '')
|
value = string.join(map(str, value), '')
|
||||||
elif type == TYPE_OBJECT:
|
elif type == TYPE_OBJECT:
|
||||||
value = node_conv(value)
|
value = node_conv(value)
|
||||||
result.append(value)
|
if value:
|
||||||
|
result.append(value)
|
||||||
return tuple(result)
|
return tuple(result)
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ their own platform definition.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import imp
|
import imp
|
||||||
import os
|
import os
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/aix.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/aix.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import string
|
import string
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/cygwin.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/cygwin.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
from SCons.Platform import TempFileMunge
|
from SCons.Platform import TempFileMunge
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/darwin.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/darwin.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/hpux.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/hpux.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/irix.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/irix.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/os2.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/os2.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if not env.has_key('ENV'):
|
if not env.has_key('ENV'):
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/posix.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/posix.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/sunos.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/sunos.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
||||||
|
@ -41,4 +41,4 @@ def generate(env):
|
||||||
env['MAXLINELENGTH'] = 1045320
|
env['MAXLINELENGTH'] = 1045320
|
||||||
env['PKGINFO'] = 'pkginfo'
|
env['PKGINFO'] = 'pkginfo'
|
||||||
env['PKGCHK'] = '/usr/sbin/pkgchk'
|
env['PKGCHK'] = '/usr/sbin/pkgchk'
|
||||||
env['ENV']['PATH'] = env['ENV']['PATH'] + ':/usr/ccs/bin'
|
env['ENV']['PATH'] = env['ENV']['PATH'] + ':/opt/SUNWspro/bin:/usr/ccs/bin'
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/win32.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Platform/win32.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -40,13 +40,53 @@ import tempfile
|
||||||
|
|
||||||
from SCons.Platform.posix import exitvalmap
|
from SCons.Platform.posix import exitvalmap
|
||||||
from SCons.Platform import TempFileMunge
|
from SCons.Platform import TempFileMunge
|
||||||
|
|
||||||
# XXX See note below about why importing SCons.Action should be
|
|
||||||
# eventually refactored.
|
|
||||||
import SCons.Action
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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" + \
|
||||||
|
"\tparallel (-j) builds may not work reliably with open Python files."
|
||||||
|
except AttributeError:
|
||||||
|
parallel_msg = \
|
||||||
|
"your pywin32 extensions do not support file handle operations;\n" + \
|
||||||
|
"\tparallel (-j) builds may not work reliably with open Python files."
|
||||||
|
else:
|
||||||
|
parallel_msg = None
|
||||||
|
|
||||||
|
import __builtin__
|
||||||
|
|
||||||
|
_builtin_file = __builtin__.file
|
||||||
|
_builtin_open = __builtin__.open
|
||||||
|
|
||||||
|
def _scons_file(*args, **kw):
|
||||||
|
fp = apply(_builtin_file, args, kw)
|
||||||
|
win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
|
||||||
|
win32con.HANDLE_FLAG_INHERIT,
|
||||||
|
0)
|
||||||
|
return fp
|
||||||
|
|
||||||
|
def _scons_open(*args, **kw):
|
||||||
|
fp = apply(_builtin_open, args, kw)
|
||||||
|
win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
|
||||||
|
win32con.HANDLE_FLAG_INHERIT,
|
||||||
|
0)
|
||||||
|
return fp
|
||||||
|
|
||||||
|
__builtin__.file = _scons_file
|
||||||
|
__builtin__.open = _scons_open
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The upshot of all this is that, if you are using Python 1.5.2,
|
# The upshot of all this is that, if you are using Python 1.5.2,
|
||||||
# you had better have cmd or command.com in your PATH when you run
|
# you had better have cmd or command.com in your PATH when you run
|
||||||
# scons.
|
# scons.
|
|
@ -26,7 +26,9 @@ Autoconf-like configuration support.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/SConf.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/SConf.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -46,10 +48,20 @@ import SCons.Util
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
import SCons.Conftest
|
import SCons.Conftest
|
||||||
|
|
||||||
|
from SCons.Debug import Trace
|
||||||
|
|
||||||
# Turn off the Conftest error logging
|
# Turn off the Conftest error logging
|
||||||
SCons.Conftest.LogInputFiles = 0
|
SCons.Conftest.LogInputFiles = 0
|
||||||
SCons.Conftest.LogErrorMessages = 0
|
SCons.Conftest.LogErrorMessages = 0
|
||||||
|
|
||||||
|
# Set
|
||||||
|
build_type = None
|
||||||
|
build_types = ['clean', 'help']
|
||||||
|
|
||||||
|
def SetBuildType(type):
|
||||||
|
global build_type
|
||||||
|
build_type = type
|
||||||
|
|
||||||
# to be set, if we are in dry-run mode
|
# to be set, if we are in dry-run mode
|
||||||
dryrun = 0
|
dryrun = 0
|
||||||
|
|
||||||
|
@ -158,12 +170,10 @@ class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
|
||||||
"""
|
"""
|
||||||
result = None # -> 0/None -> no error, != 0 error
|
result = None # -> 0/None -> no error, != 0 error
|
||||||
string = None # the stdout / stderr output when building the target
|
string = None # the stdout / stderr output when building the target
|
||||||
|
|
||||||
def __init__(self, node, result, string, sig):
|
def set_build_result(self, result, string):
|
||||||
SCons.Node.FS.FileBuildInfo.__init__(self, node)
|
|
||||||
self.result = result
|
self.result = result
|
||||||
self.string = string
|
self.string = string
|
||||||
self.ninfo.bsig = sig
|
|
||||||
|
|
||||||
|
|
||||||
class Streamer:
|
class Streamer:
|
||||||
|
@ -211,7 +221,7 @@ class SConfBuildTask(SCons.Taskmaster.Task):
|
||||||
"""
|
"""
|
||||||
if not isinstance(bi, SConfBuildInfo):
|
if not isinstance(bi, SConfBuildInfo):
|
||||||
SCons.Warnings.warn(SConfWarning,
|
SCons.Warnings.warn(SConfWarning,
|
||||||
"The stored build information has an unexpected class.")
|
"The stored build information has an unexpected class: %s" % bi.__class__)
|
||||||
else:
|
else:
|
||||||
self.display("The original builder output was:\n" +
|
self.display("The original builder output was:\n" +
|
||||||
string.replace(" |" + str(bi.string),
|
string.replace(" |" + str(bi.string),
|
||||||
|
@ -245,30 +255,39 @@ class SConfBuildTask(SCons.Taskmaster.Task):
|
||||||
# cached_error is 1, if the node(s) are up_to_date, but the
|
# cached_error is 1, if the node(s) are up_to_date, but the
|
||||||
# build will fail
|
# build will fail
|
||||||
# cachable is 0, if some nodes are not in our cache
|
# cachable is 0, if some nodes are not in our cache
|
||||||
is_up_to_date = 1
|
T = 0
|
||||||
cached_error = 0
|
changed = False
|
||||||
cachable = 1
|
cached_error = False
|
||||||
|
cachable = True
|
||||||
for t in self.targets:
|
for t in self.targets:
|
||||||
bi = t.get_stored_info()
|
if T: Trace('%s' % (t))
|
||||||
|
bi = t.get_stored_info().binfo
|
||||||
if isinstance(bi, SConfBuildInfo):
|
if isinstance(bi, SConfBuildInfo):
|
||||||
|
if T: Trace(': SConfBuildInfo')
|
||||||
if cache_mode == CACHE:
|
if cache_mode == CACHE:
|
||||||
t.set_state(SCons.Node.up_to_date)
|
t.set_state(SCons.Node.up_to_date)
|
||||||
|
if T: Trace(': set_state(up_to-date)')
|
||||||
else:
|
else:
|
||||||
new_bsig = t.calc_signature(sconf_global.calc)
|
if T: Trace(': get_state() %s' % t.get_state())
|
||||||
if t.env.use_build_signature():
|
if T: Trace(': changed() %s' % t.changed())
|
||||||
old_bsig = bi.ninfo.bsig
|
if (t.get_state() != SCons.Node.up_to_date and t.changed()):
|
||||||
else:
|
changed = True
|
||||||
old_bsig = bi.ninfo.csig
|
if T: Trace(': changed %s' % changed)
|
||||||
is_up_to_date = (is_up_to_date and new_bsig == old_bsig)
|
|
||||||
cached_error = cached_error or bi.result
|
cached_error = cached_error or bi.result
|
||||||
else:
|
else:
|
||||||
|
if T: Trace(': else')
|
||||||
# the node hasn't been built in a SConf context or doesn't
|
# the node hasn't been built in a SConf context or doesn't
|
||||||
# exist
|
# exist
|
||||||
cachable = 0
|
cachable = False
|
||||||
is_up_to_date = 0
|
changed = ( t.get_state() != SCons.Node.up_to_date )
|
||||||
return (is_up_to_date, cached_error, cachable)
|
if T: Trace(': changed %s' % changed)
|
||||||
|
if T: Trace('\n')
|
||||||
|
return (not changed, cached_error, cachable)
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
|
if not self.targets[0].has_builder():
|
||||||
|
return
|
||||||
|
|
||||||
sconf = sconf_global
|
sconf = sconf_global
|
||||||
|
|
||||||
is_up_to_date, cached_error, cachable = self.collect_node_states()
|
is_up_to_date, cached_error, cachable = self.collect_node_states()
|
||||||
|
@ -281,11 +300,13 @@ class SConfBuildTask(SCons.Taskmaster.Task):
|
||||||
if cached_error and is_up_to_date:
|
if cached_error and is_up_to_date:
|
||||||
self.display("Building \"%s\" failed in a previous run and all "
|
self.display("Building \"%s\" failed in a previous run and all "
|
||||||
"its sources are up to date." % str(self.targets[0]))
|
"its sources are up to date." % str(self.targets[0]))
|
||||||
self.display_cached_string(self.targets[0].get_stored_info())
|
binfo = self.targets[0].get_stored_info().binfo
|
||||||
|
self.display_cached_string(binfo)
|
||||||
raise SCons.Errors.BuildError # will be 'caught' in self.failed
|
raise SCons.Errors.BuildError # will be 'caught' in self.failed
|
||||||
elif is_up_to_date:
|
elif is_up_to_date:
|
||||||
self.display("\"%s\" is up to date." % str(self.targets[0]))
|
self.display("\"%s\" is up to date." % str(self.targets[0]))
|
||||||
self.display_cached_string(self.targets[0].get_stored_info())
|
binfo = self.targets[0].get_stored_info().binfo
|
||||||
|
self.display_cached_string(binfo)
|
||||||
elif dryrun:
|
elif dryrun:
|
||||||
raise ConfigureDryRunError(self.targets[0])
|
raise ConfigureDryRunError(self.targets[0])
|
||||||
else:
|
else:
|
||||||
|
@ -305,21 +326,43 @@ class SConfBuildTask(SCons.Taskmaster.Task):
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
exc_value = sys.exc_info()[1]
|
exc_value = sys.exc_info()[1]
|
||||||
raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
|
raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
|
||||||
except:
|
except Exception, e:
|
||||||
for t in self.targets:
|
for t in self.targets:
|
||||||
sig = t.calc_signature(sconf.calc)
|
binfo = t.get_binfo()
|
||||||
string = s.getvalue()
|
binfo.__class__ = SConfBuildInfo
|
||||||
binfo = SConfBuildInfo(t,1,string,sig)
|
binfo.set_build_result(1, s.getvalue())
|
||||||
t.dir.sconsign().set_entry(t.name, binfo)
|
sconsign_entry = SCons.SConsign.SConsignEntry()
|
||||||
raise
|
sconsign_entry.binfo = binfo
|
||||||
|
#sconsign_entry.ninfo = self.get_ninfo()
|
||||||
|
# We'd like to do this as follows:
|
||||||
|
# t.store_info(binfo)
|
||||||
|
# However, we need to store it as an SConfBuildInfo
|
||||||
|
# object, and store_info() will turn it into a
|
||||||
|
# regular FileNodeInfo if the target is itself a
|
||||||
|
# regular File.
|
||||||
|
sconsign = t.dir.sconsign()
|
||||||
|
sconsign.set_entry(t.name, sconsign_entry)
|
||||||
|
sconsign.merge()
|
||||||
|
raise e
|
||||||
else:
|
else:
|
||||||
for t in self.targets:
|
for t in self.targets:
|
||||||
sig = t.calc_signature(sconf.calc)
|
binfo = t.get_binfo()
|
||||||
string = s.getvalue()
|
binfo.__class__ = SConfBuildInfo
|
||||||
binfo = SConfBuildInfo(t,0,string,sig)
|
binfo.set_build_result(0, s.getvalue())
|
||||||
t.dir.sconsign().set_entry(t.name, binfo)
|
sconsign_entry = SCons.SConsign.SConsignEntry()
|
||||||
|
sconsign_entry.binfo = binfo
|
||||||
|
#sconsign_entry.ninfo = self.get_ninfo()
|
||||||
|
# We'd like to do this as follows:
|
||||||
|
# t.store_info(binfo)
|
||||||
|
# However, we need to store it as an SConfBuildInfo
|
||||||
|
# object, and store_info() will turn it into a
|
||||||
|
# regular FileNodeInfo if the target is itself a
|
||||||
|
# regular File.
|
||||||
|
sconsign = t.dir.sconsign()
|
||||||
|
sconsign.set_entry(t.name, sconsign_entry)
|
||||||
|
sconsign.merge()
|
||||||
|
|
||||||
class SConf:
|
class SConfBase:
|
||||||
"""This is simply a class to represent a configure context. After
|
"""This is simply a class to represent a configure context. After
|
||||||
creating a SConf object, you can call any tests. After finished with your
|
creating a SConf object, you can call any tests. After finished with your
|
||||||
tests, be sure to call the Finish() method, which returns the modified
|
tests, be sure to call the Finish() method, which returns the modified
|
||||||
|
@ -360,6 +403,7 @@ class SConf:
|
||||||
default_tests = {
|
default_tests = {
|
||||||
'CheckFunc' : CheckFunc,
|
'CheckFunc' : CheckFunc,
|
||||||
'CheckType' : CheckType,
|
'CheckType' : CheckType,
|
||||||
|
'CheckTypeSize' : CheckTypeSize,
|
||||||
'CheckHeader' : CheckHeader,
|
'CheckHeader' : CheckHeader,
|
||||||
'CheckCHeader' : CheckCHeader,
|
'CheckCHeader' : CheckCHeader,
|
||||||
'CheckCXXHeader' : CheckCXXHeader,
|
'CheckCXXHeader' : CheckCXXHeader,
|
||||||
|
@ -369,7 +413,6 @@ class SConf:
|
||||||
self.AddTests(default_tests)
|
self.AddTests(default_tests)
|
||||||
self.AddTests(custom_tests)
|
self.AddTests(custom_tests)
|
||||||
self.confdir = SConfFS.Dir(env.subst(conf_dir))
|
self.confdir = SConfFS.Dir(env.subst(conf_dir))
|
||||||
self.calc = None
|
|
||||||
if not config_h is None:
|
if not config_h is None:
|
||||||
config_h = SConfFS.File(config_h)
|
config_h = SConfFS.File(config_h)
|
||||||
self.config_h = config_h
|
self.config_h = config_h
|
||||||
|
@ -377,7 +420,8 @@ class SConf:
|
||||||
|
|
||||||
def Finish(self):
|
def Finish(self):
|
||||||
"""Call this method after finished with your tests:
|
"""Call this method after finished with your tests:
|
||||||
env = sconf.Finish()"""
|
env = sconf.Finish()
|
||||||
|
"""
|
||||||
self._shutdown()
|
self._shutdown()
|
||||||
return self.env
|
return self.env
|
||||||
|
|
||||||
|
@ -398,6 +442,13 @@ class SConf:
|
||||||
old_os_dir = os.getcwd()
|
old_os_dir = os.getcwd()
|
||||||
SConfFS.chdir(SConfFS.Top, change_os_dir=1)
|
SConfFS.chdir(SConfFS.Top, change_os_dir=1)
|
||||||
|
|
||||||
|
# Because we take responsibility here for writing out our
|
||||||
|
# own .sconsign info (see SConfBuildTask.execute(), above),
|
||||||
|
# we override the store_info() method with a null place-holder
|
||||||
|
# so we really control how it gets written.
|
||||||
|
for n in nodes:
|
||||||
|
n.store_info = n.do_not_store_info
|
||||||
|
|
||||||
ret = 1
|
ret = 1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -561,7 +612,7 @@ class SConf:
|
||||||
def AddTest(self, test_name, test_instance):
|
def AddTest(self, test_name, test_instance):
|
||||||
"""Adds test_class to this SConf instance. It can be called with
|
"""Adds test_class to this SConf instance. It can be called with
|
||||||
self.test_name(...)"""
|
self.test_name(...)"""
|
||||||
setattr(self, test_name, SConf.TestWrapper(test_instance, self))
|
setattr(self, test_name, SConfBase.TestWrapper(test_instance, self))
|
||||||
|
|
||||||
def AddTests(self, tests):
|
def AddTests(self, tests):
|
||||||
"""Adds all the tests given in the tests dictionary to this SConf
|
"""Adds all the tests given in the tests dictionary to this SConf
|
||||||
|
@ -773,6 +824,19 @@ class CheckContext:
|
||||||
#### End of stuff used by Conftest.py.
|
#### End of stuff used by Conftest.py.
|
||||||
|
|
||||||
|
|
||||||
|
def SConf(*args, **kw):
|
||||||
|
if kw.get(build_type, True):
|
||||||
|
kw['_depth'] = kw.get('_depth', 0) + 1
|
||||||
|
for bt in build_types:
|
||||||
|
try:
|
||||||
|
del kw[bt]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
return apply(SConfBase, args, kw)
|
||||||
|
else:
|
||||||
|
return SCons.Util.Null()
|
||||||
|
|
||||||
|
|
||||||
def CheckFunc(context, function_name, header = None, language = None):
|
def CheckFunc(context, function_name, header = None, language = None):
|
||||||
res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language)
|
res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language)
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
|
@ -784,6 +848,13 @@ def CheckType(context, type_name, includes = "", language = None):
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
return not res
|
return not res
|
||||||
|
|
||||||
|
def CheckTypeSize(context, type_name, includes = "", language = None, expect = None):
|
||||||
|
res = SCons.Conftest.CheckTypeSize(context, type_name,
|
||||||
|
header = includes, language = language,
|
||||||
|
expect = expect)
|
||||||
|
context.did_show_result = 1
|
||||||
|
return res
|
||||||
|
|
||||||
def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'):
|
def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'):
|
||||||
# used by CheckHeader and CheckLibWithHeader to produce C - #include
|
# used by CheckHeader and CheckLibWithHeader to produce C - #include
|
||||||
# statements from the specified header (list)
|
# statements from the specified header (list)
|
|
@ -27,14 +27,15 @@ Writing and reading information to the .sconsign file or files.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/SConsign.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/SConsign.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
|
|
||||||
import cPickle
|
import cPickle
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import SCons.dblite
|
import SCons.dblite
|
||||||
import SCons.Sig
|
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
|
|
||||||
def corrupt_dblite_warning(filename):
|
def corrupt_dblite_warning(filename):
|
||||||
|
@ -107,6 +108,24 @@ def write():
|
||||||
else:
|
else:
|
||||||
syncmethod()
|
syncmethod()
|
||||||
|
|
||||||
|
class SConsignEntry:
|
||||||
|
"""
|
||||||
|
Wrapper class for the generic entry in a .sconsign file.
|
||||||
|
The Node subclass populates it with attributes as it pleases.
|
||||||
|
|
||||||
|
XXX As coded below, we do expect a '.binfo' attribute to be added,
|
||||||
|
but we'll probably generalize this in the next refactorings.
|
||||||
|
"""
|
||||||
|
current_version_id = 1
|
||||||
|
def __init__(self):
|
||||||
|
# Create an object attribute from the class attribute so it ends up
|
||||||
|
# in the pickled data in the .sconsign file.
|
||||||
|
_version_id = self.current_version_id
|
||||||
|
def convert_to_sconsign(self):
|
||||||
|
self.binfo.convert_to_sconsign()
|
||||||
|
def convert_from_sconsign(self, dir, name):
|
||||||
|
self.binfo.convert_from_sconsign(dir, name)
|
||||||
|
|
||||||
class Base:
|
class Base:
|
||||||
"""
|
"""
|
||||||
This is the controlling class for the signatures for the collection of
|
This is the controlling class for the signatures for the collection of
|
||||||
|
@ -116,14 +135,10 @@ class Base:
|
||||||
methods for fetching and storing the individual bits of information
|
methods for fetching and storing the individual bits of information
|
||||||
that make up signature entry.
|
that make up signature entry.
|
||||||
"""
|
"""
|
||||||
def __init__(self, module=None):
|
def __init__(self):
|
||||||
"""
|
|
||||||
module - the signature module being used
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.module = module or SCons.Sig.default_calc.module
|
|
||||||
self.entries = {}
|
self.entries = {}
|
||||||
self.dirty = 0
|
self.dirty = False
|
||||||
|
self.to_be_merged = {}
|
||||||
|
|
||||||
def get_entry(self, filename):
|
def get_entry(self, filename):
|
||||||
"""
|
"""
|
||||||
|
@ -136,19 +151,43 @@ class Base:
|
||||||
Set the entry.
|
Set the entry.
|
||||||
"""
|
"""
|
||||||
self.entries[filename] = obj
|
self.entries[filename] = obj
|
||||||
self.dirty = 1
|
self.dirty = True
|
||||||
|
|
||||||
def do_not_set_entry(self, filename, obj):
|
def do_not_set_entry(self, filename, obj):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def store_info(self, filename, node):
|
||||||
|
entry = node.get_stored_info()
|
||||||
|
entry.binfo.merge(node.get_binfo())
|
||||||
|
self.to_be_merged[filename] = node
|
||||||
|
self.dirty = True
|
||||||
|
|
||||||
|
def do_not_store_info(self, filename, node):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def merge(self):
|
||||||
|
for key, node in self.to_be_merged.items():
|
||||||
|
entry = node.get_stored_info()
|
||||||
|
try:
|
||||||
|
ninfo = entry.ninfo
|
||||||
|
except AttributeError:
|
||||||
|
# This happens with SConf Nodes, because the configuration
|
||||||
|
# subsystem takes direct control over how the build decision
|
||||||
|
# is made and its information stored.
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
ninfo.merge(node.get_ninfo())
|
||||||
|
self.entries[key] = entry
|
||||||
|
self.to_be_merged = {}
|
||||||
|
|
||||||
class DB(Base):
|
class DB(Base):
|
||||||
"""
|
"""
|
||||||
A Base subclass that reads and writes signature information
|
A Base subclass that reads and writes signature information
|
||||||
from a global .sconsign.db* file--the actual file suffix is
|
from a global .sconsign.db* file--the actual file suffix is
|
||||||
determined by the specified database module.
|
determined by the database module.
|
||||||
"""
|
"""
|
||||||
def __init__(self, dir, module=None):
|
def __init__(self, dir):
|
||||||
Base.__init__(self, module)
|
Base.__init__(self)
|
||||||
|
|
||||||
self.dir = dir
|
self.dir = dir
|
||||||
|
|
||||||
|
@ -182,6 +221,7 @@ class DB(Base):
|
||||||
# a file there. Don't actually set any entry info, so we
|
# a file there. Don't actually set any entry info, so we
|
||||||
# won't try to write to that .sconsign.dblite file.
|
# won't try to write to that .sconsign.dblite file.
|
||||||
self.set_entry = self.do_not_set_entry
|
self.set_entry = self.do_not_set_entry
|
||||||
|
self.store_info = self.do_not_store_info
|
||||||
|
|
||||||
global sig_files
|
global sig_files
|
||||||
sig_files.append(self)
|
sig_files.append(self)
|
||||||
|
@ -190,6 +230,8 @@ class DB(Base):
|
||||||
if not self.dirty:
|
if not self.dirty:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.merge()
|
||||||
|
|
||||||
db, mode = Get_DataBase(self.dir)
|
db, mode = Get_DataBase(self.dir)
|
||||||
|
|
||||||
# Write using the path relative to the top of the SConstruct
|
# Write using the path relative to the top of the SConstruct
|
||||||
|
@ -211,27 +253,31 @@ class DB(Base):
|
||||||
syncmethod()
|
syncmethod()
|
||||||
|
|
||||||
class Dir(Base):
|
class Dir(Base):
|
||||||
def __init__(self, fp=None, module=None):
|
def __init__(self, fp=None, dir=None):
|
||||||
"""
|
"""
|
||||||
fp - file pointer to read entries from
|
fp - file pointer to read entries from
|
||||||
module - the signature module being used
|
|
||||||
"""
|
"""
|
||||||
Base.__init__(self, module)
|
Base.__init__(self)
|
||||||
|
|
||||||
if fp:
|
if not fp:
|
||||||
self.entries = cPickle.load(fp)
|
return
|
||||||
if type(self.entries) is not type({}):
|
|
||||||
self.entries = {}
|
self.entries = cPickle.load(fp)
|
||||||
raise TypeError
|
if type(self.entries) is not type({}):
|
||||||
|
self.entries = {}
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
if dir:
|
||||||
|
for key, entry in self.entries.items():
|
||||||
|
entry.convert_from_sconsign(dir, key)
|
||||||
|
|
||||||
class DirFile(Dir):
|
class DirFile(Dir):
|
||||||
"""
|
"""
|
||||||
Encapsulates reading and writing a per-directory .sconsign file.
|
Encapsulates reading and writing a per-directory .sconsign file.
|
||||||
"""
|
"""
|
||||||
def __init__(self, dir, module=None):
|
def __init__(self, dir):
|
||||||
"""
|
"""
|
||||||
dir - the directory for the file
|
dir - the directory for the file
|
||||||
module - the signature module being used
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.dir = dir
|
self.dir = dir
|
||||||
|
@ -243,7 +289,7 @@ class DirFile(Dir):
|
||||||
fp = None
|
fp = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
Dir.__init__(self, fp, module)
|
Dir.__init__(self, fp, dir)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
|
@ -253,15 +299,6 @@ class DirFile(Dir):
|
||||||
global sig_files
|
global sig_files
|
||||||
sig_files.append(self)
|
sig_files.append(self)
|
||||||
|
|
||||||
def get_entry(self, filename):
|
|
||||||
"""
|
|
||||||
Fetch the specified entry attribute, converting from .sconsign
|
|
||||||
format to in-memory format.
|
|
||||||
"""
|
|
||||||
entry = Dir.get_entry(self, filename)
|
|
||||||
entry.convert_from_sconsign(self.dir, filename)
|
|
||||||
return entry
|
|
||||||
|
|
||||||
def write(self, sync=1):
|
def write(self, sync=1):
|
||||||
"""
|
"""
|
||||||
Write the .sconsign file to disk.
|
Write the .sconsign file to disk.
|
||||||
|
@ -275,48 +312,52 @@ class DirFile(Dir):
|
||||||
to the .sconsign file. Either way, always try to remove
|
to the .sconsign file. Either way, always try to remove
|
||||||
the temporary file at the end.
|
the temporary file at the end.
|
||||||
"""
|
"""
|
||||||
if self.dirty:
|
if not self.dirty:
|
||||||
temp = os.path.join(self.dir.path, '.scons%d' % os.getpid())
|
return
|
||||||
|
|
||||||
|
self.merge()
|
||||||
|
|
||||||
|
temp = os.path.join(self.dir.path, '.scons%d' % os.getpid())
|
||||||
|
try:
|
||||||
|
file = open(temp, 'wb')
|
||||||
|
fname = temp
|
||||||
|
except IOError:
|
||||||
try:
|
try:
|
||||||
file = open(temp, 'wb')
|
file = open(self.sconsign, 'wb')
|
||||||
fname = temp
|
fname = self.sconsign
|
||||||
except IOError:
|
except IOError:
|
||||||
try:
|
return
|
||||||
file = open(self.sconsign, 'wb')
|
for key, entry in self.entries.items():
|
||||||
fname = self.sconsign
|
entry.convert_to_sconsign()
|
||||||
except IOError:
|
cPickle.dump(self.entries, file, 1)
|
||||||
return
|
file.close()
|
||||||
for key, entry in self.entries.items():
|
if fname != self.sconsign:
|
||||||
entry.convert_to_sconsign()
|
|
||||||
cPickle.dump(self.entries, file, 1)
|
|
||||||
file.close()
|
|
||||||
if fname != self.sconsign:
|
|
||||||
try:
|
|
||||||
mode = os.stat(self.sconsign)[0]
|
|
||||||
os.chmod(self.sconsign, 0666)
|
|
||||||
os.unlink(self.sconsign)
|
|
||||||
except (IOError, OSError):
|
|
||||||
# Try to carry on in the face of either OSError
|
|
||||||
# (things like permission issues) or IOError (disk
|
|
||||||
# or network issues). If there's a really dangerous
|
|
||||||
# issue, it should get re-raised by the calls below.
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
os.rename(fname, self.sconsign)
|
|
||||||
except OSError:
|
|
||||||
# An OSError failure to rename may indicate something
|
|
||||||
# like the directory has no write permission, but
|
|
||||||
# the .sconsign file itself might still be writable,
|
|
||||||
# so try writing on top of it directly. An IOError
|
|
||||||
# here, or in any of the following calls, would get
|
|
||||||
# raised, indicating something like a potentially
|
|
||||||
# serious disk or network issue.
|
|
||||||
open(self.sconsign, 'wb').write(open(fname, 'rb').read())
|
|
||||||
os.chmod(self.sconsign, mode)
|
|
||||||
try:
|
try:
|
||||||
os.unlink(temp)
|
mode = os.stat(self.sconsign)[0]
|
||||||
|
os.chmod(self.sconsign, 0666)
|
||||||
|
os.unlink(self.sconsign)
|
||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
|
# Try to carry on in the face of either OSError
|
||||||
|
# (things like permission issues) or IOError (disk
|
||||||
|
# or network issues). If there's a really dangerous
|
||||||
|
# issue, it should get re-raised by the calls below.
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
os.rename(fname, self.sconsign)
|
||||||
|
except OSError:
|
||||||
|
# An OSError failure to rename may indicate something
|
||||||
|
# like the directory has no write permission, but
|
||||||
|
# the .sconsign file itself might still be writable,
|
||||||
|
# so try writing on top of it directly. An IOError
|
||||||
|
# here, or in any of the following calls, would get
|
||||||
|
# raised, indicating something like a potentially
|
||||||
|
# serious disk or network issue.
|
||||||
|
open(self.sconsign, 'wb').write(open(fname, 'rb').read())
|
||||||
|
os.chmod(self.sconsign, mode)
|
||||||
|
try:
|
||||||
|
os.unlink(temp)
|
||||||
|
except (IOError, OSError):
|
||||||
|
pass
|
||||||
|
|
||||||
ForDirectory = DB
|
ForDirectory = DB
|
||||||
|
|
|
@ -27,7 +27,7 @@ This module implements the depenency scanner for C/C++ code.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/C.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Scanner/C.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
|
@ -30,7 +30,7 @@ Coded by Andy Friesen
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/D.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Scanner/D.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/Dir.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Scanner/Dir.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for Fortran code.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/Fortran.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Scanner/Fortran.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
|
@ -28,7 +28,7 @@ Definition Language) files.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/IDL.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Scanner/IDL.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
|
@ -27,19 +27,19 @@ This module implements the dependency scanner for LaTeX code.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/LaTeX.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Scanner/LaTeX.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
import string
|
||||||
|
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
import string
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
def LaTeXScanner(fs = SCons.Node.FS.default_fs):
|
def LaTeXScanner():
|
||||||
"""Return a prototype Scanner instance for scanning LaTeX source files"""
|
"""Return a prototype Scanner instance for scanning LaTeX source files"""
|
||||||
ds = LaTeX(name = "LaTeXScanner",
|
ds = LaTeX(name = "LaTeXScanner",
|
||||||
suffixes = '$LATEXSUFFIXES',
|
suffixes = '$LATEXSUFFIXES',
|
||||||
path_variable = 'TEXINPUTS',
|
path_variable = 'TEXINPUTS',
|
||||||
regex = '\\\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography){([^}]*)}',
|
regex = '\\\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography|usepackage){([^}]*)}',
|
||||||
recursive = 0)
|
recursive = 0)
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
|
@ -72,6 +72,10 @@ class LaTeX(SCons.Scanner.Classic):
|
||||||
base, ext = os.path.splitext( filename )
|
base, ext = os.path.splitext( filename )
|
||||||
if ext == "":
|
if ext == "":
|
||||||
filename = filename + '.bib'
|
filename = filename + '.bib'
|
||||||
|
if include[0] == 'usepackage':
|
||||||
|
base, ext = os.path.splitext( filename )
|
||||||
|
if ext == "":
|
||||||
|
filename = filename + '.sty'
|
||||||
return filename
|
return filename
|
||||||
def sort_key(self, include):
|
def sort_key(self, include):
|
||||||
return SCons.Node.FS._my_normcase(self.latex_name(include))
|
return SCons.Node.FS._my_normcase(self.latex_name(include))
|
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/Prog.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Scanner/Prog.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
|
@ -27,13 +27,12 @@ The Scanner package for the SCons software construction utility.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Scanner/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Sig
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,8 +305,7 @@ class Current(Base):
|
||||||
|
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
def current_check(node, env):
|
def current_check(node, env):
|
||||||
c = not node.has_builder() or node.current(env.get_calculator())
|
return not node.has_builder() or node.is_up_to_date()
|
||||||
return c
|
|
||||||
kw['scan_check'] = current_check
|
kw['scan_check'] = current_check
|
||||||
apply(Base.__init__, (self,) + args, kw)
|
apply(Base.__init__, (self,) + args, kw)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
884
scons/scons-local-0.97.0d20071212/SCons/Script/SConsOptions.py
Normal file
884
scons/scons-local-0.97.0d20071212/SCons/Script/SConsOptions.py
Normal file
|
@ -0,0 +1,884 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
# a copy of this software and associated documentation files (the
|
||||||
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
# without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
# the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included
|
||||||
|
# in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
# 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__ = "src/engine/SCons/Script/SConsOptions.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
|
|
||||||
|
import optparse
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
try:
|
||||||
|
from gettext import gettext
|
||||||
|
except ImportError:
|
||||||
|
def gettext(message):
|
||||||
|
return message
|
||||||
|
_ = gettext
|
||||||
|
|
||||||
|
import SCons.Node.FS
|
||||||
|
|
||||||
|
OptionValueError = optparse.OptionValueError
|
||||||
|
SUPPRESS_HELP = optparse.SUPPRESS_HELP
|
||||||
|
|
||||||
|
diskcheck_all = SCons.Node.FS.diskcheck_types()
|
||||||
|
|
||||||
|
def diskcheck_convert(value):
|
||||||
|
if value is None:
|
||||||
|
return []
|
||||||
|
if not SCons.Util.is_List(value):
|
||||||
|
value = string.split(value, ',')
|
||||||
|
result = []
|
||||||
|
for v in map(string.lower, value):
|
||||||
|
if v == 'all':
|
||||||
|
result = diskcheck_all
|
||||||
|
elif v == 'none':
|
||||||
|
result = []
|
||||||
|
elif v in diskcheck_all:
|
||||||
|
result.append(v)
|
||||||
|
else:
|
||||||
|
raise ValueError, v
|
||||||
|
return result
|
||||||
|
|
||||||
|
class SConsValues(optparse.Values):
|
||||||
|
"""
|
||||||
|
Holder class for uniform access to SCons options, regardless
|
||||||
|
of whether or not they can be set on the command line or in the
|
||||||
|
SConscript files (using the SetOption() function).
|
||||||
|
|
||||||
|
A SCons option value can originate three different ways:
|
||||||
|
|
||||||
|
1) set on the command line;
|
||||||
|
2) set in an SConscript file;
|
||||||
|
3) the default setting (from the the op.add_option()
|
||||||
|
calls in the Parser() function, below).
|
||||||
|
|
||||||
|
The command line always overrides a value set in a SConscript file,
|
||||||
|
which in turn always overrides default settings. Because we want
|
||||||
|
to support user-specified options in the SConscript file itself,
|
||||||
|
though, we may not know about all of the options when the command
|
||||||
|
line is first parsed, so we can't make all the necessary precedence
|
||||||
|
decisions at the time the option is configured.
|
||||||
|
|
||||||
|
The solution implemented in this class is to keep these different sets
|
||||||
|
of settings separate (command line, SConscript file, and default)
|
||||||
|
and to override the __getattr__() method to check them in turn.
|
||||||
|
This should allow the rest of the code to just fetch values as
|
||||||
|
attributes of an instance of this class, without having to worry
|
||||||
|
about where they came from.
|
||||||
|
|
||||||
|
Note that not all command line options are settable from SConscript
|
||||||
|
files, and the ones that are must be explicitly added to the
|
||||||
|
"settable" list in this class, and optionally validated and coerced
|
||||||
|
in the set_option() method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, defaults):
|
||||||
|
self.__dict__['__defaults__'] = defaults
|
||||||
|
self.__dict__['__SConscript_settings__'] = {}
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
"""
|
||||||
|
Fetches an options value, checking first for explicit settings
|
||||||
|
from the command line (which are direct attributes), then the
|
||||||
|
SConscript file settings, then the default values.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self.__dict__[attr]
|
||||||
|
except KeyError:
|
||||||
|
try:
|
||||||
|
return self.__dict__['__SConscript_settings__'][attr]
|
||||||
|
except KeyError:
|
||||||
|
return getattr(self.__dict__['__defaults__'], attr)
|
||||||
|
|
||||||
|
settable = [
|
||||||
|
'clean',
|
||||||
|
'diskcheck',
|
||||||
|
'duplicate',
|
||||||
|
'help',
|
||||||
|
'implicit_cache',
|
||||||
|
'max_drift',
|
||||||
|
'no_exec',
|
||||||
|
'num_jobs',
|
||||||
|
'random',
|
||||||
|
]
|
||||||
|
|
||||||
|
def set_option(self, name, value):
|
||||||
|
"""
|
||||||
|
Sets an option from an SConscript file.
|
||||||
|
"""
|
||||||
|
if not name in self.settable:
|
||||||
|
raise SCons.Errors.UserError, "This option is not settable from a SConscript file: %s"%name
|
||||||
|
|
||||||
|
if name == 'num_jobs':
|
||||||
|
try:
|
||||||
|
value = int(value)
|
||||||
|
if value < 1:
|
||||||
|
raise ValueError
|
||||||
|
except ValueError:
|
||||||
|
raise SCons.Errors.UserError, "A positive integer is required: %s"%repr(value)
|
||||||
|
elif name == 'max_drift':
|
||||||
|
try:
|
||||||
|
value = int(value)
|
||||||
|
except ValueError:
|
||||||
|
raise SCons.Errors.UserError, "An integer is required: %s"%repr(value)
|
||||||
|
elif name == 'duplicate':
|
||||||
|
try:
|
||||||
|
value = str(value)
|
||||||
|
except ValueError:
|
||||||
|
raise SCons.Errors.UserError, "A string is required: %s"%repr(value)
|
||||||
|
if not value in SCons.Node.FS.Valid_Duplicates:
|
||||||
|
raise SCons.Errors.UserError, "Not a valid duplication style: %s" % value
|
||||||
|
# Set the duplicate style right away so it can affect linking
|
||||||
|
# of SConscript files.
|
||||||
|
SCons.Node.FS.set_duplicate(value)
|
||||||
|
elif name == 'diskcheck':
|
||||||
|
try:
|
||||||
|
value = diskcheck_convert(value)
|
||||||
|
except ValueError, v:
|
||||||
|
raise SCons.Errors.UserError, "Not a valid diskcheck value: %s"%v
|
||||||
|
if not self.__dict__.has_key('diskcheck'):
|
||||||
|
# No --diskcheck= option was specified on the command line.
|
||||||
|
# Set this right away so it can affect the rest of the
|
||||||
|
# file/Node lookups while processing the SConscript files.
|
||||||
|
SCons.Node.FS.set_diskcheck(value)
|
||||||
|
|
||||||
|
self.__SConscript_settings__[name] = value
|
||||||
|
|
||||||
|
class SConsOption(optparse.Option):
|
||||||
|
def convert_value(self, opt, value):
|
||||||
|
if value is not None:
|
||||||
|
if self.nargs in (1, '?'):
|
||||||
|
return self.check_value(opt, value)
|
||||||
|
else:
|
||||||
|
return tuple(map(lambda v, o=opt, s=self: s.check_value(o, v), value))
|
||||||
|
|
||||||
|
def process(self, opt, value, values, parser):
|
||||||
|
|
||||||
|
# First, convert the value(s) to the right type. Howl if any
|
||||||
|
# value(s) are bogus.
|
||||||
|
value = self.convert_value(opt, value)
|
||||||
|
|
||||||
|
# And then take whatever action is expected of us.
|
||||||
|
# This is a separate method to make life easier for
|
||||||
|
# subclasses to add new actions.
|
||||||
|
return self.take_action(
|
||||||
|
self.action, self.dest, opt, value, values, parser)
|
||||||
|
|
||||||
|
def _check_nargs_optional(self):
|
||||||
|
if self.nargs == '?' and self._short_opts:
|
||||||
|
fmt = "option %s: nargs='?' is incompatible with short options"
|
||||||
|
raise SCons.Errors.UserError, fmt % self._short_opts[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
_orig_CONST_ACTIONS = optparse.Option.CONST_ACTIONS
|
||||||
|
|
||||||
|
_orig_CHECK_METHODS = optparse.Option.CHECK_METHODS
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
# optparse.Option had no CONST_ACTIONS before Python 2.5.
|
||||||
|
|
||||||
|
_orig_CONST_ACTIONS = ("store_const",)
|
||||||
|
|
||||||
|
def _check_const(self):
|
||||||
|
if self.action not in self.CONST_ACTIONS and self.const is not None:
|
||||||
|
raise OptionError(
|
||||||
|
"'const' must not be supplied for action %r" % self.action,
|
||||||
|
self)
|
||||||
|
|
||||||
|
# optparse.Option collects its list of unbound check functions
|
||||||
|
# up front. This sucks because it means we can't just override
|
||||||
|
# the _check_const() function like a normal method, we have to
|
||||||
|
# actually replace it in the list. This seems to be the most
|
||||||
|
# straightforward way to do that.
|
||||||
|
|
||||||
|
_orig_CHECK_METHODS = [optparse.Option._check_action,
|
||||||
|
optparse.Option._check_type,
|
||||||
|
optparse.Option._check_choice,
|
||||||
|
optparse.Option._check_dest,
|
||||||
|
_check_const,
|
||||||
|
optparse.Option._check_nargs,
|
||||||
|
optparse.Option._check_callback]
|
||||||
|
|
||||||
|
CHECK_METHODS = _orig_CHECK_METHODS + [_check_nargs_optional]
|
||||||
|
|
||||||
|
CONST_ACTIONS = _orig_CONST_ACTIONS + optparse.Option.TYPED_ACTIONS
|
||||||
|
|
||||||
|
class SConsOptionGroup(optparse.OptionGroup):
|
||||||
|
"""
|
||||||
|
A subclass for SCons-specific option groups.
|
||||||
|
|
||||||
|
The only difference between this and the base class is that we print
|
||||||
|
the group's help text flush left, underneath their own title but
|
||||||
|
lined up with the normal "SCons Options".
|
||||||
|
"""
|
||||||
|
def format_help(self, formatter):
|
||||||
|
"""
|
||||||
|
Format an option group's help text, outdenting the title so it's
|
||||||
|
flush with the "SCons Options" title we print at the top.
|
||||||
|
"""
|
||||||
|
formatter.dedent()
|
||||||
|
result = formatter.format_heading(self.title)
|
||||||
|
formatter.indent()
|
||||||
|
result = result + optparse.OptionContainer.format_help(self, formatter)
|
||||||
|
return result
|
||||||
|
|
||||||
|
class SConsOptionParser(optparse.OptionParser):
|
||||||
|
preserve_unknown_options = False
|
||||||
|
|
||||||
|
def error(self, msg):
|
||||||
|
self.print_usage(sys.stderr)
|
||||||
|
sys.stderr.write("SCons error: %s\n" % msg)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
def _process_long_opt(self, rargs, values):
|
||||||
|
"""
|
||||||
|
SCons-specific processing of long options.
|
||||||
|
|
||||||
|
This is copied directly from the normal
|
||||||
|
optparse._process_long_opt() method, except that, if configured
|
||||||
|
to do so, we catch the exception thrown when an unknown option
|
||||||
|
is encountered and just stick it back on the "leftover" arguments
|
||||||
|
for later (re-)processing.
|
||||||
|
"""
|
||||||
|
arg = rargs.pop(0)
|
||||||
|
|
||||||
|
# Value explicitly attached to arg? Pretend it's the next
|
||||||
|
# argument.
|
||||||
|
if "=" in arg:
|
||||||
|
(opt, next_arg) = string.split(arg, "=", 1)
|
||||||
|
rargs.insert(0, next_arg)
|
||||||
|
had_explicit_value = True
|
||||||
|
else:
|
||||||
|
opt = arg
|
||||||
|
had_explicit_value = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
opt = self._match_long_opt(opt)
|
||||||
|
except optparse.BadOptionError:
|
||||||
|
if self.preserve_unknown_options:
|
||||||
|
# SCons-specific: if requested, add unknown options to
|
||||||
|
# the "leftover arguments" list for later processing.
|
||||||
|
self.largs.append(arg)
|
||||||
|
if had_explicit_value:
|
||||||
|
# The unknown option will be re-processed later,
|
||||||
|
# so undo the insertion of the explicit value.
|
||||||
|
rargs.pop(0)
|
||||||
|
return
|
||||||
|
raise
|
||||||
|
|
||||||
|
option = self._long_opt[opt]
|
||||||
|
if option.takes_value():
|
||||||
|
nargs = option.nargs
|
||||||
|
if nargs == '?':
|
||||||
|
if had_explicit_value:
|
||||||
|
value = rargs.pop(0)
|
||||||
|
else:
|
||||||
|
value = option.const
|
||||||
|
elif len(rargs) < nargs:
|
||||||
|
if nargs == 1:
|
||||||
|
self.error(_("%s option requires an argument") % opt)
|
||||||
|
else:
|
||||||
|
self.error(_("%s option requires %d arguments")
|
||||||
|
% (opt, nargs))
|
||||||
|
elif nargs == 1:
|
||||||
|
value = rargs.pop(0)
|
||||||
|
else:
|
||||||
|
value = tuple(rargs[0:nargs])
|
||||||
|
del rargs[0:nargs]
|
||||||
|
|
||||||
|
elif had_explicit_value:
|
||||||
|
self.error(_("%s option does not take a value") % opt)
|
||||||
|
|
||||||
|
else:
|
||||||
|
value = None
|
||||||
|
|
||||||
|
option.process(opt, value, values, self)
|
||||||
|
|
||||||
|
def add_local_option(self, *args, **kw):
|
||||||
|
"""
|
||||||
|
Adds a local option to the parser.
|
||||||
|
|
||||||
|
This is initiated by a SetOption() call to add a user-defined
|
||||||
|
command-line option. We add the option to a separate option
|
||||||
|
group for the local options, creating the group if necessary.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
group = self.local_option_group
|
||||||
|
except AttributeError:
|
||||||
|
group = SConsOptionGroup(self, 'Local Options')
|
||||||
|
group = self.add_option_group(group)
|
||||||
|
self.local_option_group = group
|
||||||
|
|
||||||
|
result = apply(group.add_option, args, kw)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
# The option was added succesfully. We now have to add the
|
||||||
|
# default value to our object that holds the default values
|
||||||
|
# (so that an attempt to fetch the option's attribute will
|
||||||
|
# yield the default value when not overridden) and then
|
||||||
|
# we re-parse the leftover command-line options, so that
|
||||||
|
# any value overridden on the command line is immediately
|
||||||
|
# available if the user turns around and does a GetOption()
|
||||||
|
# right away.
|
||||||
|
setattr(self.values.__defaults__, result.dest, result.default)
|
||||||
|
self.parse_args(self.largs, self.values)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
|
||||||
|
def format_usage(self, usage):
|
||||||
|
return "usage: %s\n" % usage
|
||||||
|
|
||||||
|
def format_heading(self, heading):
|
||||||
|
"""
|
||||||
|
This translates any heading of "options" or "Options" into
|
||||||
|
"SCons Options." Unfortunately, we have to do this here,
|
||||||
|
because those titles are hard-coded in the optparse calls.
|
||||||
|
"""
|
||||||
|
if heading == 'options':
|
||||||
|
# The versions of optparse.py shipped with Pythons 2.3 and
|
||||||
|
# 2.4 pass this in uncapitalized; override that so we get
|
||||||
|
# consistent output on all versions.
|
||||||
|
heading = "Options"
|
||||||
|
if heading == 'Options':
|
||||||
|
heading = "SCons Options"
|
||||||
|
return optparse.IndentedHelpFormatter.format_heading(self, heading)
|
||||||
|
|
||||||
|
def format_option(self, option):
|
||||||
|
"""
|
||||||
|
A copy of the normal optparse.IndentedHelpFormatter.format_option()
|
||||||
|
method, snarfed so we can set the subsequent_indent on the
|
||||||
|
textwrap.wrap() call below...
|
||||||
|
"""
|
||||||
|
# The help for each option consists of two parts:
|
||||||
|
# * the opt strings and metavars
|
||||||
|
# eg. ("-x", or "-fFILENAME, --file=FILENAME")
|
||||||
|
# * the user-supplied help string
|
||||||
|
# eg. ("turn on expert mode", "read data from FILENAME")
|
||||||
|
#
|
||||||
|
# If possible, we write both of these on the same line:
|
||||||
|
# -x turn on expert mode
|
||||||
|
#
|
||||||
|
# But if the opt string list is too long, we put the help
|
||||||
|
# string on a second line, indented to the same column it would
|
||||||
|
# start in if it fit on the first line.
|
||||||
|
# -fFILENAME, --file=FILENAME
|
||||||
|
# read data from FILENAME
|
||||||
|
result = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
opts = self.option_strings[option]
|
||||||
|
except AttributeError:
|
||||||
|
# The Python 2.3 version of optparse attaches this to
|
||||||
|
# to the option argument, not to this object.
|
||||||
|
opts = option.option_strings
|
||||||
|
|
||||||
|
opt_width = self.help_position - self.current_indent - 2
|
||||||
|
if len(opts) > opt_width:
|
||||||
|
opts = "%*s%s\n" % (self.current_indent, "", opts)
|
||||||
|
indent_first = self.help_position
|
||||||
|
else: # start help on same line as opts
|
||||||
|
opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts)
|
||||||
|
indent_first = 0
|
||||||
|
result.append(opts)
|
||||||
|
if option.help:
|
||||||
|
|
||||||
|
try:
|
||||||
|
expand_default = self.expand_default
|
||||||
|
except AttributeError:
|
||||||
|
# The HelpFormatter base class in the Python 2.3 version
|
||||||
|
# of optparse has no expand_default() method.
|
||||||
|
help_text = option.help
|
||||||
|
else:
|
||||||
|
help_text = expand_default(option)
|
||||||
|
|
||||||
|
# SCons: indent every line of the help text but the first.
|
||||||
|
help_lines = textwrap.wrap(help_text, self.help_width,
|
||||||
|
subsequent_indent = ' ')
|
||||||
|
result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
|
||||||
|
for line in help_lines[1:]:
|
||||||
|
result.append("%*s%s\n" % (self.help_position, "", line))
|
||||||
|
elif opts[-1] != "\n":
|
||||||
|
result.append("\n")
|
||||||
|
return string.join(result, "")
|
||||||
|
|
||||||
|
# For consistent help output across Python versions, we provide a
|
||||||
|
# subclass copy of format_option_strings() and these two variables.
|
||||||
|
# This is necessary (?) for Python2.3, which otherwise concatenates
|
||||||
|
# a short option with its metavar.
|
||||||
|
_short_opt_fmt = "%s %s"
|
||||||
|
_long_opt_fmt = "%s=%s"
|
||||||
|
|
||||||
|
def format_option_strings(self, option):
|
||||||
|
"""Return a comma-separated list of option strings & metavariables."""
|
||||||
|
if option.takes_value():
|
||||||
|
metavar = option.metavar or string.upper(option.dest)
|
||||||
|
short_opts = []
|
||||||
|
for sopt in option._short_opts:
|
||||||
|
short_opts.append(self._short_opt_fmt % (sopt, metavar))
|
||||||
|
long_opts = []
|
||||||
|
for lopt in option._long_opts:
|
||||||
|
long_opts.append(self._long_opt_fmt % (lopt, metavar))
|
||||||
|
else:
|
||||||
|
short_opts = option._short_opts
|
||||||
|
long_opts = option._long_opts
|
||||||
|
|
||||||
|
if self.short_first:
|
||||||
|
opts = short_opts + long_opts
|
||||||
|
else:
|
||||||
|
opts = long_opts + short_opts
|
||||||
|
|
||||||
|
return string.join(opts, ", ")
|
||||||
|
|
||||||
|
def Parser(version):
|
||||||
|
"""
|
||||||
|
Returns an options parser object initialized with the standard
|
||||||
|
SCons options.
|
||||||
|
"""
|
||||||
|
|
||||||
|
formatter = SConsIndentedHelpFormatter(max_help_position=30)
|
||||||
|
|
||||||
|
op = SConsOptionParser(option_class=SConsOption,
|
||||||
|
add_help_option=False,
|
||||||
|
formatter=formatter,
|
||||||
|
usage="usage: scons [OPTION] [TARGET] ...",)
|
||||||
|
|
||||||
|
op.preserve_unknown_options = True
|
||||||
|
|
||||||
|
# Add the options to the parser we just created.
|
||||||
|
#
|
||||||
|
# These are in the order we want them to show up in the -H help
|
||||||
|
# text, basically alphabetical. Each op.add_option() call below
|
||||||
|
# should have a consistent format:
|
||||||
|
#
|
||||||
|
# op.add_option("-L", "--long-option-name",
|
||||||
|
# nargs=1, type="string",
|
||||||
|
# dest="long_option_name", default='foo',
|
||||||
|
# action="callback", callback=opt_long_option,
|
||||||
|
# help="help text goes here",
|
||||||
|
# metavar="VAR")
|
||||||
|
#
|
||||||
|
# Even though the optparse module constructs reasonable default
|
||||||
|
# destination names from the long option names, we're going to be
|
||||||
|
# explicit about each one for easier readability and so this code
|
||||||
|
# will at least show up when grepping the source for option attribute
|
||||||
|
# names, or otherwise browsing the source code.
|
||||||
|
|
||||||
|
# options ignored for compatibility
|
||||||
|
def opt_ignore(option, opt, value, parser):
|
||||||
|
sys.stderr.write("Warning: ignoring %s option\n" % opt)
|
||||||
|
op.add_option("-b", "-m", "-S", "-t",
|
||||||
|
"--no-keep-going", "--stop", "--touch",
|
||||||
|
action="callback", callback=opt_ignore,
|
||||||
|
help="Ignored for compatibility.")
|
||||||
|
|
||||||
|
op.add_option('-c', '--clean', '--remove',
|
||||||
|
dest="clean", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Remove specified targets and dependencies.")
|
||||||
|
|
||||||
|
op.add_option('-C', '--directory',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="directory", default=[],
|
||||||
|
action="append",
|
||||||
|
help="Change to DIR before doing anything.",
|
||||||
|
metavar="DIR")
|
||||||
|
|
||||||
|
op.add_option('--cache-debug',
|
||||||
|
nargs=1,
|
||||||
|
dest="cache_debug", default=None,
|
||||||
|
action="store",
|
||||||
|
help="Print CacheDir debug info to FILE.",
|
||||||
|
metavar="FILE")
|
||||||
|
|
||||||
|
op.add_option('--cache-disable', '--no-cache',
|
||||||
|
dest='cache_disable', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Do not retrieve built targets from CacheDir.")
|
||||||
|
|
||||||
|
op.add_option('--cache-force', '--cache-populate',
|
||||||
|
dest='cache_force', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Copy already-built targets into the CacheDir.")
|
||||||
|
|
||||||
|
op.add_option('--cache-show',
|
||||||
|
dest='cache_show', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Print build actions for files from CacheDir.")
|
||||||
|
|
||||||
|
config_options = ["auto", "force" ,"cache"]
|
||||||
|
|
||||||
|
def opt_config(option, opt, value, parser, c_options=config_options):
|
||||||
|
if not value in c_options:
|
||||||
|
raise OptionValueError("Warning: %s is not a valid config type" % value)
|
||||||
|
setattr(parser.values, option.dest, value)
|
||||||
|
opt_config_help = "Controls Configure subsystem: %s." \
|
||||||
|
% string.join(config_options, ", ")
|
||||||
|
op.add_option('--config',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="config", default="auto",
|
||||||
|
action="callback", callback=opt_config,
|
||||||
|
help = opt_config_help,
|
||||||
|
metavar="MODE")
|
||||||
|
|
||||||
|
def opt_not_yet(option, opt, value, parser):
|
||||||
|
sys.stderr.write("Warning: the %s option is not yet implemented\n" % opt)
|
||||||
|
sys.exit(0)
|
||||||
|
op.add_option('-d',
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
help = "Print file dependency information.")
|
||||||
|
|
||||||
|
op.add_option('-D',
|
||||||
|
dest="climb_up", default=None,
|
||||||
|
action="store_const", const=2,
|
||||||
|
help="Search up directory tree for SConstruct, "
|
||||||
|
"build all Default() targets.")
|
||||||
|
|
||||||
|
debug_options = ["count", "dtree", "explain", "findlibs",
|
||||||
|
"includes", "memoizer", "memory", "objects",
|
||||||
|
"pdb", "presub", "stacktrace", "stree",
|
||||||
|
"time", "tree"]
|
||||||
|
|
||||||
|
deprecated_debug_options = {
|
||||||
|
"nomemoizer" : ' and has no effect',
|
||||||
|
}
|
||||||
|
|
||||||
|
def opt_debug(option, opt, value, parser,
|
||||||
|
debug_options=debug_options,
|
||||||
|
deprecated_debug_options=deprecated_debug_options):
|
||||||
|
if value in debug_options:
|
||||||
|
parser.values.debug.append(value)
|
||||||
|
elif value in deprecated_debug_options.keys():
|
||||||
|
try:
|
||||||
|
parser.values.delayed_warnings
|
||||||
|
except AttributeError:
|
||||||
|
parser.values.delayed_warnings = []
|
||||||
|
msg = deprecated_debug_options[value]
|
||||||
|
w = "The --debug=%s option is deprecated%s." % (value, msg)
|
||||||
|
t = (SCons.Warnings.DeprecatedWarning, w)
|
||||||
|
parser.values.delayed_warnings.append(t)
|
||||||
|
else:
|
||||||
|
raise OptionValueError("Warning: %s is not a valid debug type" % value)
|
||||||
|
opt_debug_help = "Print various types of debugging information: %s." \
|
||||||
|
% string.join(debug_options, ", ")
|
||||||
|
op.add_option('--debug',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="debug", default=[],
|
||||||
|
action="callback", callback=opt_debug,
|
||||||
|
help=opt_debug_help,
|
||||||
|
metavar="TYPE")
|
||||||
|
|
||||||
|
def opt_diskcheck(option, opt, value, parser):
|
||||||
|
try:
|
||||||
|
diskcheck_value = diskcheck_convert(value)
|
||||||
|
except ValueError, e:
|
||||||
|
raise OptionValueError("Warning: `%s' is not a valid diskcheck type" % e)
|
||||||
|
setattr(parser.values, option.dest, diskcheck_value)
|
||||||
|
|
||||||
|
op.add_option('--diskcheck',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest='diskcheck', default=None,
|
||||||
|
action="callback", callback=opt_diskcheck,
|
||||||
|
help="Enable specific on-disk checks.",
|
||||||
|
metavar="TYPE")
|
||||||
|
|
||||||
|
def opt_duplicate(option, opt, value, parser):
|
||||||
|
if not value in SCons.Node.FS.Valid_Duplicates:
|
||||||
|
raise OptionValueError("`%s' is not a valid duplication style." % value)
|
||||||
|
setattr(parser.values, option.dest, value)
|
||||||
|
# Set the duplicate style right away so it can affect linking
|
||||||
|
# of SConscript files.
|
||||||
|
SCons.Node.FS.set_duplicate(value)
|
||||||
|
|
||||||
|
opt_duplicate_help = "Set the preferred duplication methods. Must be one of " \
|
||||||
|
+ string.join(SCons.Node.FS.Valid_Duplicates, ", ")
|
||||||
|
|
||||||
|
op.add_option('--duplicate',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="duplicate", default='hard-soft-copy',
|
||||||
|
action="callback", callback=opt_duplicate,
|
||||||
|
help=opt_duplicate_help)
|
||||||
|
|
||||||
|
op.add_option('-f', '--file', '--makefile', '--sconstruct',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="file", default=[],
|
||||||
|
action="append",
|
||||||
|
help="Read FILE as the top-level SConstruct file.")
|
||||||
|
|
||||||
|
op.add_option('-h', '--help',
|
||||||
|
dest="help", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Print defined help message, or this one.")
|
||||||
|
|
||||||
|
op.add_option("-H", "--help-options",
|
||||||
|
action="help",
|
||||||
|
help="Print this message and exit.")
|
||||||
|
|
||||||
|
op.add_option('-i', '--ignore-errors',
|
||||||
|
dest='ignore_errors', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Ignore errors from build actions.")
|
||||||
|
|
||||||
|
op.add_option('-I', '--include-dir',
|
||||||
|
nargs=1,
|
||||||
|
dest='include_dir', default=[],
|
||||||
|
action="append",
|
||||||
|
help="Search DIR for imported Python modules.",
|
||||||
|
metavar="DIR")
|
||||||
|
|
||||||
|
op.add_option('--implicit-cache',
|
||||||
|
dest='implicit_cache', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Cache implicit dependencies")
|
||||||
|
|
||||||
|
def opt_implicit_deps(option, opt, value, parser):
|
||||||
|
setattr(parser.values, 'implicit_cache', True)
|
||||||
|
setattr(parser.values, option.dest, True)
|
||||||
|
|
||||||
|
op.add_option('--implicit-deps-changed',
|
||||||
|
dest="implicit_deps_changed", default=False,
|
||||||
|
action="callback", callback=opt_implicit_deps,
|
||||||
|
help="Ignore cached implicit dependencies.")
|
||||||
|
|
||||||
|
op.add_option('--implicit-deps-unchanged',
|
||||||
|
dest="implicit_deps_unchanged", default=False,
|
||||||
|
action="callback", callback=opt_implicit_deps,
|
||||||
|
help="Ignore changes in implicit dependencies.")
|
||||||
|
|
||||||
|
op.add_option('-j', '--jobs',
|
||||||
|
nargs=1, type="int",
|
||||||
|
dest="num_jobs", default=1,
|
||||||
|
action="store",
|
||||||
|
help="Allow N jobs at once.",
|
||||||
|
metavar="N")
|
||||||
|
|
||||||
|
op.add_option('-k', '--keep-going',
|
||||||
|
dest='keep_going', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Keep going when a target can't be made.")
|
||||||
|
|
||||||
|
op.add_option('--max-drift',
|
||||||
|
nargs=1, type="int",
|
||||||
|
dest='max_drift', default=SCons.Node.FS.default_max_drift,
|
||||||
|
action="store",
|
||||||
|
help="Set maximum system clock drift to N seconds.",
|
||||||
|
metavar="N")
|
||||||
|
|
||||||
|
op.add_option('-n', '--no-exec', '--just-print', '--dry-run', '--recon',
|
||||||
|
dest='no_exec', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Don't build; just print commands.")
|
||||||
|
|
||||||
|
op.add_option('--no-site-dir',
|
||||||
|
dest='no_site_dir', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Don't search or use the usual site_scons dir.")
|
||||||
|
|
||||||
|
op.add_option('--profile',
|
||||||
|
nargs=1,
|
||||||
|
dest="profile_file", default=None,
|
||||||
|
action="store",
|
||||||
|
help="Profile SCons and put results in FILE.",
|
||||||
|
metavar="FILE")
|
||||||
|
|
||||||
|
op.add_option('-q', '--question',
|
||||||
|
dest="question", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Don't build; exit status says if up to date.")
|
||||||
|
|
||||||
|
op.add_option('-Q',
|
||||||
|
dest='no_progress', default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Suppress \"Reading/Building\" progress messages.")
|
||||||
|
|
||||||
|
op.add_option('--random',
|
||||||
|
dest="random", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Build dependencies in random order.")
|
||||||
|
|
||||||
|
op.add_option('-s', '--silent', '--quiet',
|
||||||
|
dest="silent", default=False,
|
||||||
|
action="store_true",
|
||||||
|
help="Don't print commands.")
|
||||||
|
|
||||||
|
op.add_option('--site-dir',
|
||||||
|
nargs=1,
|
||||||
|
dest='site_dir', default=None,
|
||||||
|
action="store",
|
||||||
|
help="Use DIR instead of the usual site_scons dir.",
|
||||||
|
metavar="DIR")
|
||||||
|
|
||||||
|
op.add_option('--taskmastertrace',
|
||||||
|
nargs=1,
|
||||||
|
dest="taskmastertrace_file", default=None,
|
||||||
|
action="store",
|
||||||
|
help="Trace Node evaluation to FILE.",
|
||||||
|
metavar="FILE")
|
||||||
|
|
||||||
|
tree_options = ["all", "derived", "prune", "status"]
|
||||||
|
|
||||||
|
def opt_tree(option, opt, value, parser, tree_options=tree_options):
|
||||||
|
import Main
|
||||||
|
tp = Main.TreePrinter()
|
||||||
|
for o in string.split(value, ','):
|
||||||
|
if o == 'all':
|
||||||
|
tp.derived = False
|
||||||
|
elif o == 'derived':
|
||||||
|
tp.derived = True
|
||||||
|
elif o == 'prune':
|
||||||
|
tp.prune = True
|
||||||
|
elif o == 'status':
|
||||||
|
tp.status = True
|
||||||
|
else:
|
||||||
|
raise OptionValueError("Warning: %s is not a valid --tree option" % o)
|
||||||
|
parser.values.tree_printers.append(tp)
|
||||||
|
|
||||||
|
opt_tree_help = "Print a dependency tree in various formats: %s." \
|
||||||
|
% string.join(tree_options, ", ")
|
||||||
|
|
||||||
|
op.add_option('--tree',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="tree_printers", default=[],
|
||||||
|
action="callback", callback=opt_tree,
|
||||||
|
help=opt_tree_help,
|
||||||
|
metavar="OPTIONS")
|
||||||
|
|
||||||
|
op.add_option('-u', '--up', '--search-up',
|
||||||
|
dest="climb_up", default=0,
|
||||||
|
action="store_const", const=1,
|
||||||
|
help="Search up directory tree for SConstruct, "
|
||||||
|
"build targets at or below current directory.")
|
||||||
|
|
||||||
|
op.add_option('-U',
|
||||||
|
dest="climb_up", default=0,
|
||||||
|
action="store_const", const=3,
|
||||||
|
help="Search up directory tree for SConstruct, "
|
||||||
|
"build Default() targets from local SConscript.")
|
||||||
|
|
||||||
|
def opt_version(option, opt, value, parser, version=version):
|
||||||
|
sys.stdout.write(version + '\n')
|
||||||
|
sys.exit(0)
|
||||||
|
op.add_option("-v", "--version",
|
||||||
|
action="callback", callback=opt_version,
|
||||||
|
help="Print the SCons version number and exit.")
|
||||||
|
|
||||||
|
op.add_option('--warn', '--warning',
|
||||||
|
nargs=1,
|
||||||
|
dest="warn", default=None,
|
||||||
|
action="store",
|
||||||
|
help="Enable or disable warnings.",
|
||||||
|
metavar="WARNING-SPEC")
|
||||||
|
|
||||||
|
op.add_option('-Y', '--repository', '--srcdir',
|
||||||
|
nargs=1,
|
||||||
|
dest="repository", default=[],
|
||||||
|
action="append",
|
||||||
|
help="Search REPOSITORY for source and target files.")
|
||||||
|
|
||||||
|
# Options from Make and Cons classic that we do not yet support,
|
||||||
|
# but which we may support someday and whose (potential) meanings
|
||||||
|
# we don't want to change. These all get a "the -X option is not
|
||||||
|
# yet implemented" message and don't show up in the help output.
|
||||||
|
|
||||||
|
op.add_option('-e', '--environment-overrides',
|
||||||
|
dest="environment_overrides",
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# help="Environment variables override makefiles."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('-l', '--load-average', '--max-load',
|
||||||
|
nargs=1, type="int",
|
||||||
|
dest="load_average", default=0,
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# action="store",
|
||||||
|
# help="Don't start multiple jobs unless load is below "
|
||||||
|
# "LOAD-AVERAGE."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('--list-actions',
|
||||||
|
dest="list_actions",
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# help="Don't build; list files and build actions."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('--list-derived',
|
||||||
|
dest="list_derived",
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# help="Don't build; list files that would be built."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('--list-where',
|
||||||
|
dest="list_where",
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# help="Don't build; list files and where defined."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('-o', '--old-file', '--assume-old',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="old_file", default=[],
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# action="append",
|
||||||
|
# help = "Consider FILE to be old; don't rebuild it."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('--override',
|
||||||
|
nargs=1, type="string",
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
dest="override",
|
||||||
|
# help="Override variables as specified in FILE."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('-p',
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
dest="p",
|
||||||
|
# help="Print internal environments/objects."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('-r', '-R', '--no-builtin-rules', '--no-builtin-variables',
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
dest="no_builtin_rules",
|
||||||
|
# help="Clear default environments and variables."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('-w', '--print-directory',
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
dest="print_directory",
|
||||||
|
# help="Print the current directory."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('--no-print-directory',
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
dest="no_print_directory",
|
||||||
|
# help="Turn off -w, even if it was turned on implicitly."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('--write-filenames',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="write_filenames",
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# help="Write all filenames examined into FILE."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('-W', '--new-file', '--assume-new', '--what-if',
|
||||||
|
nargs=1, type="string",
|
||||||
|
dest="new_file",
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# help="Consider FILE to be changed."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
op.add_option('--warn-undefined-variables',
|
||||||
|
dest="warn_undefined_variables",
|
||||||
|
action="callback", callback=opt_not_yet,
|
||||||
|
# help="Warn when an undefined variable is referenced."
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
|
||||||
|
return op
|
|
@ -28,7 +28,7 @@ files.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Script/SConscript.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Script/SConscript.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons
|
import SCons
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
|
@ -65,6 +65,9 @@ import UserList
|
||||||
#CommandLineTargets = []
|
#CommandLineTargets = []
|
||||||
#DefaultTargets = []
|
#DefaultTargets = []
|
||||||
|
|
||||||
|
class SConscriptReturn(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
launch_dir = os.path.abspath(os.curdir)
|
launch_dir = os.path.abspath(os.curdir)
|
||||||
|
|
||||||
GlobalDict = None
|
GlobalDict = None
|
||||||
|
@ -125,6 +128,8 @@ class Frame:
|
||||||
# make sure the sconscript attr is a Node.
|
# make sure the sconscript attr is a Node.
|
||||||
if isinstance(sconscript, SCons.Node.Node):
|
if isinstance(sconscript, SCons.Node.Node):
|
||||||
self.sconscript = sconscript
|
self.sconscript = sconscript
|
||||||
|
elif sconscript == '-':
|
||||||
|
self.sconscript = None
|
||||||
else:
|
else:
|
||||||
self.sconscript = fs.File(str(sconscript))
|
self.sconscript = fs.File(str(sconscript))
|
||||||
|
|
||||||
|
@ -133,7 +138,7 @@ call_stack = []
|
||||||
|
|
||||||
# For documentation on the methods in this file, see the scons man-page
|
# For documentation on the methods in this file, see the scons man-page
|
||||||
|
|
||||||
def Return(*vars):
|
def Return(*vars, **kw):
|
||||||
retval = []
|
retval = []
|
||||||
try:
|
try:
|
||||||
for var in vars:
|
for var in vars:
|
||||||
|
@ -147,6 +152,11 @@ def Return(*vars):
|
||||||
else:
|
else:
|
||||||
call_stack[-1].retval = tuple(retval)
|
call_stack[-1].retval = tuple(retval)
|
||||||
|
|
||||||
|
stop = kw.get('stop', True)
|
||||||
|
|
||||||
|
if stop:
|
||||||
|
raise SConscriptReturn
|
||||||
|
|
||||||
|
|
||||||
stack_bottom = '% Stack boTTom %' # hard to define a variable w/this name :)
|
stack_bottom = '% Stack boTTom %' # hard to define a variable w/this name :)
|
||||||
|
|
||||||
|
@ -242,7 +252,10 @@ def _SConscript(fs, *files, **kw):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
exec _file_ in call_stack[-1].globals
|
try:
|
||||||
|
exec _file_ in call_stack[-1].globals
|
||||||
|
except SConscriptReturn:
|
||||||
|
pass
|
||||||
finally:
|
finally:
|
||||||
if old_file is not None:
|
if old_file is not None:
|
||||||
call_stack[-1].globals.update({__file__:old_file})
|
call_stack[-1].globals.update({__file__:old_file})
|
||||||
|
@ -469,7 +482,7 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
|
|
||||||
def GetOption(self, name):
|
def GetOption(self, name):
|
||||||
name = self.subst(name)
|
name = self.subst(name)
|
||||||
return SCons.Script.Main.ssoptions.get(name)
|
return SCons.Script.Main.GetOption(name)
|
||||||
|
|
||||||
def Help(self, text):
|
def Help(self, text):
|
||||||
text = self.subst(text, raw=1)
|
text = self.subst(text, raw=1)
|
||||||
|
@ -525,7 +538,7 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
|
|
||||||
def SetOption(self, name, value):
|
def SetOption(self, name, value):
|
||||||
name = self.subst(name)
|
name = self.subst(name)
|
||||||
SCons.Script.Main.ssoptions.set(name, value)
|
SCons.Script.Main.SetOption(name, value)
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
|
@ -34,7 +34,7 @@ it goes here.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Script/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Script/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import time
|
import time
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
@ -70,7 +70,7 @@ if "--debug=memoizer" in _args:
|
||||||
# for it to be displayed or not after warnings are configured.
|
# for it to be displayed or not after warnings are configured.
|
||||||
import Main
|
import Main
|
||||||
exc_type, exc_value, tb = sys.exc_info()
|
exc_type, exc_value, tb = sys.exc_info()
|
||||||
Main.delayed_warnings.append(exc_type, exc_value)
|
Main.delayed_warnings.append((exc_type, exc_value))
|
||||||
del _args
|
del _args
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
|
@ -105,23 +105,28 @@ BuildTask = Main.BuildTask
|
||||||
CleanTask = Main.CleanTask
|
CleanTask = Main.CleanTask
|
||||||
QuestionTask = Main.QuestionTask
|
QuestionTask = Main.QuestionTask
|
||||||
#PrintHelp = Main.PrintHelp
|
#PrintHelp = Main.PrintHelp
|
||||||
OptParser = Main.OptParser
|
#SConscriptSettableOptions = Main.SConscriptSettableOptions
|
||||||
SConscriptSettableOptions = Main.SConscriptSettableOptions
|
|
||||||
|
|
||||||
keep_going_on_error = Main.keep_going_on_error
|
AddOption = Main.AddOption
|
||||||
|
GetOption = Main.GetOption
|
||||||
|
SetOption = Main.SetOption
|
||||||
|
Progress = Main.Progress
|
||||||
|
GetBuildFailures = Main.GetBuildFailures
|
||||||
|
|
||||||
|
#keep_going_on_error = Main.keep_going_on_error
|
||||||
#print_dtree = Main.print_dtree
|
#print_dtree = Main.print_dtree
|
||||||
print_explanations = Main.print_explanations
|
#print_explanations = Main.print_explanations
|
||||||
print_includes = Main.print_includes
|
#print_includes = Main.print_includes
|
||||||
print_objects = Main.print_objects
|
#print_objects = Main.print_objects
|
||||||
print_time = Main.print_time
|
#print_time = Main.print_time
|
||||||
#print_tree = Main.print_tree
|
#print_tree = Main.print_tree
|
||||||
memory_stats = Main.memory_stats
|
#memory_stats = Main.memory_stats
|
||||||
ignore_errors = Main.ignore_errors
|
#ignore_errors = Main.ignore_errors
|
||||||
#sconscript_time = Main.sconscript_time
|
#sconscript_time = Main.sconscript_time
|
||||||
#command_time = Main.command_time
|
#command_time = Main.command_time
|
||||||
#exit_status = Main.exit_status
|
#exit_status = Main.exit_status
|
||||||
#profiling = Main.profiling
|
#profiling = Main.profiling
|
||||||
repositories = Main.repositories
|
#repositories = Main.repositories
|
||||||
|
|
||||||
#
|
#
|
||||||
import SConscript
|
import SConscript
|
||||||
|
@ -131,12 +136,14 @@ call_stack = _SConscript.call_stack
|
||||||
|
|
||||||
#
|
#
|
||||||
Action = SCons.Action.Action
|
Action = SCons.Action.Action
|
||||||
|
AddMethod = SCons.Util.AddMethod
|
||||||
AllowSubstExceptions = SCons.Subst.SetAllowableExceptions
|
AllowSubstExceptions = SCons.Subst.SetAllowableExceptions
|
||||||
BoolOption = SCons.Options.BoolOption
|
BoolOption = SCons.Options.BoolOption
|
||||||
Builder = SCons.Builder.Builder
|
Builder = SCons.Builder.Builder
|
||||||
Configure = _SConscript.Configure
|
Configure = _SConscript.Configure
|
||||||
EnumOption = SCons.Options.EnumOption
|
EnumOption = SCons.Options.EnumOption
|
||||||
Environment = SCons.Environment.Environment
|
Environment = SCons.Environment.Environment
|
||||||
|
#OptParser = SCons.SConsOptions.OptParser
|
||||||
FindPathDirs = SCons.Scanner.FindPathDirs
|
FindPathDirs = SCons.Scanner.FindPathDirs
|
||||||
ListOption = SCons.Options.ListOption
|
ListOption = SCons.Options.ListOption
|
||||||
PackageOption = SCons.Options.PackageOption
|
PackageOption = SCons.Options.PackageOption
|
||||||
|
@ -255,7 +262,7 @@ def HelpFunction(text):
|
||||||
sconscript_reading = 0
|
sconscript_reading = 0
|
||||||
|
|
||||||
#
|
#
|
||||||
def Options(files=None, args=ARGUMENTS):
|
def Options(files=[], args=ARGUMENTS):
|
||||||
return SCons.Options.Options(files, args)
|
return SCons.Options.Options(files, args)
|
||||||
|
|
||||||
# The list of global functions to add to the SConscript name space
|
# The list of global functions to add to the SConscript name space
|
||||||
|
@ -269,12 +276,10 @@ GlobalDefaultEnvironmentFunctions = [
|
||||||
'Exit',
|
'Exit',
|
||||||
'Export',
|
'Export',
|
||||||
'GetLaunchDir',
|
'GetLaunchDir',
|
||||||
'GetOption',
|
|
||||||
'Help',
|
'Help',
|
||||||
'Import',
|
'Import',
|
||||||
#'SConscript', is handled separately, below.
|
#'SConscript', is handled separately, below.
|
||||||
'SConscriptChdir',
|
'SConscriptChdir',
|
||||||
'SetOption',
|
|
||||||
|
|
||||||
# Methods from the Environment.Base class.
|
# Methods from the Environment.Base class.
|
||||||
'AddPostAction',
|
'AddPostAction',
|
||||||
|
@ -285,6 +290,7 @@ GlobalDefaultEnvironmentFunctions = [
|
||||||
'CacheDir',
|
'CacheDir',
|
||||||
'Clean',
|
'Clean',
|
||||||
#The Command() method is handled separately, below.
|
#The Command() method is handled separately, below.
|
||||||
|
'Decider',
|
||||||
'Depends',
|
'Depends',
|
||||||
'Dir',
|
'Dir',
|
||||||
'NoClean',
|
'NoClean',
|
||||||
|
@ -293,8 +299,11 @@ GlobalDefaultEnvironmentFunctions = [
|
||||||
'Execute',
|
'Execute',
|
||||||
'File',
|
'File',
|
||||||
'FindFile',
|
'FindFile',
|
||||||
|
'FindInstalledFiles',
|
||||||
|
'FindSourceFiles',
|
||||||
'Flatten',
|
'Flatten',
|
||||||
'GetBuildPath',
|
'GetBuildPath',
|
||||||
|
'Glob',
|
||||||
'Ignore',
|
'Ignore',
|
||||||
'Install',
|
'Install',
|
||||||
'InstallAs',
|
'InstallAs',
|
||||||
|
@ -303,11 +312,13 @@ GlobalDefaultEnvironmentFunctions = [
|
||||||
'ParseDepends',
|
'ParseDepends',
|
||||||
'Precious',
|
'Precious',
|
||||||
'Repository',
|
'Repository',
|
||||||
|
'Requires',
|
||||||
'SConsignFile',
|
'SConsignFile',
|
||||||
'SideEffect',
|
'SideEffect',
|
||||||
'SourceCode',
|
'SourceCode',
|
||||||
'SourceSignatures',
|
'SourceSignatures',
|
||||||
'Split',
|
'Split',
|
||||||
|
'Tag',
|
||||||
'TargetSignatures',
|
'TargetSignatures',
|
||||||
'Value',
|
'Value',
|
||||||
]
|
]
|
||||||
|
@ -337,6 +348,7 @@ GlobalDefaultBuilders = [
|
||||||
'Tar',
|
'Tar',
|
||||||
'TypeLibrary',
|
'TypeLibrary',
|
||||||
'Zip',
|
'Zip',
|
||||||
|
'Package',
|
||||||
]
|
]
|
||||||
|
|
||||||
for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
|
for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
|
57
scons/scons-local-0.97.0d20071212/SCons/Sig.py
Normal file
57
scons/scons-local-0.97.0d20071212/SCons/Sig.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
# a copy of this software and associated documentation files (the
|
||||||
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
# without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
# the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included
|
||||||
|
# in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
# 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__ = "src/engine/SCons/Sig.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
__doc__ = """Place-holder for the old SCons.Sig module hierarchy
|
||||||
|
|
||||||
|
This is no longer used, but code out there (such as the NSIS module on
|
||||||
|
the SCons wiki) may try to import SCons.Sig. If so, we generate a warning
|
||||||
|
that points them to the line that caused the import, and don't die.
|
||||||
|
|
||||||
|
If someone actually tried to use the sub-modules or functions within
|
||||||
|
the package (for example, SCons.Sig.MD5.signature()), then they'll still
|
||||||
|
get an AttributeError, but at least they'll know where to start looking.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import SCons.Util
|
||||||
|
import SCons.Warnings
|
||||||
|
|
||||||
|
msg = 'The SCons.Sig module no longer exists.\n' \
|
||||||
|
' Remove the following "import SCons.Sig" line to eliminate this warning:'
|
||||||
|
|
||||||
|
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, msg)
|
||||||
|
|
||||||
|
default_calc = None
|
||||||
|
default_module = None
|
||||||
|
|
||||||
|
class MD5Null(SCons.Util.Null):
|
||||||
|
def __repr__(self):
|
||||||
|
return "MD5Null()"
|
||||||
|
|
||||||
|
class TimeStampNull(SCons.Util.Null):
|
||||||
|
def __repr__(self):
|
||||||
|
return "TimeStampNull()"
|
||||||
|
|
||||||
|
MD5 = MD5Null()
|
||||||
|
TimeStamp = TimeStampNull()
|
|
@ -27,7 +27,7 @@ SCons string substitution.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Subst.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Subst.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
|
@ -48,7 +48,7 @@ interface and the SCons build engine. There are two key classes here:
|
||||||
target(s) that it decides need to be evaluated and/or built.
|
target(s) that it decides need to be evaluated and/or built.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Taskmaster.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Taskmaster.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
|
@ -205,20 +205,40 @@ class Task:
|
||||||
raise SCons.Errors.TaskmasterException(self.targets[0],
|
raise SCons.Errors.TaskmasterException(self.targets[0],
|
||||||
sys.exc_info())
|
sys.exc_info())
|
||||||
|
|
||||||
def executed(self):
|
def executed_without_callbacks(self):
|
||||||
"""
|
"""
|
||||||
Called when the task has been successfully executed.
|
Called when the task has been successfully executed
|
||||||
|
and the Taskmaster instance doesn't want to call
|
||||||
This may have been a do-nothing operation (to preserve build
|
the Node's callback methods.
|
||||||
order), so we have to check the node's state before deciding
|
|
||||||
whether it was "built" or just "visited."
|
|
||||||
"""
|
"""
|
||||||
for t in self.targets:
|
for t in self.targets:
|
||||||
if t.get_state() == SCons.Node.executing:
|
if t.get_state() == SCons.Node.executing:
|
||||||
|
for side_effect in t.side_effects:
|
||||||
|
side_effect.set_state(SCons.Node.no_state)
|
||||||
|
t.set_state(SCons.Node.executed)
|
||||||
|
|
||||||
|
def executed_with_callbacks(self):
|
||||||
|
"""
|
||||||
|
Called when the task has been successfully executed and
|
||||||
|
the Taskmaster instance wants to call the Node's callback
|
||||||
|
methods.
|
||||||
|
|
||||||
|
This may have been a do-nothing operation (to preserve build
|
||||||
|
order), so we must check the node's state before deciding whether
|
||||||
|
it was "built", in which case we call the appropriate Node method.
|
||||||
|
In any event, we always call "visited()", which will handle any
|
||||||
|
post-visit actions that must take place regardless of whether
|
||||||
|
or not the target was an actual built target or a source Node.
|
||||||
|
"""
|
||||||
|
for t in self.targets:
|
||||||
|
if t.get_state() == SCons.Node.executing:
|
||||||
|
for side_effect in t.side_effects:
|
||||||
|
side_effect.set_state(SCons.Node.no_state)
|
||||||
t.set_state(SCons.Node.executed)
|
t.set_state(SCons.Node.executed)
|
||||||
t.built()
|
t.built()
|
||||||
else:
|
t.visited()
|
||||||
t.visited()
|
|
||||||
|
executed = executed_with_callbacks
|
||||||
|
|
||||||
def failed(self):
|
def failed(self):
|
||||||
"""
|
"""
|
||||||
|
@ -276,7 +296,9 @@ class Task:
|
||||||
self.out_of_date = []
|
self.out_of_date = []
|
||||||
for t in self.targets:
|
for t in self.targets:
|
||||||
try:
|
try:
|
||||||
is_up_to_date = t.disambiguate().current()
|
t.disambiguate().make_ready()
|
||||||
|
is_up_to_date = not t.has_builder() or \
|
||||||
|
(not t.always_build and t.is_up_to_date())
|
||||||
except EnvironmentError, e:
|
except EnvironmentError, e:
|
||||||
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
||||||
if is_up_to_date:
|
if is_up_to_date:
|
||||||
|
@ -307,12 +329,14 @@ class Task:
|
||||||
# back on the candidates list if the Node is also a waiting
|
# back on the candidates list if the Node is also a waiting
|
||||||
# parent.
|
# parent.
|
||||||
|
|
||||||
|
targets = set(self.targets)
|
||||||
|
|
||||||
parents = {}
|
parents = {}
|
||||||
for t in self.targets:
|
for t in targets:
|
||||||
for p in t.waiting_parents.keys():
|
for p in t.waiting_parents.keys():
|
||||||
parents[p] = parents.get(p, 0) + 1
|
parents[p] = parents.get(p, 0) + 1
|
||||||
|
|
||||||
for t in self.targets:
|
for t in targets:
|
||||||
for s in t.side_effects:
|
for s in t.side_effects:
|
||||||
if s.get_state() == SCons.Node.executing:
|
if s.get_state() == SCons.Node.executing:
|
||||||
s.set_state(SCons.Node.no_state)
|
s.set_state(SCons.Node.no_state)
|
||||||
|
@ -328,7 +352,7 @@ class Task:
|
||||||
if p.ref_count == 0:
|
if p.ref_count == 0:
|
||||||
self.tm.candidates.append(p)
|
self.tm.candidates.append(p)
|
||||||
|
|
||||||
for t in self.targets:
|
for t in targets:
|
||||||
t.postprocess()
|
t.postprocess()
|
||||||
|
|
||||||
# Exception handling subsystem.
|
# Exception handling subsystem.
|
||||||
|
@ -402,8 +426,9 @@ class Taskmaster:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, targets=[], tasker=Task, order=None, trace=None):
|
def __init__(self, targets=[], tasker=Task, order=None, trace=None):
|
||||||
self.top_targets = targets[:]
|
self.original_top = targets
|
||||||
self.top_targets.reverse()
|
self.top_targets_left = targets[:]
|
||||||
|
self.top_targets_left.reverse()
|
||||||
self.candidates = []
|
self.candidates = []
|
||||||
self.tasker = tasker
|
self.tasker = tasker
|
||||||
if not order:
|
if not order:
|
||||||
|
@ -437,7 +462,7 @@ class Taskmaster:
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
node = self.top_targets.pop()
|
node = self.top_targets_left.pop()
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
self.current_top = node
|
self.current_top = node
|
||||||
|
@ -510,7 +535,7 @@ class Taskmaster:
|
||||||
node.set_state(SCons.Node.pending)
|
node.set_state(SCons.Node.pending)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
children = node.children()
|
children = node.children() + node.prerequisites
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
exc_value = sys.exc_info()[1]
|
exc_value = sys.exc_info()[1]
|
||||||
e = SCons.Errors.ExplicitExit(node, exc_value.code)
|
e = SCons.Errors.ExplicitExit(node, exc_value.code)
|
||||||
|
@ -535,16 +560,14 @@ class Taskmaster:
|
||||||
c.sort()
|
c.sort()
|
||||||
T.write(' children:\n %s\n ' % c)
|
T.write(' children:\n %s\n ' % c)
|
||||||
|
|
||||||
childinfo = map(lambda N: (N.get_state(),
|
childstate = map(lambda N: (N, N.get_state()), children)
|
||||||
N.is_derived() or N.is_pseudo_derived(),
|
|
||||||
N), children)
|
|
||||||
|
|
||||||
# Skip this node if any of its children have failed. This
|
# Skip this node if any of its children have failed. This
|
||||||
# catches the case where we're descending a top-level target
|
# catches the case where we're descending a top-level target
|
||||||
# and one of our children failed while trying to be built
|
# and one of our children failed while trying to be built
|
||||||
# by a *previous* descent of an earlier top-level target.
|
# by a *previous* descent of an earlier top-level target.
|
||||||
failed_children = filter(lambda I: I[0] == SCons.Node.failed,
|
failed_children = filter(lambda I: I[1] == SCons.Node.failed,
|
||||||
childinfo)
|
childstate)
|
||||||
if failed_children:
|
if failed_children:
|
||||||
node.set_state(SCons.Node.failed)
|
node.set_state(SCons.Node.failed)
|
||||||
if S: S.child_failed = S.child_failed + 1
|
if S: S.child_failed = S.child_failed + 1
|
||||||
|
@ -555,76 +578,48 @@ class Taskmaster:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Detect dependency cycles:
|
# Detect dependency cycles:
|
||||||
pending_nodes = filter(lambda I: I[0] == SCons.Node.pending, childinfo)
|
pending_nodes = filter(lambda I: I[1] == SCons.Node.pending, childstate)
|
||||||
if pending_nodes:
|
if pending_nodes:
|
||||||
for p in pending_nodes:
|
for p in pending_nodes:
|
||||||
cycle = find_cycle([p[2], node])
|
cycle = find_cycle([p[0], node])
|
||||||
if cycle:
|
if cycle:
|
||||||
desc = "Dependency cycle: " + string.join(map(str, cycle), " -> ")
|
desc = "Dependency cycle: " + string.join(map(str, cycle), " -> ")
|
||||||
if T: T.write(' dependency cycle\n')
|
if T: T.write(' dependency cycle\n')
|
||||||
raise SCons.Errors.UserError, desc
|
raise SCons.Errors.UserError, desc
|
||||||
|
|
||||||
# Select all of the dependencies that are derived targets
|
not_built = filter(lambda I: I[1] <= SCons.Node.executing, childstate)
|
||||||
# (that is, children who have builders or are side effects).
|
|
||||||
derived_children = filter(lambda I: I[1], childinfo)
|
|
||||||
|
|
||||||
not_started = filter(lambda I: not I[0], derived_children)
|
|
||||||
if not_started:
|
|
||||||
not_started = map(lambda I: I[2], not_started)
|
|
||||||
|
|
||||||
# We're waiting on one more derived targets that have
|
|
||||||
# not yet started building. Add this node to the
|
|
||||||
# waiting_parents lists of those derived files so that
|
|
||||||
# when they've finished building, our implicit dependency
|
|
||||||
# list will get cleared and we'll re-scan the newly-built
|
|
||||||
# file(s) for updated implicit dependencies.
|
|
||||||
added = map(lambda n, P=node: n.add_to_waiting_parents(P), not_started)
|
|
||||||
node.ref_count = node.ref_count + reduce(operator.add, added, 0)
|
|
||||||
|
|
||||||
# Now we add these derived targets to the candidates
|
|
||||||
# list so they can be examined and built. We have to
|
|
||||||
# add ourselves back to the list first, though, so we get
|
|
||||||
# a chance to re-scan and build after the dependencies.
|
|
||||||
#
|
|
||||||
# We reverse the order in which the children are added
|
|
||||||
# to the candidates stack so the order in which they're
|
|
||||||
# popped matches the order in which they show up in our
|
|
||||||
# children's list. This is more logical / efficient for
|
|
||||||
# builders with multiple targets, since the "primary"
|
|
||||||
# target will be examined first.
|
|
||||||
self.candidates.append(node)
|
|
||||||
not_started.reverse()
|
|
||||||
self.candidates.extend(self.order(not_started))
|
|
||||||
|
|
||||||
if S: S.not_started = S.not_started + 1
|
|
||||||
if T:
|
|
||||||
c = map(str, not_started)
|
|
||||||
c.sort()
|
|
||||||
T.write(' waiting on unstarted children:\n %s\n' % c)
|
|
||||||
continue
|
|
||||||
|
|
||||||
not_built = filter(lambda I: I[0] <= SCons.Node.executing, derived_children)
|
|
||||||
if not_built:
|
if not_built:
|
||||||
not_built = map(lambda I: I[2], not_built)
|
|
||||||
|
|
||||||
# We're waiting on one or more derived targets that have
|
# We're waiting on one or more derived targets that have
|
||||||
# started building but not yet finished. Add this node
|
# not yet finished building.
|
||||||
# to the waiting parents lists of those derived files
|
|
||||||
# so that when they've finished building, our implicit
|
not_visited = filter(lambda I: not I[1], not_built)
|
||||||
# dependency list will get cleared and we'll re-scan the
|
if not_visited:
|
||||||
# newly-built file(s) for updated implicit dependencies.
|
# Some of them haven't even been visited yet.
|
||||||
added = map(lambda n, P=node: n.add_to_waiting_parents(P), not_built)
|
# Add them to the list so that on some next pass
|
||||||
node.ref_count = node.ref_count + reduce(operator.add, added, 0)
|
# we can take a stab at evaluating them (or
|
||||||
|
# their children).
|
||||||
|
not_visited = map(lambda I: I[0], not_visited)
|
||||||
|
not_visited.reverse()
|
||||||
|
self.candidates.extend(self.order(not_visited))
|
||||||
|
|
||||||
|
n_b_nodes = map(lambda I: I[0], not_built)
|
||||||
|
|
||||||
|
# Add this node to the waiting parents lists of anything
|
||||||
|
# we're waiting on, with a reference count so we can be
|
||||||
|
# put back on the list for re-evaluation when they've
|
||||||
|
# all finished.
|
||||||
|
map(lambda n, P=node: n.add_to_waiting_parents(P), n_b_nodes)
|
||||||
|
node.ref_count = len(set(n_b_nodes))
|
||||||
|
|
||||||
if S: S.not_built = S.not_built + 1
|
if S: S.not_built = S.not_built + 1
|
||||||
if T:
|
if T:
|
||||||
c = map(str, not_built)
|
c = map(str, n_b_nodes)
|
||||||
c.sort()
|
c.sort()
|
||||||
T.write(' waiting on unfinished children:\n %s\n' % c)
|
T.write(' waiting on unfinished children:\n %s\n' % c)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Skip this node if it has side-effects that are currently being
|
# Skip this node if it has side-effects that are
|
||||||
# built themselves or waiting for something else being built.
|
# currently being built:
|
||||||
side_effects = filter(lambda N:
|
side_effects = filter(lambda N:
|
||||||
N.get_state() == SCons.Node.executing,
|
N.get_state() == SCons.Node.executing,
|
||||||
node.side_effects)
|
node.side_effects)
|
||||||
|
@ -659,7 +654,7 @@ class Taskmaster:
|
||||||
|
|
||||||
tlist = node.get_executor().targets
|
tlist = node.get_executor().targets
|
||||||
|
|
||||||
task = self.tasker(self, tlist, node is self.current_top, node)
|
task = self.tasker(self, tlist, node in self.original_top, node)
|
||||||
try:
|
try:
|
||||||
task.make_ready()
|
task.make_ready()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
|
@ -32,7 +32,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/386asm.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/386asm.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
from SCons.Tool.PharLapCommon import addPharLapPaths
|
from SCons.Tool.PharLapCommon import addPharLapPaths
|
||||||
import SCons.Util
|
import SCons.Util
|
|
@ -32,7 +32,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/BitKeeper.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/BitKeeper.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/CVS.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/CVS.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
|
@ -27,7 +27,7 @@ Stuff for processing Java.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/JavaCommon.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/JavaCommon.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -36,6 +36,8 @@ import string
|
||||||
|
|
||||||
java_parsing = 1
|
java_parsing = 1
|
||||||
|
|
||||||
|
default_java_version = '1.4'
|
||||||
|
|
||||||
if java_parsing:
|
if java_parsing:
|
||||||
# Parse Java files for class names.
|
# Parse Java files for class names.
|
||||||
#
|
#
|
||||||
|
@ -53,18 +55,26 @@ if java_parsing:
|
||||||
# array declarations "[]";
|
# array declarations "[]";
|
||||||
# semi-colons;
|
# semi-colons;
|
||||||
# periods.
|
# periods.
|
||||||
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.]|' +
|
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' +
|
||||||
r'[A-Za-z_][\w\.]*|/\*|\*/|\[\])')
|
r'[A-Za-z_][\w\$\.]*|/\*|\*/|\[\])')
|
||||||
|
|
||||||
class OuterState:
|
class OuterState:
|
||||||
"""The initial state for parsing a Java file for classes,
|
"""The initial state for parsing a Java file for classes,
|
||||||
interfaces, and anonymous inner classes."""
|
interfaces, and anonymous inner classes."""
|
||||||
def __init__(self):
|
def __init__(self, version=default_java_version):
|
||||||
|
|
||||||
|
if not version in ('1.1', '1.2', '1.3','1.4', '1.5', '1.6'):
|
||||||
|
msg = "Java version %s not supported" % version
|
||||||
|
raise NotImplementedError, msg
|
||||||
|
|
||||||
|
self.version = version
|
||||||
self.listClasses = []
|
self.listClasses = []
|
||||||
self.listOutputs = []
|
self.listOutputs = []
|
||||||
self.stackBrackets = []
|
self.stackBrackets = []
|
||||||
self.brackets = 0
|
self.brackets = 0
|
||||||
self.nextAnon = 1
|
self.nextAnon = 1
|
||||||
|
self.stackAnonClassBrackets = []
|
||||||
|
self.anonStacksStack = [[0]]
|
||||||
self.package = None
|
self.package = None
|
||||||
|
|
||||||
def trace(self):
|
def trace(self):
|
||||||
|
@ -90,6 +100,7 @@ if java_parsing:
|
||||||
try:
|
try:
|
||||||
return self.anonState
|
return self.anonState
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
self.outer_state = self
|
||||||
ret = SkipState(1, AnonClassState(self))
|
ret = SkipState(1, AnonClassState(self))
|
||||||
self.anonState = ret
|
self.anonState = ret
|
||||||
return ret
|
return ret
|
||||||
|
@ -101,6 +112,9 @@ if java_parsing:
|
||||||
ret = SkipState(1, self)
|
ret = SkipState(1, self)
|
||||||
self.skipState = ret
|
self.skipState = ret
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def __getAnonStack(self):
|
||||||
|
return self.anonStacksStack[-1]
|
||||||
|
|
||||||
def openBracket(self):
|
def openBracket(self):
|
||||||
self.brackets = self.brackets + 1
|
self.brackets = self.brackets + 1
|
||||||
|
@ -111,7 +125,12 @@ if java_parsing:
|
||||||
self.brackets == self.stackBrackets[-1]:
|
self.brackets == self.stackBrackets[-1]:
|
||||||
self.listOutputs.append(string.join(self.listClasses, '$'))
|
self.listOutputs.append(string.join(self.listClasses, '$'))
|
||||||
self.listClasses.pop()
|
self.listClasses.pop()
|
||||||
|
self.anonStacksStack.pop()
|
||||||
self.stackBrackets.pop()
|
self.stackBrackets.pop()
|
||||||
|
if len(self.stackAnonClassBrackets) and \
|
||||||
|
self.brackets == self.stackAnonClassBrackets[-1]:
|
||||||
|
self.__getAnonStack().pop()
|
||||||
|
self.stackAnonClassBrackets.pop()
|
||||||
|
|
||||||
def parseToken(self, token):
|
def parseToken(self, token):
|
||||||
if token[:2] == '//':
|
if token[:2] == '//':
|
||||||
|
@ -145,32 +164,56 @@ if java_parsing:
|
||||||
|
|
||||||
def addAnonClass(self):
|
def addAnonClass(self):
|
||||||
"""Add an anonymous inner class"""
|
"""Add an anonymous inner class"""
|
||||||
clazz = self.listClasses[0]
|
if self.version in ('1.1', '1.2', '1.3', '1.4'):
|
||||||
self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
|
clazz = self.listClasses[0]
|
||||||
|
self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
|
||||||
|
elif self.version in ('1.5', '1.6'):
|
||||||
|
self.stackAnonClassBrackets.append(self.brackets)
|
||||||
|
className = []
|
||||||
|
className.extend(self.listClasses)
|
||||||
|
self.__getAnonStack()[-1] = self.__getAnonStack()[-1] + 1
|
||||||
|
for anon in self.__getAnonStack():
|
||||||
|
className.append(str(anon))
|
||||||
|
self.listOutputs.append(string.join(className, '$'))
|
||||||
|
|
||||||
self.nextAnon = self.nextAnon + 1
|
self.nextAnon = self.nextAnon + 1
|
||||||
|
self.__getAnonStack().append(0)
|
||||||
|
|
||||||
def setPackage(self, package):
|
def setPackage(self, package):
|
||||||
self.package = package
|
self.package = package
|
||||||
|
|
||||||
class AnonClassState:
|
class AnonClassState:
|
||||||
"""A state that looks for anonymous inner classes."""
|
"""A state that looks for anonymous inner classes."""
|
||||||
def __init__(self, outer_state):
|
def __init__(self, old_state):
|
||||||
# outer_state is always an instance of OuterState
|
# outer_state is always an instance of OuterState
|
||||||
self.outer_state = outer_state
|
self.outer_state = old_state.outer_state
|
||||||
self.tokens_to_find = 2
|
self.old_state = old_state
|
||||||
|
self.brace_level = 0
|
||||||
def parseToken(self, token):
|
def parseToken(self, token):
|
||||||
# This is an anonymous class if and only if the next
|
# This is an anonymous class if and only if the next
|
||||||
# non-whitespace token is a bracket
|
# non-whitespace token is a bracket. Everything between
|
||||||
if token == '\n':
|
# braces should be parsed as normal java code.
|
||||||
|
if token[:2] == '//':
|
||||||
|
return IgnoreState('\n', self)
|
||||||
|
elif token == '/*':
|
||||||
|
return IgnoreState('*/', self)
|
||||||
|
elif token == '\n':
|
||||||
|
return self
|
||||||
|
elif token == '(':
|
||||||
|
self.brace_level = self.brace_level + 1
|
||||||
|
return self
|
||||||
|
if self.brace_level > 0:
|
||||||
|
if token == 'new':
|
||||||
|
# look further for anonymous inner class
|
||||||
|
return SkipState(1, AnonClassState(self))
|
||||||
|
elif token in [ '"', "'" ]:
|
||||||
|
return IgnoreState(token, self)
|
||||||
|
elif token == ')':
|
||||||
|
self.brace_level = self.brace_level - 1
|
||||||
return self
|
return self
|
||||||
if token == '{':
|
if token == '{':
|
||||||
self.outer_state.openBracket()
|
|
||||||
self.outer_state.addAnonClass()
|
self.outer_state.addAnonClass()
|
||||||
elif token == '}':
|
return self.old_state.parseToken(token)
|
||||||
self.outer_state.closeBracket()
|
|
||||||
elif token in ['"', "'"]:
|
|
||||||
return IgnoreState(token, self)
|
|
||||||
return self.outer_state
|
|
||||||
|
|
||||||
class SkipState:
|
class SkipState:
|
||||||
"""A state that will skip a specified number of tokens before
|
"""A state that will skip a specified number of tokens before
|
||||||
|
@ -194,6 +237,7 @@ if java_parsing:
|
||||||
if token == '\n':
|
if token == '\n':
|
||||||
return self
|
return self
|
||||||
self.outer_state.listClasses.append(token)
|
self.outer_state.listClasses.append(token)
|
||||||
|
self.outer_state.anonStacksStack.append([0])
|
||||||
return self.outer_state
|
return self.outer_state
|
||||||
|
|
||||||
class IgnoreState:
|
class IgnoreState:
|
||||||
|
@ -217,15 +261,15 @@ if java_parsing:
|
||||||
self.outer_state.setPackage(token)
|
self.outer_state.setPackage(token)
|
||||||
return self.outer_state
|
return self.outer_state
|
||||||
|
|
||||||
def parse_java_file(fn):
|
def parse_java_file(fn, version=default_java_version):
|
||||||
return parse_java(open(fn, 'r').read())
|
return parse_java(open(fn, 'r').read(), version)
|
||||||
|
|
||||||
def parse_java(contents, trace=None):
|
def parse_java(contents, version=default_java_version, trace=None):
|
||||||
"""Parse a .java file and return a double of package directory,
|
"""Parse a .java file and return a double of package directory,
|
||||||
plus a list of .class files that compiling that .java file will
|
plus a list of .class files that compiling that .java file will
|
||||||
produce"""
|
produce"""
|
||||||
package = None
|
package = None
|
||||||
initial = OuterState()
|
initial = OuterState(version)
|
||||||
currstate = initial
|
currstate = initial
|
||||||
for token in _reToken.findall(contents):
|
for token in _reToken.findall(contents):
|
||||||
# The regex produces a bunch of groups, but only one will
|
# The regex produces a bunch of groups, but only one will
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/Perforce.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/Perforce.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
|
@ -29,7 +29,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/PharLapCommon.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/RCS.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/RCS.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/SCCS.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/SCCS.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/Subversion.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/Subversion.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -15,7 +15,7 @@ tool definition.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
# "Software"), to deal in the Software without restriction, including
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
@ -36,13 +36,14 @@ tool definition.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import imp
|
import imp
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
import SCons.Scanner.C
|
import SCons.Scanner.C
|
||||||
import SCons.Scanner.D
|
import SCons.Scanner.D
|
||||||
|
@ -88,8 +89,11 @@ class Tool:
|
||||||
module = self._tool_module()
|
module = self._tool_module()
|
||||||
self.generate = module.generate
|
self.generate = module.generate
|
||||||
self.exists = module.exists
|
self.exists = module.exists
|
||||||
|
if hasattr(module, 'options'):
|
||||||
|
self.options = module.options
|
||||||
|
|
||||||
def _tool_module(self):
|
def _tool_module(self):
|
||||||
|
# TODO: Interchange zipimport with normal initilization for better error reporting
|
||||||
oldpythonpath = sys.path
|
oldpythonpath = sys.path
|
||||||
sys.path = self.toolpath + sys.path
|
sys.path = self.toolpath + sys.path
|
||||||
|
|
||||||
|
@ -102,6 +106,8 @@ class Tool:
|
||||||
if file:
|
if file:
|
||||||
file.close()
|
file.close()
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
|
if str(e)!="No module named %s"%self.name:
|
||||||
|
raise SCons.Errors.EnvironmentError, e
|
||||||
try:
|
try:
|
||||||
import zipimport
|
import zipimport
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -130,6 +136,8 @@ class Tool:
|
||||||
file.close()
|
file.close()
|
||||||
return module
|
return module
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
|
if e!="No module named %s"%self.name:
|
||||||
|
raise SCons.Errors.EnvironmentError, e
|
||||||
try:
|
try:
|
||||||
import zipimport
|
import zipimport
|
||||||
importer = zipimport.zipimporter( sys.modules['SCons.Tool'].__path__[0] )
|
importer = zipimport.zipimporter( sys.modules['SCons.Tool'].__path__[0] )
|
||||||
|
@ -138,10 +146,10 @@ class Tool:
|
||||||
return module
|
return module
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
m = "No tool named '%s': %s" % (self.name, e)
|
m = "No tool named '%s': %s" % (self.name, e)
|
||||||
raise SCons.Errors.UserError, m
|
raise SCons.Errors.EnvironmentError, m
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
m = "No tool named '%s': %s" % (self.name, e)
|
m = "No tool named '%s': %s" % (self.name, e)
|
||||||
raise SCons.Errors.UserError, m
|
raise SCons.Errors.EnvironmentError, m
|
||||||
|
|
||||||
def __call__(self, env, *args, **kw):
|
def __call__(self, env, *args, **kw):
|
||||||
if self.init_kw is not None:
|
if self.init_kw is not None:
|
||||||
|
@ -154,11 +162,24 @@ class Tool:
|
||||||
else:
|
else:
|
||||||
kw = self.init_kw
|
kw = self.init_kw
|
||||||
env.Append(TOOLS = [ self.name ])
|
env.Append(TOOLS = [ self.name ])
|
||||||
|
if hasattr(self, 'options'):
|
||||||
|
from SCons.Options import Options
|
||||||
|
if not env.has_key('options'):
|
||||||
|
from SCons.Script import ARGUMENTS
|
||||||
|
env['options']=Options(args=ARGUMENTS)
|
||||||
|
opts=env['options']
|
||||||
|
|
||||||
|
self.options(opts)
|
||||||
|
opts.Update(env)
|
||||||
|
|
||||||
apply(self.generate, ( env, ) + args, kw)
|
apply(self.generate, ( env, ) + args, kw)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Create common executable program / library / object builders
|
||||||
|
|
||||||
def createProgBuilder(env):
|
def createProgBuilder(env):
|
||||||
"""This is a utility function that creates the Program
|
"""This is a utility function that creates the Program
|
||||||
Builder in an Environment if it is not there already.
|
Builder in an Environment if it is not there already.
|
||||||
|
@ -316,7 +337,8 @@ def createCFileBuilders(env):
|
||||||
emitter = {},
|
emitter = {},
|
||||||
suffix = {None:'$CFILESUFFIX'})
|
suffix = {None:'$CFILESUFFIX'})
|
||||||
env['BUILDERS']['CFile'] = c_file
|
env['BUILDERS']['CFile'] = c_file
|
||||||
env['CFILESUFFIX'] = '.c'
|
|
||||||
|
env.SetDefault(CFILESUFFIX = '.c')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cxx_file = env['BUILDERS']['CXXFile']
|
cxx_file = env['BUILDERS']['CXXFile']
|
||||||
|
@ -325,10 +347,130 @@ def createCFileBuilders(env):
|
||||||
emitter = {},
|
emitter = {},
|
||||||
suffix = {None:'$CXXFILESUFFIX'})
|
suffix = {None:'$CXXFILESUFFIX'})
|
||||||
env['BUILDERS']['CXXFile'] = cxx_file
|
env['BUILDERS']['CXXFile'] = cxx_file
|
||||||
env['CXXFILESUFFIX'] = '.cc'
|
env.SetDefault(CXXFILESUFFIX = '.cc')
|
||||||
|
|
||||||
return (c_file, cxx_file)
|
return (c_file, cxx_file)
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Create common Java builders
|
||||||
|
|
||||||
|
def CreateJarBuilder(env):
|
||||||
|
try:
|
||||||
|
java_jar = env['BUILDERS']['Jar']
|
||||||
|
except KeyError:
|
||||||
|
fs = SCons.Node.FS.get_default_fs()
|
||||||
|
jar_com = SCons.Action.Action('$JARCOM', '$JARCOMSTR')
|
||||||
|
java_jar = SCons.Builder.Builder(action = jar_com,
|
||||||
|
suffix = '$JARSUFFIX',
|
||||||
|
src_suffix = '$JAVACLASSSUFIX',
|
||||||
|
src_builder = 'JavaClassFile',
|
||||||
|
source_factory = fs.Entry)
|
||||||
|
env['BUILDERS']['Jar'] = java_jar
|
||||||
|
return java_jar
|
||||||
|
|
||||||
|
def CreateJavaHBuilder(env):
|
||||||
|
try:
|
||||||
|
java_javah = env['BUILDERS']['JavaH']
|
||||||
|
except KeyError:
|
||||||
|
fs = SCons.Node.FS.get_default_fs()
|
||||||
|
java_javah_com = SCons.Action.Action('$JAVAHCOM', '$JAVAHCOMSTR')
|
||||||
|
java_javah = SCons.Builder.Builder(action = java_javah_com,
|
||||||
|
src_suffix = '$JAVACLASSSUFFIX',
|
||||||
|
target_factory = fs.Entry,
|
||||||
|
source_factory = fs.File,
|
||||||
|
src_builder = 'JavaClassFile')
|
||||||
|
env['BUILDERS']['JavaH'] = java_javah
|
||||||
|
return java_javah
|
||||||
|
|
||||||
|
def CreateJavaClassFileBuilder(env):
|
||||||
|
try:
|
||||||
|
java_class_file = env['BUILDERS']['JavaClassFile']
|
||||||
|
except KeyError:
|
||||||
|
fs = SCons.Node.FS.get_default_fs()
|
||||||
|
javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR')
|
||||||
|
java_class_file = SCons.Builder.Builder(action = javac_com,
|
||||||
|
emitter = {},
|
||||||
|
#suffix = '$JAVACLASSSUFFIX',
|
||||||
|
src_suffix = '$JAVASUFFIX',
|
||||||
|
src_builder = ['JavaFile'],
|
||||||
|
target_factory = fs.Entry,
|
||||||
|
source_factory = fs.File)
|
||||||
|
env['BUILDERS']['JavaClassFile'] = java_class_file
|
||||||
|
return java_class_file
|
||||||
|
|
||||||
|
def CreateJavaClassDirBuilder(env):
|
||||||
|
try:
|
||||||
|
java_class_dir = env['BUILDERS']['JavaClassDir']
|
||||||
|
except KeyError:
|
||||||
|
fs = SCons.Node.FS.get_default_fs()
|
||||||
|
javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR')
|
||||||
|
java_class_dir = SCons.Builder.Builder(action = javac_com,
|
||||||
|
emitter = {},
|
||||||
|
target_factory = fs.Dir,
|
||||||
|
source_factory = fs.Dir)
|
||||||
|
env['BUILDERS']['JavaClassDir'] = java_class_dir
|
||||||
|
return java_class_dir
|
||||||
|
|
||||||
|
def CreateJavaFileBuilder(env):
|
||||||
|
try:
|
||||||
|
java_file = env['BUILDERS']['JavaFile']
|
||||||
|
except KeyError:
|
||||||
|
java_file = SCons.Builder.Builder(action = {},
|
||||||
|
emitter = {},
|
||||||
|
suffix = {None:'$JAVASUFFIX'})
|
||||||
|
env['BUILDERS']['JavaFile'] = java_file
|
||||||
|
env['JAVASUFFIX'] = '.java'
|
||||||
|
return java_file
|
||||||
|
|
||||||
|
class ToolInitializer:
|
||||||
|
"""
|
||||||
|
A class for delayed initialization of Tools modules.
|
||||||
|
|
||||||
|
This is intended to be added to a construction environment in
|
||||||
|
place of the method(s) normally called for a Builder (env.Object,
|
||||||
|
env.StaticObject, etc.). When called, it searches the specified
|
||||||
|
list of tools, applies the first one that exists to the construction
|
||||||
|
environment, and calls whatever builder was (presumably) added the
|
||||||
|
construction environment in our place.
|
||||||
|
"""
|
||||||
|
def __init__(self, name, tools):
|
||||||
|
"""
|
||||||
|
Note: we store the tool name as __name__ so it can be used by
|
||||||
|
the class that attaches this to a construction environment.
|
||||||
|
"""
|
||||||
|
self.__name__ = name
|
||||||
|
if not SCons.Util.is_List(tools):
|
||||||
|
tools = [tools]
|
||||||
|
self.tools = tools
|
||||||
|
def __call__(self, env, *args, **kw):
|
||||||
|
for t in self.tools:
|
||||||
|
tool = SCons.Tool.Tool(t)
|
||||||
|
if tool.exists(env):
|
||||||
|
env.Tool(tool)
|
||||||
|
break
|
||||||
|
|
||||||
|
builder = getattr(env, self.__name__)
|
||||||
|
if builder is self:
|
||||||
|
# There was no Builder added, which means no valid Tool
|
||||||
|
# for this name was found (or possibly there's a mismatch
|
||||||
|
# between the name we were called by and the Builder name
|
||||||
|
# added by the Tool module).
|
||||||
|
#
|
||||||
|
# (Eventually this is where we'll put a more informative
|
||||||
|
# error message about the inability to find that tool
|
||||||
|
# as cut over more Builders+Tools to using this.
|
||||||
|
return [], []
|
||||||
|
|
||||||
|
# Let the construction environment remove the added method
|
||||||
|
# so we no longer copy and re-bind this method when the
|
||||||
|
# construction environment gets cloned.
|
||||||
|
env.RemoveMethod(self)
|
||||||
|
return apply(builder, args, kw)
|
||||||
|
|
||||||
|
def Initializers(env):
|
||||||
|
env.AddMethod(ToolInitializer('Install', 'install'))
|
||||||
|
env.AddMethod(ToolInitializer('InstallAs', 'install'))
|
||||||
|
|
||||||
def FindTool(tools, env):
|
def FindTool(tools, env):
|
||||||
for tool in tools:
|
for tool in tools:
|
||||||
t = Tool(tool)
|
t = Tool(tool)
|
||||||
|
@ -340,7 +482,7 @@ def FindAllTools(tools, env):
|
||||||
def ToolExists(tool, env=env):
|
def ToolExists(tool, env=env):
|
||||||
return Tool(tool).exists(env)
|
return Tool(tool).exists(env)
|
||||||
return filter (ToolExists, tools)
|
return filter (ToolExists, tools)
|
||||||
|
|
||||||
def tool_list(platform, env):
|
def tool_list(platform, env):
|
||||||
|
|
||||||
# XXX this logic about what tool to prefer on which platform
|
# XXX this logic about what tool to prefer on which platform
|
||||||
|
@ -414,11 +556,11 @@ def tool_list(platform, env):
|
||||||
ars = ['ar', 'mslib']
|
ars = ['ar', 'mslib']
|
||||||
|
|
||||||
c_compiler = FindTool(c_compilers, env) or c_compilers[0]
|
c_compiler = FindTool(c_compilers, env) or c_compilers[0]
|
||||||
|
|
||||||
# XXX this logic about what tool provides what should somehow be
|
# XXX this logic about what tool provides what should somehow be
|
||||||
# moved into the tool files themselves.
|
# moved into the tool files themselves.
|
||||||
if c_compiler and c_compiler == 'mingw':
|
if c_compiler and c_compiler == 'mingw':
|
||||||
# MinGW contains a linker, C compiler, C++ compiler,
|
# MinGW contains a linker, C compiler, C++ compiler,
|
||||||
# Fortran compiler, archiver and assembler:
|
# Fortran compiler, archiver and assembler:
|
||||||
cxx_compiler = None
|
cxx_compiler = None
|
||||||
linker = None
|
linker = None
|
||||||
|
@ -438,6 +580,7 @@ def tool_list(platform, env):
|
||||||
|
|
||||||
other_tools = FindAllTools(['BitKeeper', 'CVS',
|
other_tools = FindAllTools(['BitKeeper', 'CVS',
|
||||||
'dmd',
|
'dmd',
|
||||||
|
'filesystem',
|
||||||
'dvipdf', 'dvips', 'gs',
|
'dvipdf', 'dvips', 'gs',
|
||||||
'jar', 'javac', 'javah',
|
'jar', 'javac', 'javah',
|
||||||
'latex', 'lex',
|
'latex', 'lex',
|
||||||
|
@ -448,11 +591,11 @@ def tool_list(platform, env):
|
||||||
# 'Subversion',
|
# 'Subversion',
|
||||||
'swig',
|
'swig',
|
||||||
'tar', 'tex',
|
'tar', 'tex',
|
||||||
'yacc', 'zip'],
|
'yacc', 'zip', 'rpm', 'wix'],
|
||||||
env)
|
env)
|
||||||
|
|
||||||
tools = ([linker, c_compiler, cxx_compiler,
|
tools = ([linker, c_compiler, cxx_compiler,
|
||||||
fortran_compiler, assembler, ar]
|
fortran_compiler, assembler, ar]
|
||||||
+ other_tools)
|
+ other_tools)
|
||||||
|
|
||||||
return filter(lambda x: x, tools)
|
return filter(lambda x: x, tools)
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixc++.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/aixc++.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixcc.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/aixcc.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixf77.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/aixf77.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixlink.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/aixlink.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -44,7 +44,7 @@ cplusplus = __import__('c++', globals(), locals(), [])
|
||||||
|
|
||||||
def smart_linkflags(source, target, env, for_signature):
|
def smart_linkflags(source, target, env, for_signature):
|
||||||
if cplusplus.iscplusplus(source):
|
if cplusplus.iscplusplus(source):
|
||||||
build_dir = env.subst('$BUILDDIR')
|
build_dir = env.subst('$BUILDDIR', target=target, source=source)
|
||||||
if build_dir:
|
if build_dir:
|
||||||
return '-qtempinc=' + os.path.join(build_dir, 'tempinc')
|
return '-qtempinc=' + os.path.join(build_dir, 'tempinc')
|
||||||
return ''
|
return ''
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/applelink.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/applelink.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/ar.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/ar.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/as.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/as.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
|
@ -27,7 +27,7 @@ XXX
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/bcc32.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/bcc32.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -42,12 +42,7 @@ def findIt(program, env):
|
||||||
borwin = env.WhereIs(program) or SCons.Util.WhereIs(program)
|
borwin = env.WhereIs(program) or SCons.Util.WhereIs(program)
|
||||||
if borwin:
|
if borwin:
|
||||||
dir = os.path.dirname(borwin)
|
dir = os.path.dirname(borwin)
|
||||||
path = env['ENV'].get('PATH', [])
|
env.PrependENVPath('PATH', dir)
|
||||||
if not path:
|
|
||||||
path = []
|
|
||||||
if SCons.Util.is_String(path):
|
|
||||||
path = string.split(path, os.pathsep)
|
|
||||||
env['ENV']['PATH'] = string.join([dir]+path, os.pathsep)
|
|
||||||
return borwin
|
return borwin
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/c++.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/c++.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/cc.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/cc.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
|
@ -73,6 +73,18 @@ def generate(env):
|
||||||
shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
|
shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
|
||||||
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
||||||
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
|
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
|
||||||
|
#<<<<<<< .working
|
||||||
|
#
|
||||||
|
# env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS'
|
||||||
|
# # It's a hack to test for darwin here, but the alternative of creating
|
||||||
|
# # an applecc.py to contain this seems overkill. Maybe someday the Apple
|
||||||
|
# # platform will require more setup and this logic will be moved.
|
||||||
|
# env['FRAMEWORKS'] = SCons.Util.CLVar('')
|
||||||
|
# env['FRAMEWORKPATH'] = SCons.Util.CLVar('')
|
||||||
|
# if env['PLATFORM'] == 'darwin':
|
||||||
|
# env['_CCCOMCOM'] = env['_CCCOMCOM'] + ' $_FRAMEWORKPATH'
|
||||||
|
#=======
|
||||||
|
#>>>>>>> .merge-right.r1907
|
||||||
|
|
||||||
add_common_cc_variables(env)
|
add_common_cc_variables(env)
|
||||||
|
|
|
@ -27,7 +27,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/cvf.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/cvf.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import fortran
|
import fortran
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/default.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/default.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
|
|
@ -53,7 +53,7 @@ Lib tool variables:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dmd.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/dmd.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import string
|
import string
|
|
@ -27,7 +27,7 @@ Common DVI Builder definition for various other Tool modules that use it.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dvi.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/dvi.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Tool
|
import SCons.Tool
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dvipdf.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/dvipdf.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dvips.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/dvips.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f77.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/f77.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Scanner.Fortran
|
import SCons.Scanner.Fortran
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f90.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/f90.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Scanner.Fortran
|
import SCons.Scanner.Fortran
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f95.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/f95.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
92
scons/scons-local-0.97.0d20071212/SCons/Tool/filesystem.py
Normal file
92
scons/scons-local-0.97.0d20071212/SCons/Tool/filesystem.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
"""SCons.Tool.filesystem
|
||||||
|
|
||||||
|
Tool-specific initialization for the filesystem tools.
|
||||||
|
|
||||||
|
There normally shouldn't be any need to import this module directly.
|
||||||
|
It will usually be imported through the generic SCons.Tool.Tool()
|
||||||
|
selection method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
# a copy of this software and associated documentation files (the
|
||||||
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
# without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
# the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included
|
||||||
|
# in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
# 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__ = "src/engine/SCons/Tool/filesystem.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
import SCons
|
||||||
|
from SCons.Tool.install import copyFunc
|
||||||
|
|
||||||
|
copyToBuilder, copyAsBuilder = None, None
|
||||||
|
|
||||||
|
def copyto_emitter(target, source, env):
|
||||||
|
""" changes the path of the source to be under the target (which
|
||||||
|
are assumed to be directories.
|
||||||
|
"""
|
||||||
|
n_target = []
|
||||||
|
|
||||||
|
for t in target:
|
||||||
|
n_target = n_target + map( lambda s, t=t: t.File( str( s ) ), source )
|
||||||
|
|
||||||
|
return (n_target, source)
|
||||||
|
|
||||||
|
def copy_action_func(target, source, env):
|
||||||
|
assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(map(str, target),map(str, source))
|
||||||
|
|
||||||
|
for t, s in zip(target, source):
|
||||||
|
if copyFunc(t.get_path(), s.get_path(), env):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def copy_action_str(target, source, env):
|
||||||
|
return env.subst_target_source(env['COPYSTR'], 0, target, source)
|
||||||
|
|
||||||
|
copy_action = SCons.Action.Action( copy_action_func, copy_action_str )
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
try:
|
||||||
|
env['BUILDERS']['CopyTo']
|
||||||
|
env['BUILDERS']['CopyAs']
|
||||||
|
except KeyError, e:
|
||||||
|
global copyToBuilder
|
||||||
|
if copyToBuilder is None:
|
||||||
|
copyToBuilder = SCons.Builder.Builder(
|
||||||
|
action = copy_action,
|
||||||
|
target_factory = env.fs.Dir,
|
||||||
|
source_factory = env.fs.Entry,
|
||||||
|
multi = 1,
|
||||||
|
emitter = [ copyto_emitter, ] )
|
||||||
|
|
||||||
|
global copyAsBuilder
|
||||||
|
if copyAsBuilder is None:
|
||||||
|
copyAsBuilder = SCons.Builder.Builder(
|
||||||
|
action = copy_action,
|
||||||
|
target_factory = env.fs.Entry,
|
||||||
|
source_factory = env.fs.Entry )
|
||||||
|
|
||||||
|
env['BUILDERS']['CopyTo'] = copyToBuilder
|
||||||
|
env['BUILDERS']['CopyAs'] = copyAsBuilder
|
||||||
|
|
||||||
|
env['COPYSTR'] = 'Copy file(s): "$SOURCES" to "$TARGETS"'
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
return 1
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/fortran.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/fortran.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
|
@ -78,8 +78,8 @@ def _fortranEmitter(target, source, env):
|
||||||
# Remove unique items from the list
|
# Remove unique items from the list
|
||||||
modules = SCons.Util.unique(modules)
|
modules = SCons.Util.unique(modules)
|
||||||
# Convert module name to a .mod filename
|
# Convert module name to a .mod filename
|
||||||
suffix = env.subst('$FORTRANMODSUFFIX')
|
suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source)
|
||||||
moddir = env.subst('$FORTRANMODDIR')
|
moddir = env.subst('$FORTRANMODDIR', target=target, source=source)
|
||||||
modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
|
modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
|
||||||
for m in modules:
|
for m in modules:
|
||||||
target.append(env.fs.File(m, moddir))
|
target.append(env.fs.File(m, moddir))
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/g++.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/g++.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/g77.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/g77.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import f77
|
import f77
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/gas.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/gas.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
as_module = __import__('as', globals(), locals(), [])
|
as_module = __import__('as', globals(), locals(), [])
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/gcc.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/gcc.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/gnulink.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/gnulink.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/gs.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/gs.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Platform
|
import SCons.Platform
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/hpc++.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/hpc++.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import string
|
import string
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/hpcc.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/hpcc.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/hplink.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/hplink.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/icc.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/icc.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import cc
|
import cc
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/icl.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/icl.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Tool.intelc
|
import SCons.Tool.intelc
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/ifl.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/ifl.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
|
|
|
@ -32,7 +32,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/ifort.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/ifort.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/ilink.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/ilink.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
|
@ -27,7 +27,7 @@ XXX
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/ilink32.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/ilink32.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Tool.bcc32
|
import SCons.Tool.bcc32
|
226
scons/scons-local-0.97.0d20071212/SCons/Tool/install.py
Normal file
226
scons/scons-local-0.97.0d20071212/SCons/Tool/install.py
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
"""SCons.Tool.install
|
||||||
|
|
||||||
|
Tool-specific initialization for the install tool.
|
||||||
|
|
||||||
|
There normally shouldn't be any need to import this module directly.
|
||||||
|
It will usually be imported through the generic SCons.Tool.Tool()
|
||||||
|
selection method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
# a copy of this software and associated documentation files (the
|
||||||
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
# without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
# permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
# the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included
|
||||||
|
# in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
|
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
# 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__ = "src/engine/SCons/Tool/install.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import stat
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
|
from SCons.Util import make_path_relative
|
||||||
|
|
||||||
|
#
|
||||||
|
# We keep track of *all* installed files.
|
||||||
|
_INSTALLED_FILES = []
|
||||||
|
_UNIQUE_INSTALLED_FILES = None
|
||||||
|
|
||||||
|
#
|
||||||
|
# Functions doing the actual work of the Install Builder.
|
||||||
|
#
|
||||||
|
def copyFunc(dest, source, env):
|
||||||
|
"""Install a source file or directory into a destination by copying,
|
||||||
|
(including copying permission/mode bits)."""
|
||||||
|
|
||||||
|
if os.path.isdir(source):
|
||||||
|
if os.path.exists(dest):
|
||||||
|
if not os.path.isdir(dest):
|
||||||
|
raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source))
|
||||||
|
else:
|
||||||
|
parent = os.path.split(dest)[0]
|
||||||
|
if not os.path.exists(parent):
|
||||||
|
os.makedirs(parent)
|
||||||
|
shutil.copytree(source, dest)
|
||||||
|
else:
|
||||||
|
shutil.copy2(source, dest)
|
||||||
|
st = os.stat(source)
|
||||||
|
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def installFunc(target, source, env):
|
||||||
|
"""Install a source file into a target using the function specified
|
||||||
|
as the INSTALL construction variable."""
|
||||||
|
try:
|
||||||
|
install = env['INSTALL']
|
||||||
|
except KeyError:
|
||||||
|
raise SCons.Errors.UserError('Missing INSTALL construction variable.')
|
||||||
|
|
||||||
|
assert( len(target)==len(source) )
|
||||||
|
for t,s in zip(target,source):
|
||||||
|
if install(t.get_path(),s.get_path(),env):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def stringFunc(target, source, env):
|
||||||
|
installstr = env.get('INSTALLSTR')
|
||||||
|
if installstr:
|
||||||
|
return env.subst_target_source(installstr, 0, target, source)
|
||||||
|
target = str(target[0])
|
||||||
|
source = str(source[0])
|
||||||
|
if os.path.isdir(source):
|
||||||
|
type = 'directory'
|
||||||
|
else:
|
||||||
|
type = 'file'
|
||||||
|
return 'Install %s: "%s" as "%s"' % (type, source, target)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Emitter functions
|
||||||
|
#
|
||||||
|
def add_targets_to_INSTALLED_FILES(target, source, env):
|
||||||
|
""" an emitter that adds all target files to the list stored in the
|
||||||
|
_INSTALLED_FILES global variable. This way all installed files of one
|
||||||
|
scons call will be collected.
|
||||||
|
"""
|
||||||
|
global _INSTALLED_FILES, _UNIQUE_INSTALLED_FILES
|
||||||
|
_INSTALLED_FILES.extend(target)
|
||||||
|
_UNIQUE_INSTALLED_FILES = None
|
||||||
|
return (target, source)
|
||||||
|
|
||||||
|
class DESTDIR_factory:
|
||||||
|
""" a node factory, where all files will be relative to the dir supplied
|
||||||
|
in the constructor.
|
||||||
|
"""
|
||||||
|
def __init__(self, env, dir):
|
||||||
|
self.env = env
|
||||||
|
self.dir = env.arg2nodes( dir, env.fs.Dir )[0]
|
||||||
|
|
||||||
|
def Entry(self, name):
|
||||||
|
name = make_path_relative(name)
|
||||||
|
return self.dir.Entry(name)
|
||||||
|
|
||||||
|
def Dir(self, name):
|
||||||
|
name = make_path_relative(name)
|
||||||
|
return self.dir.Dir(name)
|
||||||
|
|
||||||
|
#
|
||||||
|
# The Builder Definition
|
||||||
|
#
|
||||||
|
install_action = SCons.Action.Action(installFunc, stringFunc)
|
||||||
|
installas_action = SCons.Action.Action(installFunc, stringFunc)
|
||||||
|
|
||||||
|
BaseInstallBuilder = None
|
||||||
|
|
||||||
|
def InstallBuilderWrapper(env, target, source, dir=None):
|
||||||
|
if target and dir:
|
||||||
|
raise SCons.Errors.UserError, "Both target and dir defined for Install(), only one may be defined."
|
||||||
|
if not dir:
|
||||||
|
dir=target
|
||||||
|
|
||||||
|
import SCons.Script
|
||||||
|
install_sandbox = SCons.Script.GetOption('install_sandbox')
|
||||||
|
if install_sandbox:
|
||||||
|
target_factory = DESTDIR_factory(env, install_sandbox)
|
||||||
|
else:
|
||||||
|
target_factory = env.fs
|
||||||
|
|
||||||
|
try:
|
||||||
|
dnodes = env.arg2nodes(dir, target_factory.Dir)
|
||||||
|
except TypeError:
|
||||||
|
raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir)
|
||||||
|
sources = env.arg2nodes(source, env.fs.Entry)
|
||||||
|
tgt = []
|
||||||
|
for dnode in dnodes:
|
||||||
|
for src in sources:
|
||||||
|
# Prepend './' so the lookup doesn't interpret an initial
|
||||||
|
# '#' on the file name portion as meaning the Node should
|
||||||
|
# be relative to the top-level SConstruct directory.
|
||||||
|
target = env.fs.Entry('.'+os.sep+src.name, dnode)
|
||||||
|
tgt.extend(BaseInstallBuilder(env, target, src))
|
||||||
|
return tgt
|
||||||
|
|
||||||
|
def InstallAsBuilderWrapper(env, target, source):
|
||||||
|
result = []
|
||||||
|
for src, tgt in map(lambda x, y: (x, y), source, target):
|
||||||
|
result.extend(BaseInstallBuilder(env, tgt, src))
|
||||||
|
return result
|
||||||
|
|
||||||
|
added = None
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
|
||||||
|
from SCons.Script import AddOption, GetOption
|
||||||
|
global added
|
||||||
|
if not added:
|
||||||
|
added = 1
|
||||||
|
AddOption('--install-sandbox',
|
||||||
|
dest='install_sandbox',
|
||||||
|
type="string",
|
||||||
|
action="store",
|
||||||
|
help='A directory under which all installed files will be placed.')
|
||||||
|
|
||||||
|
global BaseInstallBuilder
|
||||||
|
if BaseInstallBuilder is None:
|
||||||
|
install_sandbox = GetOption('install_sandbox')
|
||||||
|
if install_sandbox:
|
||||||
|
target_factory = DESTDIR_factory(env, install_sandbox)
|
||||||
|
else:
|
||||||
|
target_factory = env.fs
|
||||||
|
|
||||||
|
BaseInstallBuilder = SCons.Builder.Builder(
|
||||||
|
action = install_action,
|
||||||
|
target_factory = target_factory.Entry,
|
||||||
|
source_factory = env.fs.Entry,
|
||||||
|
multi = 1,
|
||||||
|
emitter = [ add_targets_to_INSTALLED_FILES, ],
|
||||||
|
name = 'InstallBuilder')
|
||||||
|
|
||||||
|
try:
|
||||||
|
env['BUILDERS']['Install']
|
||||||
|
except KeyError, e:
|
||||||
|
env['BUILDERS']['Install'] = InstallBuilderWrapper
|
||||||
|
|
||||||
|
try:
|
||||||
|
env['BUILDERS']['InstallAs']
|
||||||
|
except KeyError, e:
|
||||||
|
env['BUILDERS']['InstallAs'] = InstallAsBuilderWrapper
|
||||||
|
|
||||||
|
# We'd like to initialize this doing something like the following,
|
||||||
|
# but there isn't yet support for a ${SOURCE.type} expansion that
|
||||||
|
# will print "file" or "directory" depending on what's being
|
||||||
|
# installed. For now we punt by not initializing it, and letting
|
||||||
|
# the stringFunc() that we put in the action fall back to the
|
||||||
|
# hand-crafted default string if it's not set.
|
||||||
|
#
|
||||||
|
#try:
|
||||||
|
# env['INSTALLSTR']
|
||||||
|
#except KeyError:
|
||||||
|
# env['INSTALLSTR'] = 'Install ${SOURCE.type}: "$SOURCES" as "$TARGETS"'
|
||||||
|
|
||||||
|
try:
|
||||||
|
env['INSTALL']
|
||||||
|
except KeyError:
|
||||||
|
env['INSTALL'] = copyFunc
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
return 1
|
|
@ -32,11 +32,14 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/intelc.py 0.97.D001 2007/05/17 11:35:19 knight"
|
__revision__ = "src/engine/SCons/Tool/intelc.py 2523 2007/12/12 09:37:41 knight"
|
||||||
|
|
||||||
import math, sys, os.path, glob, string, re
|
import math, sys, os.path, glob, string, re
|
||||||
|
|
||||||
is_windows = sys.platform == 'win32'
|
is_windows = sys.platform == 'win32'
|
||||||
|
is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or
|
||||||
|
(os.environ.has_key('PROCESSOR_ARCHITEW6432') and
|
||||||
|
os.environ['PROCESSOR_ARCHITEW6432'] == 'AMD64'))
|
||||||
is_linux = sys.platform == 'linux2'
|
is_linux = sys.platform == 'linux2'
|
||||||
|
|
||||||
if is_windows:
|
if is_windows:
|
||||||
|
@ -138,7 +141,10 @@ def get_intel_registry_value(valuename, version=None, abi=None):
|
||||||
Return a value from the Intel compiler registry tree. (Windows only)
|
Return a value from the Intel compiler registry tree. (Windows only)
|
||||||
"""
|
"""
|
||||||
# Open the key:
|
# Open the key:
|
||||||
K = 'Software\\Intel\\Compilers\\C++\\' + version + '\\'+abi.upper()
|
if is_win64:
|
||||||
|
K = 'Software\\Wow6432Node\\Intel\\Compilers\\C++\\' + version + '\\'+abi.upper()
|
||||||
|
else:
|
||||||
|
K = 'Software\\Intel\\Compilers\\C++\\' + version + '\\'+abi.upper()
|
||||||
try:
|
try:
|
||||||
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
|
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
|
||||||
except SCons.Util.RegError:
|
except SCons.Util.RegError:
|
||||||
|
@ -160,7 +166,10 @@ def get_all_compiler_versions():
|
||||||
"""
|
"""
|
||||||
versions=[]
|
versions=[]
|
||||||
if is_windows:
|
if is_windows:
|
||||||
keyname = 'Software\\Intel\\Compilers\\C++'
|
if is_win64:
|
||||||
|
keyname = 'Software\\WoW6432Node\\Intel\\Compilers\\C++'
|
||||||
|
else:
|
||||||
|
keyname = 'Software\\Intel\\Compilers\\C++'
|
||||||
try:
|
try:
|
||||||
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
|
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
|
||||||
keyname)
|
keyname)
|
||||||
|
@ -178,7 +187,7 @@ def get_all_compiler_versions():
|
||||||
# than uninstalling properly), so the registry values
|
# than uninstalling properly), so the registry values
|
||||||
# are still there.
|
# are still there.
|
||||||
ok = False
|
ok = False
|
||||||
for try_abi in ('IA32', 'IA32e', 'IA64'):
|
for try_abi in ('IA32', 'IA32e', 'IA64', 'EM64T'):
|
||||||
try:
|
try:
|
||||||
d = get_intel_registry_value('ProductDir', subkey, try_abi)
|
d = get_intel_registry_value('ProductDir', subkey, try_abi)
|
||||||
except MissingRegistryError:
|
except MissingRegistryError:
|
||||||
|
@ -212,6 +221,7 @@ def get_intel_compiler_top(version, abi):
|
||||||
The compiler will be in <top>/bin/icl.exe (icc on linux),
|
The compiler will be in <top>/bin/icl.exe (icc on linux),
|
||||||
the include dir is <top>/include, etc.
|
the include dir is <top>/include, etc.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if is_windows:
|
if is_windows:
|
||||||
if not SCons.Util.can_read_reg:
|
if not SCons.Util.can_read_reg:
|
||||||
raise NoRegistryModuleError, "No Windows registry module was found"
|
raise NoRegistryModuleError, "No Windows registry module was found"
|
||||||
|
@ -282,8 +292,10 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
|
||||||
else:
|
else:
|
||||||
abi = 'ia32'
|
abi = 'ia32'
|
||||||
else:
|
else:
|
||||||
# XXX: how would we do the same test on Windows?
|
if is_win64:
|
||||||
abi = "ia32"
|
abi = 'em64t'
|
||||||
|
else:
|
||||||
|
abi = 'ia32'
|
||||||
|
|
||||||
if version and not topdir:
|
if version and not topdir:
|
||||||
try:
|
try:
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue