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
|
||||
|
||||
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
|
||||
# src/README.txt 0.97.D001 2007/05/17 11:35:19 knight
|
||||
|
||||
|
||||
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
|
||||
files). SCons is implemented in Python, and its "configuration files"
|
||||
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.
|
||||
1) You have unpacked an scons-local-{version} package and are
|
||||
examining the contents.
|
||||
|
||||
See the RELEASE.txt file for notes about this specific release,
|
||||
including known problems. See the CHANGES.txt file for a list of
|
||||
changes since the previous release.
|
||||
In this case, you are presumably interested in using this
|
||||
package to include a local copy of SCons with some other
|
||||
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
|
||||
==============
|
||||
|
||||
Before going further, you can check that this package you have is
|
||||
the latest version by checking the SCons download page at:
|
||||
Before going further, you can check for the latest version of the
|
||||
scons-local package, or any SCons package, at the SCons download page:
|
||||
|
||||
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
|
||||
no other dependencies or requirements to run SCons. (There is, however,
|
||||
an additional requirement to *install* SCons from this particular
|
||||
package; see the next section.)
|
||||
no other dependencies or requirements to run SCons.
|
||||
|
||||
By default, SCons knows how to search for available programming tools
|
||||
on various systems--see the SCons man page for details. You may,
|
||||
of course, override the default SCons choices made by appropriate
|
||||
The default SCons configuration assumes use of the Microsoft Visual C++
|
||||
compiler suite on WIN32 systems, and assumes a C compiler named 'cc',
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
============
|
||||
|
||||
Assuming your system satisfies the installation requirements in the
|
||||
previous section, install SCons from this package simply by running the
|
||||
provided Python-standard setup script as follows:
|
||||
Installation of this package should be as simple as unpacking the
|
||||
archive (either .tar.gz or .zip) in any directory (top-level or a
|
||||
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"
|
||||
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.
|
||||
$ python scons.py
|
||||
|
||||
-- Install scripts named "scons" and "sconsign" scripts in the
|
||||
default system script directory (/usr/bin or C:\Python*\Scripts,
|
||||
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.
|
||||
Or (if, for example, you installed this package in a subdirectory named
|
||||
"scons"):
|
||||
|
||||
On UNIX or Linux systems, you can have the "scons" and "sconsign"
|
||||
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.
|
||||
$ python scons/scons.py
|
||||
|
||||
-- Install "scons-0.97.bat" and "scons.bat" wrapper scripts in the
|
||||
Python prefix directory on Windows (C:\Python*, for example).
|
||||
This can be disabled by specifying the "--no-install-bat" option
|
||||
on the command line.
|
||||
That should be all you have to do. (If it isn't that simple, please let
|
||||
us know!)
|
||||
|
||||
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
|
||||
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.
|
||||
CONTENTS OF THIS PACKAGE
|
||||
========================
|
||||
|
||||
-- Install the troff-format man pages in an appropriate directory
|
||||
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.
|
||||
This scons-local package consists of the following:
|
||||
|
||||
Note that, by default, SCons does not install its build engine library
|
||||
in the standard Python library directories. If you want to be able to
|
||||
use the SCons library modules (the build engine) in other Python
|
||||
scripts, specify the "--standard-lib" option on the command line, as
|
||||
follows:
|
||||
scons-LICENSE
|
||||
A copy of the copyright and terms under which SCons is
|
||||
distributed (the Open Source Initiative-approved MIT license).
|
||||
|
||||
# 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
|
||||
directory (/usr/lib/python*/site-packages or
|
||||
C:\Python*\Lib\site-packages).
|
||||
scons-README
|
||||
What you're looking at right now.
|
||||
|
||||
Alternatively, you can have SCons install its build engine library in a
|
||||
hard-coded standalone library directory, instead of the default
|
||||
version-numbered directory, by specifying the "--standalone-lib" option
|
||||
on the command line, as follows:
|
||||
scons-local-{version}/
|
||||
The SCons build engine. This is structured as a Python
|
||||
library.
|
||||
|
||||
# python setup.py install --standalone-lib
|
||||
|
||||
This is usually not recommended, however.
|
||||
|
||||
Note that, to install SCons in any of the above system directories,
|
||||
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.
|
||||
scons.py
|
||||
The SCons script itself. The script sets up the Python
|
||||
sys.path variable to use the build engine found in the
|
||||
scons-local-{version}/ directory in preference to any other
|
||||
SCons build engine installed on your system.
|
||||
|
||||
|
||||
DOCUMENTATION
|
||||
=============
|
||||
|
||||
See the RELEASE.txt file for notes about this specific release,
|
||||
including known problems. See the CHANGES.txt file for a list of
|
||||
changes since the previous release.
|
||||
Because this package is intended to be included with other software by
|
||||
experienced users, we have not included any SCons documentation in this
|
||||
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
|
||||
of small examples for getting started using SCons.
|
||||
If, however, you need documentation about SCons, then consult any of the
|
||||
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:
|
||||
|
||||
|
@ -184,8 +142,8 @@ LICENSING
|
|||
=========
|
||||
|
||||
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
|
||||
Source license, which means:
|
||||
available in the scons-LICENSE file in this package. The MIT license is
|
||||
an approved Open Source license, which means:
|
||||
|
||||
This software is OSI Certified Open Source Software. OSI
|
||||
Certified is a certification mark of the Open Source Initiative.
|
||||
|
@ -199,51 +157,27 @@ available at:
|
|||
REPORTING BUGS
|
||||
==============
|
||||
|
||||
Please report bugs by following the detailed instructions on our Bug
|
||||
Submission page:
|
||||
You can report bugs either by following the "Tracker - Bugs" link
|
||||
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
|
||||
|
||||
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.
|
||||
scons-devel@lists.sourceforge.net
|
||||
|
||||
|
||||
MAILING LISTS
|
||||
=============
|
||||
|
||||
An active mailing list for users of SCons is available. You may send
|
||||
questions or comments to the list at:
|
||||
A mailing list for users of SCons is available. You may send questions
|
||||
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
|
||||
|
||||
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
|
||||
http://lists.sourceforge.net/lists/listinfo/scons-users
|
||||
|
||||
|
||||
FOR MORE INFORMATION
|
||||
|
@ -265,9 +199,6 @@ With plenty of help from the SCons Development team:
|
|||
Chad Austin
|
||||
Charles Crain
|
||||
Steve Leblanc
|
||||
Greg Noel
|
||||
Gary Oberbrunner
|
||||
Anthony Roach
|
||||
Greg Spencer
|
||||
Christoph Wiedemann
|
||||
Terrel Shumway
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ other modules:
|
|||
|
||||
get_contents()
|
||||
Fetches the "contents" of an Action for signature calculation.
|
||||
This is what the Sig/*.py subsystem uses to decide if a target
|
||||
needs to be rebuilt because its action changed.
|
||||
This is what gets MD5 checksumm'ed to decide if a target needs
|
||||
to be rebuilt because its action changed.
|
||||
|
||||
genstring()
|
||||
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.
|
||||
#
|
||||
|
||||
__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 os
|
||||
|
@ -287,6 +287,7 @@ class _ActionAction(ActionBase):
|
|||
target = [target]
|
||||
if not SCons.Util.is_List(source):
|
||||
source = [source]
|
||||
|
||||
if exitstatfunc is _null: exitstatfunc = self.exitstatfunc
|
||||
if presub is _null:
|
||||
presub = self.presub
|
||||
|
@ -329,12 +330,20 @@ class _ActionAction(ActionBase):
|
|||
os.chdir(chdir)
|
||||
try:
|
||||
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:
|
||||
if save_cwd:
|
||||
os.chdir(save_cwd)
|
||||
if s and save_cwd:
|
||||
print_func('os.chdir(%s)' % repr(save_cwd), target, source, env)
|
||||
|
||||
return stat
|
||||
|
||||
|
||||
|
@ -476,7 +485,11 @@ class CommandAction(_ActionAction):
|
|||
cmd_line = escape_list(cmd_line, escape)
|
||||
result = spawn(shell, escape, cmd_line[0], cmd_line, ENV)
|
||||
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
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
|
@ -493,6 +506,22 @@ class CommandAction(_ActionAction):
|
|||
cmd = str(cmd)
|
||||
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 for command-generator actions."""
|
||||
def __init__(self, generator, *args, **kw):
|
||||
|
@ -515,9 +544,11 @@ class CommandGeneratorAction(ActionBase):
|
|||
|
||||
def __str__(self):
|
||||
try:
|
||||
env = self.presub_env or {}
|
||||
env = self.presub_env
|
||||
except AttributeError:
|
||||
env = {}
|
||||
env = None
|
||||
if env is None:
|
||||
env = SCons.Defaults.DefaultEnvironment()
|
||||
act = self._generate([], [], env, 1)
|
||||
return str(act)
|
||||
|
||||
|
@ -538,6 +569,9 @@ class CommandGeneratorAction(ActionBase):
|
|||
"""
|
||||
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
|
||||
|
@ -666,9 +700,19 @@ class FunctionAction(_ActionAction):
|
|||
# target file will appear).
|
||||
try: filename = e.filename
|
||||
except AttributeError: filename = None
|
||||
raise SCons.Errors.BuildError(node=target,
|
||||
errstr=e.strerror,
|
||||
filename=filename)
|
||||
result = SCons.Errors.BuildError(node=target,
|
||||
errstr=e.strerror,
|
||||
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
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
|
@ -713,6 +757,9 @@ class FunctionAction(_ActionAction):
|
|||
return contents + env.subst(string.join(map(lambda v: '${'+v+'}',
|
||||
self.varlist)))
|
||||
|
||||
def get_implicit_deps(self, target, source, env):
|
||||
return []
|
||||
|
||||
class ListAction(ActionBase):
|
||||
"""Class for lists of other actions."""
|
||||
def __init__(self, list):
|
||||
|
@ -756,6 +803,12 @@ class ListAction(ActionBase):
|
|||
return stat
|
||||
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:
|
||||
"""A class for delaying calling an Action function with specific
|
||||
(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.
|
||||
if s == '$__env__':
|
||||
return env
|
||||
else:
|
||||
elif SCons.Util.is_String(s):
|
||||
return env.subst(s, 0, target, source)
|
||||
return self.parent.convert(s)
|
||||
def subst_args(self, target, source, env):
|
||||
return map(lambda x, self=self, t=target, s=source, e=env:
|
||||
self.subst(x, t, s, e),
|
||||
|
@ -821,9 +875,10 @@ class ActionFactory:
|
|||
called with and give them to the ActionCaller object we create,
|
||||
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.strfunc = strfunc
|
||||
self.convert = convert
|
||||
def __call__(self, *args, **kw):
|
||||
ac = ActionCaller(self, args, kw)
|
||||
action = Action(ac, strfunction=ac.strfunction)
|
|
@ -39,9 +39,6 @@ used by other modules:
|
|||
variable. This also takes care of warning about possible mistakes
|
||||
in keyword arguments.
|
||||
|
||||
targets()
|
||||
Returns the list of targets for a specific builder instance.
|
||||
|
||||
add_emitter()
|
||||
Adds an emitter for a specific file suffix, used by some Tool
|
||||
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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
||||
|
@ -367,6 +364,7 @@ class BuilderBase:
|
|||
chdir = _null,
|
||||
is_explicit = 1,
|
||||
src_builder = [],
|
||||
ensure_suffix = False,
|
||||
**overrides):
|
||||
if __debug__: logInstanceCreation(self, 'Builder.BuilderBase')
|
||||
self._memo = {}
|
||||
|
@ -394,6 +392,7 @@ class BuilderBase:
|
|||
|
||||
self.set_suffix(suffix)
|
||||
self.set_src_suffix(src_suffix)
|
||||
self.ensure_suffix = ensure_suffix
|
||||
|
||||
self.target_factory = target_factory
|
||||
self.source_factory = source_factory
|
||||
|
@ -467,28 +466,28 @@ class BuilderBase:
|
|||
executor.add_sources(slist)
|
||||
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):
|
||||
"""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)
|
||||
|
||||
target_factory = env.get_factory(self.target_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)
|
||||
|
||||
pre = self.get_prefix(env, slist)
|
||||
|
@ -505,7 +504,7 @@ class BuilderBase:
|
|||
splitext = lambda S,self=self,env=env: self.splitext(S,env)
|
||||
tlist = [ t_from_s(pre, suf, splitext) ]
|
||||
else:
|
||||
target = _adjustixes(target, pre, suf)
|
||||
target = self._adjustixes(target, pre, suf, self.ensure_suffix)
|
||||
tlist = env.arg2nodes(target, target_factory)
|
||||
|
||||
if self.emitter:
|
||||
|
@ -520,6 +519,9 @@ class BuilderBase:
|
|||
t.builder_set(self)
|
||||
new_targets.append(t)
|
||||
|
||||
orig_tlist = tlist[:]
|
||||
orig_slist = slist[:]
|
||||
|
||||
target, source = self.emitter(target=tlist, source=slist, env=env)
|
||||
|
||||
# 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
|
||||
# emitters to spit out strings as well as Node instances.
|
||||
tlist = env.arg2nodes(target, target_factory)
|
||||
slist = env.arg2nodes(source, source_factory)
|
||||
tlist = env.arg2nodes(target, target_factory,
|
||||
target=orig_tlist, source=orig_slist)
|
||||
slist = env.arg2nodes(source, source_factory,
|
||||
target=orig_tlist, source=orig_slist)
|
||||
|
||||
return tlist, slist
|
||||
|
||||
|
@ -550,7 +554,7 @@ class BuilderBase:
|
|||
if not tgt is None: tgt = [tgt]
|
||||
if not src is None: src = [src]
|
||||
result.extend(self._execute(env, tgt, src, overwarn))
|
||||
return result
|
||||
return SCons.Node.NodeList(result)
|
||||
|
||||
overwarn.warn()
|
||||
|
||||
|
@ -647,13 +651,6 @@ class BuilderBase:
|
|||
return ''
|
||||
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):
|
||||
"""Add a suffix-emitter mapping to this Builder.
|
||||
|
||||
|
@ -701,20 +698,14 @@ class BuilderBase:
|
|||
return sdict
|
||||
|
||||
def src_builder_sources(self, env, source, overwarn={}):
|
||||
source_factory = env.get_factory(self.source_factory)
|
||||
slist = env.arg2nodes(source, source_factory)
|
||||
|
||||
sdict = self._get_sdict(env)
|
||||
|
||||
src_suffixes = self.src_suffixes(env)
|
||||
|
||||
lengths_dict = {}
|
||||
for l in map(len, src_suffixes):
|
||||
lengths_dict[l] = None
|
||||
lengths = lengths_dict.keys()
|
||||
lengths = list(set(map(len, src_suffixes)))
|
||||
|
||||
def match_src_suffix(node, src_suffixes=src_suffixes, lengths=lengths):
|
||||
node_suffixes = map(lambda l, n=node: n.name[-l:], lengths)
|
||||
def match_src_suffix(name, src_suffixes=src_suffixes, lengths=lengths):
|
||||
node_suffixes = map(lambda l, n=name: n[-l:], lengths)
|
||||
for suf in src_suffixes:
|
||||
if suf in node_suffixes:
|
||||
return suf
|
||||
|
@ -722,25 +713,38 @@ class BuilderBase:
|
|||
|
||||
result = []
|
||||
|
||||
for snode in slist:
|
||||
match_suffix = match_src_suffix(snode)
|
||||
if SCons.Util.is_List(source):
|
||||
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:
|
||||
try:
|
||||
bld = sdict[match_suffix]
|
||||
except KeyError:
|
||||
result.append(snode)
|
||||
result.append(s)
|
||||
else:
|
||||
tlist = bld._execute(env, None, [snode], overwarn)
|
||||
tlist = bld._execute(env, None, [s], overwarn)
|
||||
# If the subsidiary Builder returned more than one
|
||||
# target, then filter out any sources that this
|
||||
# Builder isn't capable of building.
|
||||
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)
|
||||
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):
|
||||
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
|
||||
|
||||
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,
|
||||
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)
|
||||
context.havedict[key_up] = have
|
||||
if have == 1:
|
||||
line = "#define %s\n" % key_up
|
||||
line = "#define %s 1\n" % key_up
|
||||
elif have == 0:
|
||||
line = "/* #undef %s */\n" % key_up
|
||||
elif type(have) == IntType:
|
|
@ -29,7 +29,7 @@ needed by most users.
|
|||
# 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 string
|
||||
|
@ -197,3 +197,4 @@ def Trace(msg, file=None, mode='w'):
|
|||
# Assume we were passed an open file pointer.
|
||||
fp = file
|
||||
fp.write(msg)
|
||||
fp.flush()
|
|
@ -32,7 +32,7 @@ from distutils.msvccompiler.
|
|||
# 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.Builder
|
||||
import SCons.CacheDir
|
||||
import SCons.Environment
|
||||
import SCons.PathList
|
||||
import SCons.Sig
|
||||
import SCons.Subst
|
||||
import SCons.Tool
|
||||
|
||||
|
@ -60,12 +60,40 @@ _default_env = None
|
|||
|
||||
# Lazily instantiate the default environment so the overhead of creating
|
||||
# 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):
|
||||
"""
|
||||
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
|
||||
if not _default_env:
|
||||
import SCons.Util
|
||||
_default_env = apply(SCons.Environment.Environment, args, kw)
|
||||
_default_env._build_signature = 1
|
||||
_default_env._calc_module = SCons.Sig.default_module
|
||||
if SCons.Util.md5:
|
||||
_default_env.Decider('MD5')
|
||||
else:
|
||||
_default_env.Decider('timestamp-match')
|
||||
global DefaultEnvironment
|
||||
DefaultEnvironment = _fetch_DefaultEnvironment
|
||||
_default_env._CacheDir = SCons.CacheDir.Null()
|
||||
return _default_env
|
||||
|
||||
# Emitters for setting the shared attribute on object files,
|
||||
|
@ -104,9 +132,9 @@ LaTeXScan = SCons.Tool.LaTeXScanner
|
|||
ObjSourceScan = SCons.Tool.SourceFileScanner
|
||||
ProgScan = SCons.Tool.ProgramScanner
|
||||
|
||||
# This isn't really a tool scanner, so it doesn't quite belong with
|
||||
# the rest of those in Tool/__init__.py, but I'm not sure where else it
|
||||
# should go. Leave it here for now.
|
||||
# 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
|
||||
# they should go. Leave them here for now.
|
||||
import SCons.Scanner.Dir
|
||||
DirScanner = SCons.Scanner.Dir.DirScanner()
|
||||
DirEntryScanner = SCons.Scanner.Dir.DirEntryScanner()
|
||||
|
@ -129,19 +157,28 @@ LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR")
|
|||
# ways by creating ActionFactory instances.
|
||||
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))
|
||||
|
||||
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)
|
||||
else:
|
||||
return shutil.copytree(src, dest, 1)
|
||||
|
||||
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):
|
||||
entry = str(entry)
|
||||
if not must_exist and not os.path.exists(entry):
|
||||
return None
|
||||
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)
|
||||
|
||||
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),
|
||||
lambda dest, src: 'Move("%s", "%s")' % (dest, src))
|
||||
lambda dest, src: 'Move("%s", "%s")' % (dest, src),
|
||||
convert=str)
|
||||
|
||||
def touch_func(file):
|
||||
file = str(file)
|
||||
mtime = int(time.time())
|
||||
if os.path.exists(file):
|
||||
atime = os.path.getatime(file)
|
||||
|
@ -173,33 +213,6 @@ Touch = ActionFactory(touch_func,
|
|||
lambda file: 'Touch("%s")' % file)
|
||||
|
||||
# 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):
|
||||
"""
|
||||
|
@ -258,91 +271,46 @@ def _concat_ixes(prefix, list, suffix, env):
|
|||
return result
|
||||
|
||||
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
|
||||
finds them. This is used by tools (like the GNU linker) that need
|
||||
to turn something like 'libfoo.a' into '-lfoo'."""
|
||||
"""
|
||||
This is a wrapper around _concat()/_concat_ixes() that checks for the
|
||||
existence of prefixes or suffixes on list elements and strips them
|
||||
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 list:
|
||||
return list
|
||||
|
||||
if not callable(c):
|
||||
if callable(env["_concat"]):
|
||||
c = env["_concat"]
|
||||
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
|
||||
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)
|
||||
c = _concat_ixes
|
||||
|
||||
# This is an alternate _stripixes() function that passes all of our tests
|
||||
# (as of 21 February 2007), like the current version above. It's more
|
||||
# straightforward because it does its manipulation directly, not using
|
||||
# the funky f call-back function to _concat(). (In this respect it's
|
||||
# like the updated _defines() function below.)
|
||||
#
|
||||
# The most convoluted thing is that it still uses a custom _concat()
|
||||
# function if one was placed in the construction environment; there's
|
||||
# a specific test for that functionality, but it might be worth getting
|
||||
# rid of.
|
||||
#
|
||||
# Since this work was done while trying to get 0.97 out the door
|
||||
# (just prior to 0.96.96), I decided to be cautious and leave the old
|
||||
# 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
|
||||
# using it at a less sensitive time in the development cycle (or when
|
||||
# it's clearly required to fix something).
|
||||
#
|
||||
#def _stripixes(prefix, list, suffix, stripprefix, stripsuffix, env, c=None):
|
||||
# """
|
||||
# This is a wrapper around _concat()/_concat_ixes() that checks for the
|
||||
# existence of prefixes or suffixes on list elements and strips them
|
||||
# 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 list:
|
||||
# return list
|
||||
#
|
||||
# if not callable(c):
|
||||
# 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)
|
||||
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):
|
||||
"""A wrapper around _concat_ixes that turns a list or string
|
||||
|
@ -430,9 +398,6 @@ ConstructionEnvironment = {
|
|||
'DSUFFIXES' : SCons.Tool.DSuffixes,
|
||||
'ENV' : {},
|
||||
'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
|
||||
'INSTALL' : installFunc,
|
||||
'INSTALLSTR' : installStr,
|
||||
'_installStr' : installStr,
|
||||
'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes,
|
||||
'_concat' : _concat,
|
||||
'_defines' : _defines,
|
|
@ -32,12 +32,13 @@ Environment
|
|||
# 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 os
|
||||
import os.path
|
||||
import shlex
|
||||
import string
|
||||
from UserDict import UserDict
|
||||
|
||||
|
@ -53,7 +54,6 @@ import SCons.Node.FS
|
|||
import SCons.Node.Python
|
||||
import SCons.Platform
|
||||
import SCons.SConsign
|
||||
import SCons.Sig
|
||||
import SCons.Subst
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
|
@ -67,32 +67,13 @@ _null = _Null
|
|||
CleanTargets = {}
|
||||
CalculatorArgs = {}
|
||||
|
||||
semi_deepcopy = SCons.Util.semi_deepcopy
|
||||
|
||||
# Pull UserError into the global name space for the benefit of
|
||||
# Environment().SourceSignatures(), which has some import statements
|
||||
# which seem to mess up its ability to reference SCons directly.
|
||||
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):
|
||||
pass
|
||||
|
||||
|
@ -103,23 +84,6 @@ AliasBuilder = SCons.Builder.Builder(action = alias_builder,
|
|||
is_explicit = None,
|
||||
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):
|
||||
# Store the toolpath in the Environment.
|
||||
if toolpath is not None:
|
||||
|
@ -143,7 +107,7 @@ reserved_construction_var_names = \
|
|||
['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']
|
||||
|
||||
def copy_non_reserved_keywords(dict):
|
||||
result = our_deepcopy(dict)
|
||||
result = semi_deepcopy(dict)
|
||||
for k in result.keys():
|
||||
if k in reserved_construction_var_names:
|
||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning,
|
||||
|
@ -161,8 +125,9 @@ def _set_BUILDERS(env, key, value):
|
|||
for k in bd.keys():
|
||||
del bd[k]
|
||||
except KeyError:
|
||||
env._dict[key] = BuilderDict(kwbd, env)
|
||||
env._dict[key].update(value)
|
||||
bd = BuilderDict(kwbd, env)
|
||||
env._dict[key] = bd
|
||||
bd.update(value)
|
||||
|
||||
def _del_SCANNERS(env, key):
|
||||
del env._dict[key]
|
||||
|
@ -172,13 +137,72 @@ def _set_SCANNERS(env, key, value):
|
|||
env._dict[key] = value
|
||||
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):
|
||||
if source is _null:
|
||||
source = target
|
||||
|
@ -187,7 +211,29 @@ class BuilderWrapper:
|
|||
target = [target]
|
||||
if not source is None and not SCons.Util.is_List(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
|
||||
# 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
|
||||
# yet rule out that it would be useful in the
|
||||
# future, so leave it for now.
|
||||
def execute(self, **kw):
|
||||
kw['env'] = self.env
|
||||
apply(self.builder.execute, (), kw)
|
||||
#def execute(self, **kw):
|
||||
# kw['env'] = self.env
|
||||
# apply(self.builder.execute, (), kw)
|
||||
|
||||
class BuilderDict(UserDict):
|
||||
"""This is a dictionary-like class used by an Environment to hold
|
||||
|
@ -212,28 +258,18 @@ class BuilderDict(UserDict):
|
|||
self.env = env
|
||||
UserDict.__init__(self, dict)
|
||||
|
||||
def __semi_deepcopy__(self):
|
||||
return self.__class__(self.data, self.env)
|
||||
|
||||
def __setitem__(self, item, val):
|
||||
UserDict.__setitem__(self, item, val)
|
||||
try:
|
||||
self.setenvattr(item, val)
|
||||
method = getattr(self.env, item).method
|
||||
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
|
||||
|
||||
def setenvattr(self, item, val):
|
||||
"""Set the corresponding environment attribute for this Builder.
|
||||
|
||||
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))
|
||||
else:
|
||||
self.env.RemoveMethod(method)
|
||||
UserDict.__setitem__(self, item, val)
|
||||
BuilderWrapper(self.env, val, item)
|
||||
|
||||
def __delitem__(self, item):
|
||||
UserDict.__delitem__(self, item)
|
||||
|
@ -276,11 +312,12 @@ class SubstitutionEnvironment:
|
|||
"""Initialization of an underlying SubstitutionEnvironment class.
|
||||
"""
|
||||
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.lookup_list = SCons.Node.arg2nodes_lookups
|
||||
self._dict = kw.copy()
|
||||
self._init_special()
|
||||
self.added_methods = []
|
||||
#self._memo = {}
|
||||
|
||||
def _init_special(self):
|
||||
|
@ -327,7 +364,7 @@ class SubstitutionEnvironment:
|
|||
def items(self):
|
||||
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:
|
||||
node_factory = self.fs.File
|
||||
if lookup_list is _null:
|
||||
|
@ -351,7 +388,9 @@ class SubstitutionEnvironment:
|
|||
break
|
||||
if not n is None:
|
||||
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:
|
||||
n = node_factory(n)
|
||||
if SCons.Util.is_List(n):
|
||||
|
@ -359,7 +398,9 @@ class SubstitutionEnvironment:
|
|||
else:
|
||||
nodes.append(n)
|
||||
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):
|
||||
nodes.extend(v)
|
||||
else:
|
||||
|
@ -473,6 +514,23 @@ class SubstitutionEnvironment:
|
|||
raise OSError("'%s' exited %d" % (command, status))
|
||||
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):
|
||||
"""
|
||||
Produce a modified environment whose variables are overriden by
|
||||
|
@ -564,7 +622,7 @@ class SubstitutionEnvironment:
|
|||
# -R dir (deprecated linker rpath)
|
||||
# IBM compilers may also accept -qframeworkdir=foo
|
||||
|
||||
params = string.split(arg)
|
||||
params = shlex.split(arg)
|
||||
append_next_arg_to = None # for multi-word args
|
||||
for arg in params:
|
||||
if append_next_arg_to:
|
||||
|
@ -705,6 +763,29 @@ class SubstitutionEnvironment:
|
|||
self[key] = t
|
||||
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):
|
||||
"""Base class for "real" construction Environments. These are the
|
||||
primary objects used to communicate dependency and construction
|
||||
|
@ -752,11 +833,23 @@ class Base(SubstitutionEnvironment):
|
|||
"""
|
||||
if __debug__: logInstanceCreation(self, 'Environment.Base')
|
||||
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.lookup_list = SCons.Node.arg2nodes_lookups
|
||||
self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment)
|
||||
self._dict = semi_deepcopy(SCons.Defaults.ConstructionEnvironment)
|
||||
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)
|
||||
|
||||
|
@ -787,6 +880,8 @@ class Base(SubstitutionEnvironment):
|
|||
# reserved variable name like TARGETS.
|
||||
pass
|
||||
|
||||
SCons.Tool.Initializers(self)
|
||||
|
||||
if tools is None:
|
||||
tools = self._dict.get('TOOLS', None)
|
||||
if tools is None:
|
||||
|
@ -812,16 +907,13 @@ class Base(SubstitutionEnvironment):
|
|||
except KeyError:
|
||||
return None
|
||||
|
||||
def get_calculator(self):
|
||||
def get_CacheDir(self):
|
||||
try:
|
||||
module = self._calc_module
|
||||
c = apply(SCons.Sig.Calculator, (module,), CalculatorArgs)
|
||||
return self._CacheDir
|
||||
except AttributeError:
|
||||
# Note that we're calling get_calculator() here, so the
|
||||
# DefaultEnvironment() must have a _calc_module attribute
|
||||
# to avoid infinite recursion.
|
||||
c = SCons.Defaults.DefaultEnvironment().get_calculator()
|
||||
return c
|
||||
cd = SCons.Defaults.DefaultEnvironment()._CacheDir
|
||||
self._CacheDir = cd
|
||||
return cd
|
||||
|
||||
def get_factory(self, factory, default='File'):
|
||||
"""Return a factory function for creating Nodes for this
|
||||
|
@ -903,13 +995,21 @@ class Base(SubstitutionEnvironment):
|
|||
"""
|
||||
self._dict.update(dict)
|
||||
|
||||
def use_build_signature(self):
|
||||
def get_src_sig_type(self):
|
||||
try:
|
||||
return self._build_signature
|
||||
return self.src_sig_type
|
||||
except AttributeError:
|
||||
b = SCons.Defaults.DefaultEnvironment()._build_signature
|
||||
self._build_signature = b
|
||||
return b
|
||||
t = SCons.Defaults.DefaultEnvironment().src_sig_type
|
||||
self.src_sig_type = t
|
||||
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
|
||||
|
@ -978,7 +1078,11 @@ class Base(SubstitutionEnvironment):
|
|||
try:
|
||||
update_dict(val)
|
||||
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)
|
||||
|
||||
def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
|
||||
|
@ -1037,29 +1141,95 @@ class Base(SubstitutionEnvironment):
|
|||
objects in the original Environment.
|
||||
"""
|
||||
clone = copy.copy(self)
|
||||
clone._dict = our_deepcopy(self._dict)
|
||||
clone._dict = semi_deepcopy(self._dict)
|
||||
|
||||
try:
|
||||
cbd = clone._dict['BUILDERS']
|
||||
clone._dict['BUILDERS'] = BuilderDict(cbd, clone)
|
||||
except KeyError:
|
||||
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 = {}
|
||||
|
||||
apply_tools(clone, tools, toolpath)
|
||||
|
||||
# Apply passed-in variables after the new tools.
|
||||
# Apply passed-in variables before the tools
|
||||
# so the tools can use the new variables
|
||||
kw = copy_non_reserved_keywords(kw)
|
||||
new = {}
|
||||
for key, value in kw.items():
|
||||
new[key] = SCons.Subst.scons_subst_once(value, self, key)
|
||||
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')
|
||||
return clone
|
||||
|
||||
def Copy(self, *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):
|
||||
"""Return the first available program in progs.
|
||||
"""
|
||||
|
@ -1233,7 +1403,11 @@ class Base(SubstitutionEnvironment):
|
|||
try:
|
||||
update_dict(val)
|
||||
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)
|
||||
|
||||
def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
|
||||
|
@ -1288,13 +1462,15 @@ class Base(SubstitutionEnvironment):
|
|||
with new construction variables and/or values.
|
||||
"""
|
||||
try:
|
||||
kwbd = our_deepcopy(kw['BUILDERS'])
|
||||
del kw['BUILDERS']
|
||||
self.__setitem__('BUILDERS', kwbd)
|
||||
kwbd = kw['BUILDERS']
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
kwbd = semi_deepcopy(kwbd)
|
||||
del kw['BUILDERS']
|
||||
self.__setitem__('BUILDERS', kwbd)
|
||||
kw = copy_non_reserved_keywords(kw)
|
||||
self._update(our_deepcopy(kw))
|
||||
self._update(semi_deepcopy(kw))
|
||||
self.scanner_map_delete(kw)
|
||||
|
||||
def ReplaceIxes(self, path, old_prefix, old_suffix, new_prefix, new_suffix):
|
||||
|
@ -1453,7 +1629,7 @@ class Base(SubstitutionEnvironment):
|
|||
def AlwaysBuild(self, *targets):
|
||||
tlist = []
|
||||
for t in targets:
|
||||
tlist.extend(self.arg2nodes(t, self.fs.File))
|
||||
tlist.extend(self.arg2nodes(t, self.fs.Entry))
|
||||
for t in tlist:
|
||||
t.set_always_build()
|
||||
return tlist
|
||||
|
@ -1468,7 +1644,11 @@ class Base(SubstitutionEnvironment):
|
|||
return apply(SCons.Builder.Builder, [], nkw)
|
||||
|
||||
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):
|
||||
global CleanTargets
|
||||
|
@ -1551,7 +1731,11 @@ class Base(SubstitutionEnvironment):
|
|||
"""Directly execute an action through an Environment
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
|
@ -1573,6 +1757,9 @@ class Base(SubstitutionEnvironment):
|
|||
else:
|
||||
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):
|
||||
"""Ignore a dependency."""
|
||||
tlist = self.arg2nodes(target, self.fs.Entry)
|
||||
|
@ -1581,50 +1768,6 @@ class Base(SubstitutionEnvironment):
|
|||
t.add_ignore(dlist)
|
||||
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):
|
||||
return SCons.Subst.Literal(string)
|
||||
|
||||
|
@ -1652,6 +1795,16 @@ class Base(SubstitutionEnvironment):
|
|||
dirs = self.arg2nodes(list(dirs), self.fs.Dir)
|
||||
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):
|
||||
nargs = []
|
||||
for arg in args:
|
||||
|
@ -1693,21 +1846,15 @@ class Base(SubstitutionEnvironment):
|
|||
|
||||
def SourceSignatures(self, type):
|
||||
type = self.subst(type)
|
||||
self.src_sig_type = type
|
||||
if type == 'MD5':
|
||||
try:
|
||||
import SCons.Sig.MD5
|
||||
except ImportError:
|
||||
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
|
||||
if not SCons.Util.md5:
|
||||
raise UserError, "MD5 signatures are not available in this version of Python."
|
||||
self.decide_source = self._changed_content
|
||||
elif type == 'timestamp':
|
||||
import SCons.Sig.TimeStamp
|
||||
self._calc_module = SCons.Sig.TimeStamp
|
||||
self.decide_source = self._changed_timestamp_match
|
||||
else:
|
||||
raise UserError, "Unknown source signature type '%s'"%type
|
||||
raise UserError, "Unknown source signature type '%s'" % type
|
||||
|
||||
def Split(self, arg):
|
||||
"""This function converts a string or list into a list of strings
|
||||
|
@ -1729,18 +1876,66 @@ class Base(SubstitutionEnvironment):
|
|||
|
||||
def TargetSignatures(self, type):
|
||||
type = self.subst(type)
|
||||
if type == 'build':
|
||||
self._build_signature = 1
|
||||
elif type == 'content':
|
||||
self._build_signature = 0
|
||||
self.tgt_sig_type = type
|
||||
if type in ('MD5', 'content'):
|
||||
if not SCons.Util.md5:
|
||||
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:
|
||||
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):
|
||||
"""
|
||||
"""
|
||||
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):
|
||||
"""A proxy that overrides variables in a wrapped construction
|
||||
environment by returning values from an overrides dictionary in
|
||||
|
@ -1839,7 +2034,7 @@ class OverrideEnvironment(Base):
|
|||
# Overridden public construction environment methods.
|
||||
def Replace(self, **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
|
||||
# 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):
|
||||
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.errstr = errstr
|
||||
self.status = status
|
||||
self.filename = filename
|
||||
self.executor = executor
|
||||
self.action = action
|
||||
self.command = command
|
||||
apply(Exception.__init__, (self,) + args)
|
||||
|
||||
class InternalError(Exception):
|
||||
|
@ -48,6 +54,9 @@ class UserError(Exception):
|
|||
class StopError(Exception):
|
||||
pass
|
||||
|
||||
class EnvironmentError(Exception):
|
||||
pass
|
||||
|
||||
class ExplicitExit(Exception):
|
||||
def __init__(self, node=None, status=None, *args):
|
||||
self.node = node
|
|
@ -28,11 +28,12 @@ Nodes.
|
|||
# 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
|
||||
|
||||
from SCons.Debug import logInstanceCreation
|
||||
import SCons.Errors
|
||||
import SCons.Memoize
|
||||
|
||||
|
||||
|
@ -59,6 +60,7 @@ class Executor:
|
|||
self.overridelist = overridelist
|
||||
self.targets = targets
|
||||
self.sources = sources[:]
|
||||
self.sources_need_sorting = False
|
||||
self.builder_kw = builder_kw
|
||||
self._memo = {}
|
||||
|
||||
|
@ -74,10 +76,17 @@ class Executor:
|
|||
def get_action_list(self):
|
||||
return self.pre_actions + self.action_list + self.post_actions
|
||||
|
||||
memoizer_counters.append(SCons.Memoize.CountValue('get_build_env'))
|
||||
|
||||
def get_build_env(self):
|
||||
"""Fetch or create the appropriate build Environment
|
||||
for this Executor.
|
||||
"""
|
||||
try:
|
||||
return self._memo['get_build_env']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# Create the build environment instance with appropriate
|
||||
# overrides. These get evaluated against the current
|
||||
# environment's construction variables so that users can
|
||||
|
@ -91,42 +100,49 @@ class Executor:
|
|||
env = self.env or SCons.Defaults.DefaultEnvironment()
|
||||
build_env = env.Override(overrides)
|
||||
|
||||
self._memo['get_build_env'] = build_env
|
||||
|
||||
return build_env
|
||||
|
||||
def get_build_scanner_path(self, scanner):
|
||||
"""Fetch the scanner path for this executor's targets
|
||||
and sources.
|
||||
"""Fetch the scanner path for this executor's targets and sources.
|
||||
"""
|
||||
env = self.get_build_env()
|
||||
try:
|
||||
cwd = self.targets[0].cwd
|
||||
except (IndexError, AttributeError):
|
||||
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={}):
|
||||
result = self.builder_kw.copy()
|
||||
result.update(kw)
|
||||
return result
|
||||
|
||||
def do_nothing(self, target, exitstatfunc, kw):
|
||||
pass
|
||||
def do_nothing(self, target, kw):
|
||||
return 0
|
||||
|
||||
def do_execute(self, target, exitstatfunc, kw):
|
||||
def do_execute(self, target, kw):
|
||||
"""Actually execute the action list."""
|
||||
env = self.get_build_env()
|
||||
kw = self.get_kw(kw)
|
||||
status = 0
|
||||
for act in self.get_action_list():
|
||||
apply(act,
|
||||
(self.targets, self.sources, env, exitstatfunc),
|
||||
kw)
|
||||
status = apply(act, (self.targets, self.get_sources(), env), kw)
|
||||
if isinstance(status, SCons.Errors.BuildError):
|
||||
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
|
||||
# and above) we can't override special methods, and nullify() needs
|
||||
# to be able to do this.
|
||||
|
||||
def __call__(self, target, exitstatfunc, **kw):
|
||||
self.do_execute(target, exitstatfunc, kw)
|
||||
def __call__(self, target, **kw):
|
||||
return self.do_execute(target, kw)
|
||||
|
||||
def cleanup(self):
|
||||
self._memo = {}
|
||||
|
@ -135,8 +151,14 @@ class Executor:
|
|||
"""Add source files to this Executor's list. This is necessary
|
||||
for "multi" Builders that can be called repeatedly to build up
|
||||
a source file list for a given target."""
|
||||
slist = filter(lambda x, s=self.sources: x not in s, sources)
|
||||
self.sources.extend(slist)
|
||||
self.sources.extend(sources)
|
||||
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):
|
||||
self.pre_actions.append(action)
|
||||
|
@ -148,7 +170,7 @@ class Executor:
|
|||
|
||||
def my_str(self):
|
||||
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)
|
||||
return string.join(map(get, self.get_action_list()), "\n")
|
||||
|
||||
|
@ -173,7 +195,7 @@ class Executor:
|
|||
except KeyError:
|
||||
pass
|
||||
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)
|
||||
result = string.join(map(get, self.get_action_list()), "")
|
||||
self._memo['get_contents'] = result
|
||||
|
@ -191,7 +213,7 @@ class Executor:
|
|||
|
||||
def scan_sources(self, scanner):
|
||||
if self.sources:
|
||||
self.scan(scanner, self.sources)
|
||||
self.scan(scanner, self.get_sources())
|
||||
|
||||
def scan(self, scanner, node_list):
|
||||
"""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 = filter(remove_null_scanners, scanner_list)
|
||||
scanner_path_list = map(add_scanner_path, scanner_list)
|
||||
|
||||
deps = []
|
||||
for node, scanner, path in scanner_path_list:
|
||||
deps.extend(node.get_implicit_deps(env, scanner, path))
|
||||
|
||||
deps.extend(self.get_implicit_deps())
|
||||
|
||||
for tgt in self.targets:
|
||||
tgt.add_to_implicit(deps)
|
||||
|
||||
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=()):
|
||||
return tuple(ignore)
|
||||
|
@ -248,9 +273,12 @@ class Executor:
|
|||
except KeyError:
|
||||
pass
|
||||
|
||||
sourcelist = self.sources
|
||||
sourcelist = self.get_sources()
|
||||
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
|
||||
|
||||
|
@ -280,6 +308,15 @@ class Executor:
|
|||
|
||||
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
|
||||
|
||||
|
@ -296,9 +333,15 @@ class Null(_Executor):
|
|||
kw['action'] = []
|
||||
apply(_Executor.__init__, (self,), kw)
|
||||
def get_build_env(self):
|
||||
class NullEnvironment:
|
||||
def get_scanner(self, key):
|
||||
return None
|
||||
import SCons.Util
|
||||
class NullEnvironment(SCons.Util.Null):
|
||||
#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()
|
||||
def get_build_scanner_path(self):
|
||||
return None
|
|
@ -29,7 +29,7 @@ stop, and wait on jobs.
|
|||
# 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
|
||||
|
||||
|
@ -76,6 +76,9 @@ class Jobs:
|
|||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
raise
|
||||
|
||||
def cleanup(self):
|
||||
self.job.cleanup()
|
||||
|
||||
class Serial:
|
||||
"""This class is used to execute tasks in series, and is more efficient
|
||||
than Parallel, but is only appropriate for non-parallel builds. Only
|
||||
|
@ -122,6 +125,8 @@ class Serial:
|
|||
|
||||
task.postprocess()
|
||||
|
||||
def cleanup(self):
|
||||
pass
|
||||
|
||||
# Trap import failure so that everything in the Job module but the
|
||||
# Parallel class (and its dependent classes) will work if the interpreter
|
||||
|
@ -148,6 +153,12 @@ else:
|
|||
while 1:
|
||||
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:
|
||||
task.execute()
|
||||
except KeyboardInterrupt:
|
||||
|
@ -170,8 +181,10 @@ else:
|
|||
self.resultsQueue = Queue.Queue(0)
|
||||
|
||||
# Create worker threads
|
||||
self.workers = []
|
||||
for _ in range(num):
|
||||
Worker(self.requestQueue, self.resultsQueue)
|
||||
worker = Worker(self.requestQueue, self.resultsQueue)
|
||||
self.workers.append(worker)
|
||||
|
||||
def put(self, obj):
|
||||
"""Put task into request queue."""
|
||||
|
@ -182,7 +195,36 @@ else:
|
|||
return self.resultsQueue.get(block)
|
||||
|
||||
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:
|
||||
"""This class is used to execute tasks in parallel, and is somewhat
|
||||
|
@ -261,3 +303,6 @@ else:
|
|||
|
||||
if self.tp.resultsQueue.empty():
|
||||
break
|
||||
|
||||
def cleanup(self):
|
||||
self.tp.cleanup()
|
|
@ -21,7 +21,7 @@
|
|||
# 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
|
||||
|
|
@ -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.
|
||||
#
|
||||
|
||||
__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 UserDict
|
||||
|
@ -57,10 +57,13 @@ class AliasNameSpace(UserDict.UserDict):
|
|||
return None
|
||||
|
||||
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):
|
||||
pass
|
||||
current_version_id = 1
|
||||
|
||||
class Alias(SCons.Node.Node):
|
||||
|
||||
|
@ -74,8 +77,11 @@ class Alias(SCons.Node.Node):
|
|||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def make_ready(self):
|
||||
self.get_csig()
|
||||
|
||||
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):
|
||||
# Make Alias nodes get built regardless of
|
||||
|
@ -85,9 +91,9 @@ class Alias(SCons.Node.Node):
|
|||
|
||||
def get_contents(self):
|
||||
"""The contents of an alias is the concatenation
|
||||
of all the contents of its sources"""
|
||||
contents = map(lambda n: n.get_contents(), self.children())
|
||||
return string.join(contents, '')
|
||||
of the content signatures of all its sources."""
|
||||
childsigs = map(lambda n: n.get_csig(), self.children())
|
||||
return string.join(childsigs, '')
|
||||
|
||||
def sconsign(self):
|
||||
"""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):
|
||||
"""A "builder" for aliases."""
|
||||
pass
|
||||
|
@ -107,6 +120,25 @@ class Alias(SCons.Node.Node):
|
|||
self.reset_executor()
|
||||
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()
|
||||
|
||||
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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
||||
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):
|
||||
pass
|
||||
current_version_id = 1
|
||||
|
||||
class Value(SCons.Node.Node):
|
||||
"""A class for Python variables, typically passed on the command line
|
||||
|
@ -54,11 +59,14 @@ class Value(SCons.Node.Node):
|
|||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
||||
def make_ready(self):
|
||||
self.get_csig()
|
||||
|
||||
def build(self, **kw):
|
||||
if not hasattr(self, 'built_value'):
|
||||
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):
|
||||
# Make Value nodes get built regardless of
|
||||
|
@ -88,17 +96,21 @@ class Value(SCons.Node.Node):
|
|||
contents = contents + kid.get_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):
|
||||
"""Because we're a Python value node and don't have a real
|
||||
timestamp, we get to ignore the calculator and just use the
|
||||
value contents."""
|
||||
try:
|
||||
binfo = self.binfo
|
||||
return self.ninfo.csig
|
||||
except AttributeError:
|
||||
binfo = self.binfo = self.new_binfo()
|
||||
try:
|
||||
return binfo.ninfo.csig
|
||||
except AttributeError:
|
||||
binfo.ninfo.csig = self.get_contents()
|
||||
self.store_info(binfo)
|
||||
return binfo.ninfo.csig
|
||||
pass
|
||||
contents = self.get_contents()
|
||||
self.get_ninfo().csig = contents
|
||||
return contents
|
|
@ -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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
||||
|
@ -53,9 +53,13 @@ import UserList
|
|||
from SCons.Debug import logInstanceCreation
|
||||
import SCons.Executor
|
||||
import SCons.Memoize
|
||||
import SCons.SConsign
|
||||
import SCons.Util
|
||||
|
||||
from SCons.Debug import Trace
|
||||
|
||||
def classname(obj):
|
||||
return string.split(str(obj.__class__), '.')[-1]
|
||||
|
||||
# Node states
|
||||
#
|
||||
# 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
|
||||
logic for dealing with their own Node-specific signature information.
|
||||
"""
|
||||
current_version_id = 1
|
||||
def __init__(self, node):
|
||||
"""A null initializer so that subclasses have a superclass
|
||||
initialization method to call for future use.
|
||||
"""
|
||||
pass
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.__dict__, other.__dict__)
|
||||
# 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
|
||||
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:
|
||||
field_list = self.field_list
|
||||
except AttributeError:
|
||||
field_list = self.__dict__.keys()
|
||||
field_list.sort()
|
||||
return
|
||||
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 = []
|
||||
for field in field_list:
|
||||
try:
|
||||
f = getattr(self, field)
|
||||
except AttributeError:
|
||||
f = None
|
||||
fields.append(str(f))
|
||||
return string.join(fields, " ")
|
||||
f = str(f)
|
||||
if names:
|
||||
f = field + ': ' + f
|
||||
fields.append(f)
|
||||
return fields
|
||||
|
||||
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.
|
||||
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,
|
||||
implicit dependencies, and action information.
|
||||
"""
|
||||
current_version_id = 1
|
||||
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.bdependsigs = []
|
||||
self.bimplicitsigs = []
|
||||
self.bactsig = None
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.ninfo, other.ninfo)
|
||||
def merge(self, other):
|
||||
for key, val in other.__dict__.items():
|
||||
try:
|
||||
merge = self.__dict__[key].merge
|
||||
except (AttributeError, KeyError):
|
||||
self.__dict__[key] = val
|
||||
else:
|
||||
merge(val)
|
||||
self.__dict__.update(other.__dict__)
|
||||
|
||||
class Node:
|
||||
"""The base Node class, for entities that we know how to
|
||||
|
@ -193,6 +207,7 @@ class Node:
|
|||
self.depends_dict = {}
|
||||
self.ignore = [] # dependencies to ignore
|
||||
self.ignore_dict = {}
|
||||
self.prerequisites = SCons.Util.UniqueList()
|
||||
self.implicit = None # implicit (scanned) dependencies (None means not scanned yet)
|
||||
self.waiting_parents = {}
|
||||
self.waiting_s_e = {}
|
||||
|
@ -225,10 +240,18 @@ class Node:
|
|||
def get_suffix(self):
|
||||
return ''
|
||||
|
||||
memoizer_counters.append(SCons.Memoize.CountValue('get_build_env'))
|
||||
|
||||
def get_build_env(self):
|
||||
"""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):
|
||||
"""Fetch the appropriate scanner path for this node."""
|
||||
|
@ -286,19 +309,64 @@ class Node:
|
|||
"""
|
||||
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):
|
||||
"""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,
|
||||
so only do thread safe stuff here. Do thread unsafe stuff in
|
||||
built().
|
||||
so only do thread safe stuff here. Do thread unsafe stuff
|
||||
in built().
|
||||
|
||||
"""
|
||||
def exitstatfunc(stat, node=self):
|
||||
if stat:
|
||||
msg = "Error %d" % stat
|
||||
raise SCons.Errors.BuildError(node=node, errstr=msg)
|
||||
executor = self.get_executor()
|
||||
apply(executor, (self, exitstatfunc), kw)
|
||||
try:
|
||||
apply(self.get_executor(), (self,), kw)
|
||||
except SCons.Errors.BuildError, e:
|
||||
e.node = self
|
||||
raise
|
||||
|
||||
def built(self):
|
||||
"""Called just after this node is successfully built."""
|
||||
|
@ -309,28 +377,26 @@ class Node:
|
|||
parent.implicit = None
|
||||
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()
|
||||
|
||||
if new:
|
||||
# It had build info, so it should be stored in the signature
|
||||
# cache. However, if the build info included a content
|
||||
# signature then it must be recalculated before being stored.
|
||||
if hasattr(new.ninfo, 'csig'):
|
||||
self.get_csig()
|
||||
else:
|
||||
new.ninfo.update(self)
|
||||
self.binfo = new
|
||||
self.store_info(self.binfo)
|
||||
self.ninfo.update(self)
|
||||
|
||||
def visited(self):
|
||||
"""Called just after this node has been visited (with or
|
||||
without a build)."""
|
||||
try:
|
||||
binfo = self.binfo
|
||||
except AttributeError:
|
||||
# Apparently this node doesn't need build info, so
|
||||
# don't bother calculating or storing it.
|
||||
pass
|
||||
else:
|
||||
self.ninfo.update(self)
|
||||
self.store_info()
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
def add_to_waiting_s_e(self, node):
|
||||
self.waiting_s_e[node] = 1
|
||||
|
@ -367,27 +433,33 @@ class Node:
|
|||
can be re-evaluated by interfaces that do continuous integration
|
||||
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.ninfo = self.new_ninfo()
|
||||
self.executor_cleanup()
|
||||
self.del_binfo()
|
||||
try:
|
||||
delattr(self, '_calculated_sig')
|
||||
except AttributeError:
|
||||
pass
|
||||
self.includes = None
|
||||
self.found_includes = {}
|
||||
self.implicit = None
|
||||
|
||||
def clear_memoized_values(self):
|
||||
self._memo = {}
|
||||
|
||||
def visited(self):
|
||||
"""Called just after this node has been visited
|
||||
without requiring a build.."""
|
||||
pass
|
||||
|
||||
def builder_set(self, builder):
|
||||
self.builder = builder
|
||||
try:
|
||||
del self.executor
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def has_builder(self):
|
||||
"""Return whether this Node has a builder or not.
|
||||
|
@ -405,8 +477,7 @@ class Node:
|
|||
except AttributeError:
|
||||
# There was no explicit builder for this Node, so initialize
|
||||
# the self.builder attribute to None now.
|
||||
self.builder = None
|
||||
b = self.builder
|
||||
b = self.builder = None
|
||||
return not b is None
|
||||
|
||||
def set_explicit(self, is_explicit):
|
||||
|
@ -446,14 +517,6 @@ class Node:
|
|||
"""
|
||||
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):
|
||||
"""Return a list of alternate targets for this Node.
|
||||
"""
|
||||
|
@ -552,40 +615,33 @@ class Node:
|
|||
return
|
||||
|
||||
build_env = self.get_build_env()
|
||||
executor = self.get_executor()
|
||||
|
||||
# Here's where we implement --implicit-cache.
|
||||
if implicit_cache and not implicit_deps_changed:
|
||||
implicit = self.get_stored_implicit()
|
||||
if implicit is not None:
|
||||
factory = build_env.get_factory(self.builder.source_factory)
|
||||
nodes = []
|
||||
for i in implicit:
|
||||
try:
|
||||
n = factory(i)
|
||||
except TypeError:
|
||||
# The implicit dependency was cached as one type
|
||||
# of Node last time, but the configuration has
|
||||
# changed (probably) and it's a different type
|
||||
# this time. Just ignore the mismatch and go
|
||||
# with what our current configuration says the
|
||||
# Node is.
|
||||
pass
|
||||
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):
|
||||
# We now add the implicit dependencies returned from the
|
||||
# stored .sconsign entry to have already been converted
|
||||
# to Nodes for us. (We used to run them through a
|
||||
# source_factory function here.)
|
||||
|
||||
# Update all of the targets with them. This
|
||||
# essentially short-circuits an N*M scan of the
|
||||
# sources for each individual target, which is a hell
|
||||
# of a lot more efficient.
|
||||
for tgt in executor.targets:
|
||||
tgt.add_to_implicit(implicit)
|
||||
|
||||
if implicit_deps_unchanged or self.is_up_to_date():
|
||||
return
|
||||
# one of this node's sources has changed, so
|
||||
# we need to recalculate the implicit deps,
|
||||
# and the bsig:
|
||||
# one of this node's sources has changed,
|
||||
# so we must recalculate the implicit deps:
|
||||
self.implicit = []
|
||||
self.implicit_dict = {}
|
||||
self._children_reset()
|
||||
self.del_binfo()
|
||||
|
||||
executor = self.get_executor()
|
||||
|
||||
# Have the executor scan the sources.
|
||||
executor.scan_sources(self.builder.source_scanner)
|
||||
|
||||
|
@ -620,65 +676,24 @@ class Node:
|
|||
NodeInfo = NodeInfoBase
|
||||
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):
|
||||
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):
|
||||
return self.BuildInfo(self)
|
||||
binfo = self.BuildInfo(self)
|
||||
return binfo
|
||||
|
||||
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
|
||||
of its dependency files and build information.
|
||||
Fetch a node's build information.
|
||||
|
||||
node - the node whose sources will be collected
|
||||
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
|
||||
what's wanted.
|
||||
"""
|
||||
try:
|
||||
return self.binfo
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if calc is None:
|
||||
calc = self.calculator()
|
||||
|
||||
binfo = self.get_binfo()
|
||||
|
||||
if scan:
|
||||
self.scan()
|
||||
binfo = self.new_binfo()
|
||||
self.binfo = binfo
|
||||
|
||||
executor = self.get_executor()
|
||||
def calc_signature(node, calc=calc):
|
||||
return node.calc_signature(calc)
|
||||
|
||||
sources = executor.get_unignored_sources(self.ignore)
|
||||
sourcesigs = executor.process_sources(calc_signature, self.ignore)
|
||||
|
||||
depends = self.depends
|
||||
implicit = self.implicit or []
|
||||
|
@ -712,15 +723,16 @@ class Node:
|
|||
depends = filter(self.do_not_ignore, depends)
|
||||
implicit = filter(self.do_not_ignore, implicit)
|
||||
|
||||
dependsigs = map(calc_signature, depends)
|
||||
implicitsigs = map(calc_signature, implicit)
|
||||
def get_ninfo(node):
|
||||
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():
|
||||
binfo.bact = str(executor)
|
||||
binfo.bactsig = calc.module.signature(executor)
|
||||
sigs.append(binfo.bactsig)
|
||||
binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())
|
||||
|
||||
binfo.bsources = sources
|
||||
binfo.bdepends = depends
|
||||
|
@ -730,33 +742,34 @@ class Node:
|
|||
binfo.bdependsigs = dependsigs
|
||||
binfo.bimplicitsigs = implicitsigs
|
||||
|
||||
binfo.ninfo.bsig = calc.module.collect(filter(None, sigs))
|
||||
|
||||
return binfo
|
||||
|
||||
def get_bsig(self, calc=None):
|
||||
binfo = self.get_binfo()
|
||||
def del_binfo(self):
|
||||
"""Delete the build info from this node."""
|
||||
try:
|
||||
return binfo.ninfo.bsig
|
||||
delattr(self, 'binfo')
|
||||
except AttributeError:
|
||||
self.binfo = self.gen_binfo(calc)
|
||||
return self.binfo.ninfo.bsig
|
||||
pass
|
||||
|
||||
def get_csig(self, calc=None):
|
||||
binfo = self.get_binfo()
|
||||
def get_csig(self):
|
||||
try:
|
||||
return binfo.ninfo.csig
|
||||
return self.ninfo.csig
|
||||
except AttributeError:
|
||||
if calc is None:
|
||||
calc = self.calculator()
|
||||
csig = binfo.ninfo.csig = calc.module.signature(self)
|
||||
return csig
|
||||
ninfo = self.get_ninfo()
|
||||
ninfo.csig = SCons.Util.MD5signature(self.get_contents())
|
||||
return self.ninfo.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
|
||||
.sconsign file or equivalent)."""
|
||||
pass
|
||||
|
||||
def do_not_store_info(self):
|
||||
pass
|
||||
|
||||
def get_stored_info(self):
|
||||
return None
|
||||
|
||||
|
@ -800,24 +813,9 @@ class Node:
|
|||
|
||||
def missing(self):
|
||||
return not self.is_derived() and \
|
||||
not self.is_pseudo_derived() and \
|
||||
not self.linked and \
|
||||
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):
|
||||
"""Remove this Node: no-op by default."""
|
||||
return None
|
||||
|
@ -834,6 +832,11 @@ class Node:
|
|||
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)))
|
||||
|
||||
def add_prerequisite(self, prerequisite):
|
||||
"""Adds prerequisites"""
|
||||
self.prerequisites.extend(prerequisite)
|
||||
self._children_reset()
|
||||
|
||||
def add_ignore(self, depend):
|
||||
"""Adds dependencies to ignore."""
|
||||
try:
|
||||
|
@ -861,11 +864,11 @@ class Node:
|
|||
def _add_child(self, collection, dict, child):
|
||||
"""Adds 'child' to 'collection', first checking 'dict' to see
|
||||
if it's already present."""
|
||||
if type(child) is not type([]):
|
||||
child = [child]
|
||||
for c in child:
|
||||
if not isinstance(c, Node):
|
||||
raise TypeError, c
|
||||
#if type(child) is not type([]):
|
||||
# child = [child]
|
||||
#for c in child:
|
||||
# if not isinstance(c, Node):
|
||||
# raise TypeError, c
|
||||
added = None
|
||||
for c in child:
|
||||
if not dict.has_key(c):
|
||||
|
@ -883,7 +886,7 @@ class Node:
|
|||
def _children_reset(self):
|
||||
self.clear_memoized_values()
|
||||
# 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()
|
||||
|
||||
def do_not_ignore(self, node):
|
||||
|
@ -944,19 +947,107 @@ class Node:
|
|||
def get_state(self):
|
||||
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
|
||||
subtypes are always out of date, so they will always get built."""
|
||||
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
|
||||
our children were up-to-date, then this Node was up-to-date, too.
|
||||
|
||||
The SCons.Node.Alias and SCons.Node.Python.Value subclasses
|
||||
rebind their current() method to this method."""
|
||||
# Allow the children to calculate their signatures.
|
||||
self.binfo = self.gen_binfo(calc)
|
||||
self.binfo = self.get_binfo()
|
||||
if self.always_build:
|
||||
return None
|
||||
state = 0
|
||||
|
@ -1046,32 +1137,29 @@ class Node:
|
|||
if not self.exists():
|
||||
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()
|
||||
if old is None:
|
||||
return None
|
||||
|
||||
old = old.binfo
|
||||
old.prepare_dependencies()
|
||||
|
||||
def dictify(result, kids, sigs):
|
||||
for k, s in zip(kids, sigs):
|
||||
result[k] = s
|
||||
|
||||
try:
|
||||
osig = {}
|
||||
dictify(osig, old.bsources, old.bsourcesigs)
|
||||
dictify(osig, old.bdepends, old.bdependsigs)
|
||||
dictify(osig, old.bimplicit, old.bimplicitsigs)
|
||||
old_bkids = old.bsources + old.bdepends + old.bimplicit
|
||||
old_bkidsigs = old.bsourcesigs + old.bdependsigs + old.bimplicitsigs
|
||||
except AttributeError:
|
||||
return "Cannot explain why `%s' is being rebuilt: No previous build information found\n" % self
|
||||
|
||||
new = self.get_binfo()
|
||||
|
||||
nsig = {}
|
||||
dictify(nsig, new.bsources, new.bsourcesigs)
|
||||
dictify(nsig, new.bdepends, new.bdependsigs)
|
||||
dictify(nsig, new.bimplicit, new.bimplicitsigs)
|
||||
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
||||
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
|
||||
|
||||
old_bkids = old.bsources + old.bdepends + old.bimplicit
|
||||
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
||||
osig = dict(zip(old_bkids, old_bkidsigs))
|
||||
nsig = dict(zip(new_bkids, new_bkidsigs))
|
||||
|
||||
# The sources and dependencies we'll want to report are all stored
|
||||
# as relative paths to this target's directory, but we want to
|
||||
|
@ -1092,7 +1180,7 @@ class Node:
|
|||
for k in new_bkids:
|
||||
if not k in old_bkids:
|
||||
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))
|
||||
|
||||
if len(lines) == 0 and old_bkids != new_bkids:
|
||||
|
@ -1124,19 +1212,18 @@ class Node:
|
|||
lines = ["%s:\n" % preamble] + lines
|
||||
return string.join(lines, ' '*11)
|
||||
|
||||
l = [1]
|
||||
ul = UserList.UserList([2])
|
||||
try:
|
||||
l.extend(ul)
|
||||
[].extend(UserList.UserList([]))
|
||||
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):
|
||||
return l
|
||||
else:
|
||||
class NodeList(UserList.UserList):
|
||||
def __str__(self):
|
||||
return str(map(str, self.data))
|
||||
del l
|
||||
del ul
|
||||
|
||||
def get_children(node, parent): return node.children()
|
||||
def ignore_cycle(node, stack): pass
|
|
@ -34,7 +34,7 @@ Usage example:
|
|||
# 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')
|
||||
|
|
@ -37,7 +37,7 @@ Usage example:
|
|||
# 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',)
|
||||
|
|
@ -47,7 +47,7 @@ Usage example:
|
|||
# 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,
|
||||
# since elements can occur twice.
|
|
@ -50,7 +50,7 @@ Usage example:
|
|||
# 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')
|
||||
|
|
@ -68,7 +68,7 @@ Usage example:
|
|||
# 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.path
|
||||
|
@ -128,7 +128,12 @@ class _PathOptionClass:
|
|||
"""
|
||||
if validator is None:
|
||||
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()
|
|
@ -27,10 +27,13 @@ customizable variables to an SCons build.
|
|||
# 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 string
|
||||
import sys
|
||||
|
||||
import SCons.Errors
|
||||
import SCons.Util
|
||||
|
@ -44,31 +47,49 @@ from PathOption import PathOption # okay
|
|||
|
||||
|
||||
class Options:
|
||||
instance=None
|
||||
|
||||
"""
|
||||
Holds all the options, updates the environment with the variables,
|
||||
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
|
||||
(backward compatibility) If a single string is passed it is
|
||||
automatically placed in a file list
|
||||
"""
|
||||
|
||||
self.options = []
|
||||
self.args = args
|
||||
self.files = None
|
||||
if SCons.Util.is_String(files):
|
||||
self.files = [ files ]
|
||||
elif files:
|
||||
self.files = files
|
||||
if not SCons.Util.is_List(files):
|
||||
if files:
|
||||
files = [ files ]
|
||||
else:
|
||||
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):
|
||||
class Option:
|
||||
pass
|
||||
|
||||
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.default = default
|
||||
option.validator = validator
|
||||
|
@ -139,19 +160,34 @@ class Options:
|
|||
values[option.key] = option.default
|
||||
|
||||
# next set the value specified in the options file
|
||||
if self.files:
|
||||
for filename in self.files:
|
||||
if os.path.exists(filename):
|
||||
execfile(filename, values)
|
||||
for filename in self.files:
|
||||
if os.path.exists(filename):
|
||||
dir = os.path.split(os.path.abspath(filename))[0]
|
||||
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:
|
||||
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:
|
||||
# (don't copy over variables that are not declared
|
||||
# as options)
|
||||
# (don't copy over variables that are not declared as options)
|
||||
for option in self.options:
|
||||
try:
|
||||
env[option.key] = values[option.key]
|
||||
|
@ -176,6 +212,13 @@ class Options:
|
|||
if option.validator and values.has_key(option.key):
|
||||
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):
|
||||
"""
|
||||
Saves all the options in the given file. This file can
|
||||
|
@ -238,12 +281,19 @@ class Options:
|
|||
actual = env.subst('${%s}' % opt.key)
|
||||
else:
|
||||
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))
|
||||
|
||||
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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
||||
|
@ -138,7 +138,8 @@ class _PathList:
|
|||
value = string.join(map(str, value), '')
|
||||
elif type == TYPE_OBJECT:
|
||||
value = node_conv(value)
|
||||
result.append(value)
|
||||
if value:
|
||||
result.append(value)
|
||||
return tuple(result)
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ their own platform definition.
|
|||
# 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 os
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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 string
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
from SCons.Platform import TempFileMunge
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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):
|
||||
if not env.has_key('ENV'):
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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.path
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
|
||||
|
@ -41,4 +41,4 @@ def generate(env):
|
|||
env['MAXLINELENGTH'] = 1045320
|
||||
env['PKGINFO'] = 'pkginfo'
|
||||
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.
|
||||
#
|
||||
|
||||
__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.path
|
||||
|
@ -40,13 +40,53 @@ import tempfile
|
|||
|
||||
from SCons.Platform.posix import exitvalmap
|
||||
from SCons.Platform import TempFileMunge
|
||||
|
||||
# XXX See note below about why importing SCons.Action should be
|
||||
# eventually refactored.
|
||||
import SCons.Action
|
||||
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,
|
||||
# you had better have cmd or command.com in your PATH when you run
|
||||
# scons.
|
|
@ -26,7 +26,9 @@ Autoconf-like configuration support.
|
|||
# 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 re
|
||||
|
@ -46,10 +48,20 @@ import SCons.Util
|
|||
import SCons.Warnings
|
||||
import SCons.Conftest
|
||||
|
||||
from SCons.Debug import Trace
|
||||
|
||||
# Turn off the Conftest error logging
|
||||
SCons.Conftest.LogInputFiles = 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
|
||||
dryrun = 0
|
||||
|
||||
|
@ -159,11 +171,9 @@ class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
|
|||
result = None # -> 0/None -> no error, != 0 error
|
||||
string = None # the stdout / stderr output when building the target
|
||||
|
||||
def __init__(self, node, result, string, sig):
|
||||
SCons.Node.FS.FileBuildInfo.__init__(self, node)
|
||||
def set_build_result(self, result, string):
|
||||
self.result = result
|
||||
self.string = string
|
||||
self.ninfo.bsig = sig
|
||||
|
||||
|
||||
class Streamer:
|
||||
|
@ -211,7 +221,7 @@ class SConfBuildTask(SCons.Taskmaster.Task):
|
|||
"""
|
||||
if not isinstance(bi, SConfBuildInfo):
|
||||
SCons.Warnings.warn(SConfWarning,
|
||||
"The stored build information has an unexpected class.")
|
||||
"The stored build information has an unexpected class: %s" % bi.__class__)
|
||||
else:
|
||||
self.display("The original builder output was:\n" +
|
||||
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
|
||||
# build will fail
|
||||
# cachable is 0, if some nodes are not in our cache
|
||||
is_up_to_date = 1
|
||||
cached_error = 0
|
||||
cachable = 1
|
||||
T = 0
|
||||
changed = False
|
||||
cached_error = False
|
||||
cachable = True
|
||||
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 T: Trace(': SConfBuildInfo')
|
||||
if cache_mode == CACHE:
|
||||
t.set_state(SCons.Node.up_to_date)
|
||||
if T: Trace(': set_state(up_to-date)')
|
||||
else:
|
||||
new_bsig = t.calc_signature(sconf_global.calc)
|
||||
if t.env.use_build_signature():
|
||||
old_bsig = bi.ninfo.bsig
|
||||
else:
|
||||
old_bsig = bi.ninfo.csig
|
||||
is_up_to_date = (is_up_to_date and new_bsig == old_bsig)
|
||||
if T: Trace(': get_state() %s' % t.get_state())
|
||||
if T: Trace(': changed() %s' % t.changed())
|
||||
if (t.get_state() != SCons.Node.up_to_date and t.changed()):
|
||||
changed = True
|
||||
if T: Trace(': changed %s' % changed)
|
||||
cached_error = cached_error or bi.result
|
||||
else:
|
||||
if T: Trace(': else')
|
||||
# the node hasn't been built in a SConf context or doesn't
|
||||
# exist
|
||||
cachable = 0
|
||||
is_up_to_date = 0
|
||||
return (is_up_to_date, cached_error, cachable)
|
||||
cachable = False
|
||||
changed = ( t.get_state() != SCons.Node.up_to_date )
|
||||
if T: Trace(': changed %s' % changed)
|
||||
if T: Trace('\n')
|
||||
return (not changed, cached_error, cachable)
|
||||
|
||||
def execute(self):
|
||||
if not self.targets[0].has_builder():
|
||||
return
|
||||
|
||||
sconf = sconf_global
|
||||
|
||||
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:
|
||||
self.display("Building \"%s\" failed in a previous run and all "
|
||||
"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
|
||||
elif is_up_to_date:
|
||||
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:
|
||||
raise ConfigureDryRunError(self.targets[0])
|
||||
else:
|
||||
|
@ -305,21 +326,43 @@ class SConfBuildTask(SCons.Taskmaster.Task):
|
|||
except SystemExit:
|
||||
exc_value = sys.exc_info()[1]
|
||||
raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
|
||||
except:
|
||||
except Exception, e:
|
||||
for t in self.targets:
|
||||
sig = t.calc_signature(sconf.calc)
|
||||
string = s.getvalue()
|
||||
binfo = SConfBuildInfo(t,1,string,sig)
|
||||
t.dir.sconsign().set_entry(t.name, binfo)
|
||||
raise
|
||||
binfo = t.get_binfo()
|
||||
binfo.__class__ = SConfBuildInfo
|
||||
binfo.set_build_result(1, s.getvalue())
|
||||
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()
|
||||
raise e
|
||||
else:
|
||||
for t in self.targets:
|
||||
sig = t.calc_signature(sconf.calc)
|
||||
string = s.getvalue()
|
||||
binfo = SConfBuildInfo(t,0,string,sig)
|
||||
t.dir.sconsign().set_entry(t.name, binfo)
|
||||
binfo = t.get_binfo()
|
||||
binfo.__class__ = SConfBuildInfo
|
||||
binfo.set_build_result(0, s.getvalue())
|
||||
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
|
||||
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
|
||||
|
@ -360,6 +403,7 @@ class SConf:
|
|||
default_tests = {
|
||||
'CheckFunc' : CheckFunc,
|
||||
'CheckType' : CheckType,
|
||||
'CheckTypeSize' : CheckTypeSize,
|
||||
'CheckHeader' : CheckHeader,
|
||||
'CheckCHeader' : CheckCHeader,
|
||||
'CheckCXXHeader' : CheckCXXHeader,
|
||||
|
@ -369,7 +413,6 @@ class SConf:
|
|||
self.AddTests(default_tests)
|
||||
self.AddTests(custom_tests)
|
||||
self.confdir = SConfFS.Dir(env.subst(conf_dir))
|
||||
self.calc = None
|
||||
if not config_h is None:
|
||||
config_h = SConfFS.File(config_h)
|
||||
self.config_h = config_h
|
||||
|
@ -377,7 +420,8 @@ class SConf:
|
|||
|
||||
def Finish(self):
|
||||
"""Call this method after finished with your tests:
|
||||
env = sconf.Finish()"""
|
||||
env = sconf.Finish()
|
||||
"""
|
||||
self._shutdown()
|
||||
return self.env
|
||||
|
||||
|
@ -398,6 +442,13 @@ class SConf:
|
|||
old_os_dir = os.getcwd()
|
||||
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
|
||||
|
||||
try:
|
||||
|
@ -561,7 +612,7 @@ class SConf:
|
|||
def AddTest(self, test_name, test_instance):
|
||||
"""Adds test_class to this SConf instance. It can be called with
|
||||
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):
|
||||
"""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.
|
||||
|
||||
|
||||
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):
|
||||
res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language)
|
||||
context.did_show_result = 1
|
||||
|
@ -784,6 +848,13 @@ def CheckType(context, type_name, includes = "", language = None):
|
|||
context.did_show_result = 1
|
||||
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 = '""'):
|
||||
# used by CheckHeader and CheckLibWithHeader to produce C - #include
|
||||
# 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.
|
||||
#
|
||||
|
||||
__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 os
|
||||
import os.path
|
||||
|
||||
import SCons.dblite
|
||||
import SCons.Sig
|
||||
import SCons.Warnings
|
||||
|
||||
def corrupt_dblite_warning(filename):
|
||||
|
@ -107,6 +108,24 @@ def write():
|
|||
else:
|
||||
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:
|
||||
"""
|
||||
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
|
||||
that make up signature entry.
|
||||
"""
|
||||
def __init__(self, module=None):
|
||||
"""
|
||||
module - the signature module being used
|
||||
"""
|
||||
|
||||
self.module = module or SCons.Sig.default_calc.module
|
||||
def __init__(self):
|
||||
self.entries = {}
|
||||
self.dirty = 0
|
||||
self.dirty = False
|
||||
self.to_be_merged = {}
|
||||
|
||||
def get_entry(self, filename):
|
||||
"""
|
||||
|
@ -136,19 +151,43 @@ class Base:
|
|||
Set the entry.
|
||||
"""
|
||||
self.entries[filename] = obj
|
||||
self.dirty = 1
|
||||
self.dirty = True
|
||||
|
||||
def do_not_set_entry(self, filename, obj):
|
||||
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):
|
||||
"""
|
||||
A Base subclass that reads and writes signature information
|
||||
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):
|
||||
Base.__init__(self, module)
|
||||
def __init__(self, dir):
|
||||
Base.__init__(self)
|
||||
|
||||
self.dir = dir
|
||||
|
||||
|
@ -182,6 +221,7 @@ class DB(Base):
|
|||
# a file there. Don't actually set any entry info, so we
|
||||
# won't try to write to that .sconsign.dblite file.
|
||||
self.set_entry = self.do_not_set_entry
|
||||
self.store_info = self.do_not_store_info
|
||||
|
||||
global sig_files
|
||||
sig_files.append(self)
|
||||
|
@ -190,6 +230,8 @@ class DB(Base):
|
|||
if not self.dirty:
|
||||
return
|
||||
|
||||
self.merge()
|
||||
|
||||
db, mode = Get_DataBase(self.dir)
|
||||
|
||||
# Write using the path relative to the top of the SConstruct
|
||||
|
@ -211,27 +253,31 @@ class DB(Base):
|
|||
syncmethod()
|
||||
|
||||
class Dir(Base):
|
||||
def __init__(self, fp=None, module=None):
|
||||
def __init__(self, fp=None, dir=None):
|
||||
"""
|
||||
fp - file pointer to read entries from
|
||||
module - the signature module being used
|
||||
"""
|
||||
Base.__init__(self, module)
|
||||
Base.__init__(self)
|
||||
|
||||
if fp:
|
||||
self.entries = cPickle.load(fp)
|
||||
if type(self.entries) is not type({}):
|
||||
self.entries = {}
|
||||
raise TypeError
|
||||
if not fp:
|
||||
return
|
||||
|
||||
self.entries = cPickle.load(fp)
|
||||
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):
|
||||
"""
|
||||
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
|
||||
module - the signature module being used
|
||||
"""
|
||||
|
||||
self.dir = dir
|
||||
|
@ -243,7 +289,7 @@ class DirFile(Dir):
|
|||
fp = None
|
||||
|
||||
try:
|
||||
Dir.__init__(self, fp, module)
|
||||
Dir.__init__(self, fp, dir)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
|
@ -253,15 +299,6 @@ class DirFile(Dir):
|
|||
global sig_files
|
||||
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):
|
||||
"""
|
||||
Write the .sconsign file to disk.
|
||||
|
@ -275,48 +312,52 @@ class DirFile(Dir):
|
|||
to the .sconsign file. Either way, always try to remove
|
||||
the temporary file at the end.
|
||||
"""
|
||||
if self.dirty:
|
||||
temp = os.path.join(self.dir.path, '.scons%d' % os.getpid())
|
||||
if not self.dirty:
|
||||
return
|
||||
|
||||
self.merge()
|
||||
|
||||
temp = os.path.join(self.dir.path, '.scons%d' % os.getpid())
|
||||
try:
|
||||
file = open(temp, 'wb')
|
||||
fname = temp
|
||||
except IOError:
|
||||
try:
|
||||
file = open(temp, 'wb')
|
||||
fname = temp
|
||||
file = open(self.sconsign, 'wb')
|
||||
fname = self.sconsign
|
||||
except IOError:
|
||||
try:
|
||||
file = open(self.sconsign, 'wb')
|
||||
fname = self.sconsign
|
||||
except IOError:
|
||||
return
|
||||
for key, entry in self.entries.items():
|
||||
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)
|
||||
return
|
||||
for key, entry in self.entries.items():
|
||||
entry.convert_to_sconsign()
|
||||
cPickle.dump(self.entries, file, 1)
|
||||
file.close()
|
||||
if fname != self.sconsign:
|
||||
try:
|
||||
os.unlink(temp)
|
||||
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:
|
||||
os.unlink(temp)
|
||||
except (IOError, OSError):
|
||||
pass
|
||||
|
||||
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.
|
||||
#
|
||||
|
||||
__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.Scanner
|
|
@ -30,7 +30,7 @@ Coded by Andy Friesen
|
|||
# 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
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
# 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.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.
|
||||
#
|
||||
|
||||
__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 string
|
|
@ -28,7 +28,7 @@ Definition Language) files.
|
|||
# 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.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.
|
||||
#
|
||||
|
||||
__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 string
|
||||
import os.path
|
||||
|
||||
def LaTeXScanner(fs = SCons.Node.FS.default_fs):
|
||||
def LaTeXScanner():
|
||||
"""Return a prototype Scanner instance for scanning LaTeX source files"""
|
||||
ds = LaTeX(name = "LaTeXScanner",
|
||||
suffixes = '$LATEXSUFFIXES',
|
||||
path_variable = 'TEXINPUTS',
|
||||
regex = '\\\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography){([^}]*)}',
|
||||
regex = '\\\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography|usepackage){([^}]*)}',
|
||||
recursive = 0)
|
||||
return ds
|
||||
|
||||
|
@ -72,6 +72,10 @@ class LaTeX(SCons.Scanner.Classic):
|
|||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
filename = filename + '.bib'
|
||||
if include[0] == 'usepackage':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
filename = filename + '.sty'
|
||||
return filename
|
||||
def sort_key(self, 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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
|
@ -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.
|
||||
#
|
||||
|
||||
__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 string
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Sig
|
||||
import SCons.Util
|
||||
|
||||
|
||||
|
@ -306,8 +305,7 @@ class Current(Base):
|
|||
|
||||
def __init__(self, *args, **kw):
|
||||
def current_check(node, env):
|
||||
c = not node.has_builder() or node.current(env.get_calculator())
|
||||
return c
|
||||
return not node.has_builder() or node.is_up_to_date()
|
||||
kw['scan_check'] = current_check
|
||||
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.
|
||||
#
|
||||
|
||||
__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.Action
|
||||
|
@ -65,6 +65,9 @@ import UserList
|
|||
#CommandLineTargets = []
|
||||
#DefaultTargets = []
|
||||
|
||||
class SConscriptReturn(Exception):
|
||||
pass
|
||||
|
||||
launch_dir = os.path.abspath(os.curdir)
|
||||
|
||||
GlobalDict = None
|
||||
|
@ -125,6 +128,8 @@ class Frame:
|
|||
# make sure the sconscript attr is a Node.
|
||||
if isinstance(sconscript, SCons.Node.Node):
|
||||
self.sconscript = sconscript
|
||||
elif sconscript == '-':
|
||||
self.sconscript = None
|
||||
else:
|
||||
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
|
||||
|
||||
def Return(*vars):
|
||||
def Return(*vars, **kw):
|
||||
retval = []
|
||||
try:
|
||||
for var in vars:
|
||||
|
@ -147,6 +152,11 @@ def Return(*vars):
|
|||
else:
|
||||
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 :)
|
||||
|
||||
|
@ -242,7 +252,10 @@ def _SConscript(fs, *files, **kw):
|
|||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
exec _file_ in call_stack[-1].globals
|
||||
try:
|
||||
exec _file_ in call_stack[-1].globals
|
||||
except SConscriptReturn:
|
||||
pass
|
||||
finally:
|
||||
if old_file is not None:
|
||||
call_stack[-1].globals.update({__file__:old_file})
|
||||
|
@ -469,7 +482,7 @@ class SConsEnvironment(SCons.Environment.Base):
|
|||
|
||||
def GetOption(self, name):
|
||||
name = self.subst(name)
|
||||
return SCons.Script.Main.ssoptions.get(name)
|
||||
return SCons.Script.Main.GetOption(name)
|
||||
|
||||
def Help(self, text):
|
||||
text = self.subst(text, raw=1)
|
||||
|
@ -525,7 +538,7 @@ class SConsEnvironment(SCons.Environment.Base):
|
|||
|
||||
def SetOption(self, name, value):
|
||||
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.
|
||||
#
|
||||
|
||||
__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
|
||||
start_time = time.time()
|
||||
|
@ -70,7 +70,7 @@ if "--debug=memoizer" in _args:
|
|||
# for it to be displayed or not after warnings are configured.
|
||||
import Main
|
||||
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
|
||||
|
||||
import SCons.Action
|
||||
|
@ -105,23 +105,28 @@ BuildTask = Main.BuildTask
|
|||
CleanTask = Main.CleanTask
|
||||
QuestionTask = Main.QuestionTask
|
||||
#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_explanations = Main.print_explanations
|
||||
print_includes = Main.print_includes
|
||||
print_objects = Main.print_objects
|
||||
print_time = Main.print_time
|
||||
#print_explanations = Main.print_explanations
|
||||
#print_includes = Main.print_includes
|
||||
#print_objects = Main.print_objects
|
||||
#print_time = Main.print_time
|
||||
#print_tree = Main.print_tree
|
||||
memory_stats = Main.memory_stats
|
||||
ignore_errors = Main.ignore_errors
|
||||
#memory_stats = Main.memory_stats
|
||||
#ignore_errors = Main.ignore_errors
|
||||
#sconscript_time = Main.sconscript_time
|
||||
#command_time = Main.command_time
|
||||
#exit_status = Main.exit_status
|
||||
#profiling = Main.profiling
|
||||
repositories = Main.repositories
|
||||
#repositories = Main.repositories
|
||||
|
||||
#
|
||||
import SConscript
|
||||
|
@ -131,12 +136,14 @@ call_stack = _SConscript.call_stack
|
|||
|
||||
#
|
||||
Action = SCons.Action.Action
|
||||
AddMethod = SCons.Util.AddMethod
|
||||
AllowSubstExceptions = SCons.Subst.SetAllowableExceptions
|
||||
BoolOption = SCons.Options.BoolOption
|
||||
Builder = SCons.Builder.Builder
|
||||
Configure = _SConscript.Configure
|
||||
EnumOption = SCons.Options.EnumOption
|
||||
Environment = SCons.Environment.Environment
|
||||
#OptParser = SCons.SConsOptions.OptParser
|
||||
FindPathDirs = SCons.Scanner.FindPathDirs
|
||||
ListOption = SCons.Options.ListOption
|
||||
PackageOption = SCons.Options.PackageOption
|
||||
|
@ -255,7 +262,7 @@ def HelpFunction(text):
|
|||
sconscript_reading = 0
|
||||
|
||||
#
|
||||
def Options(files=None, args=ARGUMENTS):
|
||||
def Options(files=[], args=ARGUMENTS):
|
||||
return SCons.Options.Options(files, args)
|
||||
|
||||
# The list of global functions to add to the SConscript name space
|
||||
|
@ -269,12 +276,10 @@ GlobalDefaultEnvironmentFunctions = [
|
|||
'Exit',
|
||||
'Export',
|
||||
'GetLaunchDir',
|
||||
'GetOption',
|
||||
'Help',
|
||||
'Import',
|
||||
#'SConscript', is handled separately, below.
|
||||
'SConscriptChdir',
|
||||
'SetOption',
|
||||
|
||||
# Methods from the Environment.Base class.
|
||||
'AddPostAction',
|
||||
|
@ -285,6 +290,7 @@ GlobalDefaultEnvironmentFunctions = [
|
|||
'CacheDir',
|
||||
'Clean',
|
||||
#The Command() method is handled separately, below.
|
||||
'Decider',
|
||||
'Depends',
|
||||
'Dir',
|
||||
'NoClean',
|
||||
|
@ -293,8 +299,11 @@ GlobalDefaultEnvironmentFunctions = [
|
|||
'Execute',
|
||||
'File',
|
||||
'FindFile',
|
||||
'FindInstalledFiles',
|
||||
'FindSourceFiles',
|
||||
'Flatten',
|
||||
'GetBuildPath',
|
||||
'Glob',
|
||||
'Ignore',
|
||||
'Install',
|
||||
'InstallAs',
|
||||
|
@ -303,11 +312,13 @@ GlobalDefaultEnvironmentFunctions = [
|
|||
'ParseDepends',
|
||||
'Precious',
|
||||
'Repository',
|
||||
'Requires',
|
||||
'SConsignFile',
|
||||
'SideEffect',
|
||||
'SourceCode',
|
||||
'SourceSignatures',
|
||||
'Split',
|
||||
'Tag',
|
||||
'TargetSignatures',
|
||||
'Value',
|
||||
]
|
||||
|
@ -337,6 +348,7 @@ GlobalDefaultBuilders = [
|
|||
'Tar',
|
||||
'TypeLibrary',
|
||||
'Zip',
|
||||
'Package',
|
||||
]
|
||||
|
||||
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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
|
@ -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.
|
||||
"""
|
||||
|
||||
__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
|
||||
|
||||
|
@ -205,20 +205,40 @@ class Task:
|
|||
raise SCons.Errors.TaskmasterException(self.targets[0],
|
||||
sys.exc_info())
|
||||
|
||||
def executed(self):
|
||||
def executed_without_callbacks(self):
|
||||
"""
|
||||
Called when the task has been successfully executed.
|
||||
|
||||
This may have been a do-nothing operation (to preserve build
|
||||
order), so we have to check the node's state before deciding
|
||||
whether it was "built" or just "visited."
|
||||
Called when the task has been successfully executed
|
||||
and the Taskmaster instance doesn't want to call
|
||||
the Node's callback methods.
|
||||
"""
|
||||
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)
|
||||
|
||||
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.built()
|
||||
else:
|
||||
t.visited()
|
||||
t.visited()
|
||||
|
||||
executed = executed_with_callbacks
|
||||
|
||||
def failed(self):
|
||||
"""
|
||||
|
@ -276,7 +296,9 @@ class Task:
|
|||
self.out_of_date = []
|
||||
for t in self.targets:
|
||||
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:
|
||||
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
||||
if is_up_to_date:
|
||||
|
@ -307,12 +329,14 @@ class Task:
|
|||
# back on the candidates list if the Node is also a waiting
|
||||
# parent.
|
||||
|
||||
targets = set(self.targets)
|
||||
|
||||
parents = {}
|
||||
for t in self.targets:
|
||||
for t in targets:
|
||||
for p in t.waiting_parents.keys():
|
||||
parents[p] = parents.get(p, 0) + 1
|
||||
|
||||
for t in self.targets:
|
||||
for t in targets:
|
||||
for s in t.side_effects:
|
||||
if s.get_state() == SCons.Node.executing:
|
||||
s.set_state(SCons.Node.no_state)
|
||||
|
@ -328,7 +352,7 @@ class Task:
|
|||
if p.ref_count == 0:
|
||||
self.tm.candidates.append(p)
|
||||
|
||||
for t in self.targets:
|
||||
for t in targets:
|
||||
t.postprocess()
|
||||
|
||||
# Exception handling subsystem.
|
||||
|
@ -402,8 +426,9 @@ class Taskmaster:
|
|||
"""
|
||||
|
||||
def __init__(self, targets=[], tasker=Task, order=None, trace=None):
|
||||
self.top_targets = targets[:]
|
||||
self.top_targets.reverse()
|
||||
self.original_top = targets
|
||||
self.top_targets_left = targets[:]
|
||||
self.top_targets_left.reverse()
|
||||
self.candidates = []
|
||||
self.tasker = tasker
|
||||
if not order:
|
||||
|
@ -437,7 +462,7 @@ class Taskmaster:
|
|||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
node = self.top_targets.pop()
|
||||
node = self.top_targets_left.pop()
|
||||
except IndexError:
|
||||
return None
|
||||
self.current_top = node
|
||||
|
@ -510,7 +535,7 @@ class Taskmaster:
|
|||
node.set_state(SCons.Node.pending)
|
||||
|
||||
try:
|
||||
children = node.children()
|
||||
children = node.children() + node.prerequisites
|
||||
except SystemExit:
|
||||
exc_value = sys.exc_info()[1]
|
||||
e = SCons.Errors.ExplicitExit(node, exc_value.code)
|
||||
|
@ -535,16 +560,14 @@ class Taskmaster:
|
|||
c.sort()
|
||||
T.write(' children:\n %s\n ' % c)
|
||||
|
||||
childinfo = map(lambda N: (N.get_state(),
|
||||
N.is_derived() or N.is_pseudo_derived(),
|
||||
N), children)
|
||||
childstate = map(lambda N: (N, N.get_state()), children)
|
||||
|
||||
# Skip this node if any of its children have failed. This
|
||||
# catches the case where we're descending a top-level target
|
||||
# and one of our children failed while trying to be built
|
||||
# by a *previous* descent of an earlier top-level target.
|
||||
failed_children = filter(lambda I: I[0] == SCons.Node.failed,
|
||||
childinfo)
|
||||
failed_children = filter(lambda I: I[1] == SCons.Node.failed,
|
||||
childstate)
|
||||
if failed_children:
|
||||
node.set_state(SCons.Node.failed)
|
||||
if S: S.child_failed = S.child_failed + 1
|
||||
|
@ -555,76 +578,48 @@ class Taskmaster:
|
|||
continue
|
||||
|
||||
# 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:
|
||||
for p in pending_nodes:
|
||||
cycle = find_cycle([p[2], node])
|
||||
cycle = find_cycle([p[0], node])
|
||||
if cycle:
|
||||
desc = "Dependency cycle: " + string.join(map(str, cycle), " -> ")
|
||||
if T: T.write(' dependency cycle\n')
|
||||
raise SCons.Errors.UserError, desc
|
||||
|
||||
# Select all of the dependencies that are derived targets
|
||||
# (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)
|
||||
not_built = filter(lambda I: I[1] <= SCons.Node.executing, childstate)
|
||||
if not_built:
|
||||
not_built = map(lambda I: I[2], not_built)
|
||||
|
||||
# We're waiting on one or more derived targets that have
|
||||
# started building but not yet finished. 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_built)
|
||||
node.ref_count = node.ref_count + reduce(operator.add, added, 0)
|
||||
# not yet finished building.
|
||||
|
||||
not_visited = filter(lambda I: not I[1], not_built)
|
||||
if not_visited:
|
||||
# Some of them haven't even been visited yet.
|
||||
# Add them to the list so that on some next pass
|
||||
# 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 T:
|
||||
c = map(str, not_built)
|
||||
c = map(str, n_b_nodes)
|
||||
c.sort()
|
||||
T.write(' waiting on unfinished children:\n %s\n' % c)
|
||||
continue
|
||||
|
||||
# Skip this node if it has side-effects that are currently being
|
||||
# built themselves or waiting for something else being built.
|
||||
# Skip this node if it has side-effects that are
|
||||
# currently being built:
|
||||
side_effects = filter(lambda N:
|
||||
N.get_state() == SCons.Node.executing,
|
||||
node.side_effects)
|
||||
|
@ -659,7 +654,7 @@ class Taskmaster:
|
|||
|
||||
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:
|
||||
task.make_ready()
|
||||
except KeyboardInterrupt:
|
|
@ -32,7 +32,7 @@ selection method.
|
|||
# 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
|
||||
import SCons.Util
|
|
@ -32,7 +32,7 @@ selection method.
|
|||
# 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.Builder
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Builder
|
|
@ -27,7 +27,7 @@ Stuff for processing Java.
|
|||
# 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.path
|
||||
|
@ -36,6 +36,8 @@ import string
|
|||
|
||||
java_parsing = 1
|
||||
|
||||
default_java_version = '1.4'
|
||||
|
||||
if java_parsing:
|
||||
# Parse Java files for class names.
|
||||
#
|
||||
|
@ -53,18 +55,26 @@ if java_parsing:
|
|||
# array declarations "[]";
|
||||
# semi-colons;
|
||||
# periods.
|
||||
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.]|' +
|
||||
r'[A-Za-z_][\w\.]*|/\*|\*/|\[\])')
|
||||
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' +
|
||||
r'[A-Za-z_][\w\$\.]*|/\*|\*/|\[\])')
|
||||
|
||||
class OuterState:
|
||||
"""The initial state for parsing a Java file for 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.listOutputs = []
|
||||
self.stackBrackets = []
|
||||
self.brackets = 0
|
||||
self.nextAnon = 1
|
||||
self.stackAnonClassBrackets = []
|
||||
self.anonStacksStack = [[0]]
|
||||
self.package = None
|
||||
|
||||
def trace(self):
|
||||
|
@ -90,6 +100,7 @@ if java_parsing:
|
|||
try:
|
||||
return self.anonState
|
||||
except AttributeError:
|
||||
self.outer_state = self
|
||||
ret = SkipState(1, AnonClassState(self))
|
||||
self.anonState = ret
|
||||
return ret
|
||||
|
@ -102,6 +113,9 @@ if java_parsing:
|
|||
self.skipState = ret
|
||||
return ret
|
||||
|
||||
def __getAnonStack(self):
|
||||
return self.anonStacksStack[-1]
|
||||
|
||||
def openBracket(self):
|
||||
self.brackets = self.brackets + 1
|
||||
|
||||
|
@ -111,7 +125,12 @@ if java_parsing:
|
|||
self.brackets == self.stackBrackets[-1]:
|
||||
self.listOutputs.append(string.join(self.listClasses, '$'))
|
||||
self.listClasses.pop()
|
||||
self.anonStacksStack.pop()
|
||||
self.stackBrackets.pop()
|
||||
if len(self.stackAnonClassBrackets) and \
|
||||
self.brackets == self.stackAnonClassBrackets[-1]:
|
||||
self.__getAnonStack().pop()
|
||||
self.stackAnonClassBrackets.pop()
|
||||
|
||||
def parseToken(self, token):
|
||||
if token[:2] == '//':
|
||||
|
@ -145,32 +164,56 @@ if java_parsing:
|
|||
|
||||
def addAnonClass(self):
|
||||
"""Add an anonymous inner class"""
|
||||
clazz = self.listClasses[0]
|
||||
self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
|
||||
if self.version in ('1.1', '1.2', '1.3', '1.4'):
|
||||
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.__getAnonStack().append(0)
|
||||
|
||||
def setPackage(self, package):
|
||||
self.package = package
|
||||
|
||||
class AnonClassState:
|
||||
"""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
|
||||
self.outer_state = outer_state
|
||||
self.tokens_to_find = 2
|
||||
self.outer_state = old_state.outer_state
|
||||
self.old_state = old_state
|
||||
self.brace_level = 0
|
||||
def parseToken(self, token):
|
||||
# This is an anonymous class if and only if the next
|
||||
# non-whitespace token is a bracket
|
||||
if token == '\n':
|
||||
# non-whitespace token is a bracket. Everything between
|
||||
# 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
|
||||
if token == '{':
|
||||
self.outer_state.openBracket()
|
||||
self.outer_state.addAnonClass()
|
||||
elif token == '}':
|
||||
self.outer_state.closeBracket()
|
||||
elif token in ['"', "'"]:
|
||||
return IgnoreState(token, self)
|
||||
return self.outer_state
|
||||
return self.old_state.parseToken(token)
|
||||
|
||||
class SkipState:
|
||||
"""A state that will skip a specified number of tokens before
|
||||
|
@ -194,6 +237,7 @@ if java_parsing:
|
|||
if token == '\n':
|
||||
return self
|
||||
self.outer_state.listClasses.append(token)
|
||||
self.outer_state.anonStacksStack.append([0])
|
||||
return self.outer_state
|
||||
|
||||
class IgnoreState:
|
||||
|
@ -217,15 +261,15 @@ if java_parsing:
|
|||
self.outer_state.setPackage(token)
|
||||
return self.outer_state
|
||||
|
||||
def parse_java_file(fn):
|
||||
return parse_java(open(fn, 'r').read())
|
||||
def parse_java_file(fn, version=default_java_version):
|
||||
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,
|
||||
plus a list of .class files that compiling that .java file will
|
||||
produce"""
|
||||
package = None
|
||||
initial = OuterState()
|
||||
initial = OuterState(version)
|
||||
currstate = initial
|
||||
for token in _reToken.findall(contents):
|
||||
# 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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
|
@ -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.
|
||||
#
|
||||
|
||||
__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.path
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Builder
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Builder
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -36,13 +36,14 @@ tool definition.
|
|||
# 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 sys
|
||||
|
||||
import SCons.Builder
|
||||
import SCons.Errors
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
||||
import SCons.Scanner.C
|
||||
import SCons.Scanner.D
|
||||
|
@ -88,8 +89,11 @@ class Tool:
|
|||
module = self._tool_module()
|
||||
self.generate = module.generate
|
||||
self.exists = module.exists
|
||||
if hasattr(module, 'options'):
|
||||
self.options = module.options
|
||||
|
||||
def _tool_module(self):
|
||||
# TODO: Interchange zipimport with normal initilization for better error reporting
|
||||
oldpythonpath = sys.path
|
||||
sys.path = self.toolpath + sys.path
|
||||
|
||||
|
@ -102,6 +106,8 @@ class Tool:
|
|||
if file:
|
||||
file.close()
|
||||
except ImportError, e:
|
||||
if str(e)!="No module named %s"%self.name:
|
||||
raise SCons.Errors.EnvironmentError, e
|
||||
try:
|
||||
import zipimport
|
||||
except ImportError:
|
||||
|
@ -130,6 +136,8 @@ class Tool:
|
|||
file.close()
|
||||
return module
|
||||
except ImportError, e:
|
||||
if e!="No module named %s"%self.name:
|
||||
raise SCons.Errors.EnvironmentError, e
|
||||
try:
|
||||
import zipimport
|
||||
importer = zipimport.zipimporter( sys.modules['SCons.Tool'].__path__[0] )
|
||||
|
@ -138,10 +146,10 @@ class Tool:
|
|||
return module
|
||||
except ImportError, e:
|
||||
m = "No tool named '%s': %s" % (self.name, e)
|
||||
raise SCons.Errors.UserError, m
|
||||
raise SCons.Errors.EnvironmentError, m
|
||||
except ImportError, 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):
|
||||
if self.init_kw is not None:
|
||||
|
@ -154,11 +162,24 @@ class Tool:
|
|||
else:
|
||||
kw = self.init_kw
|
||||
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)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
##########################################################################
|
||||
# Create common executable program / library / object builders
|
||||
|
||||
def createProgBuilder(env):
|
||||
"""This is a utility function that creates the Program
|
||||
Builder in an Environment if it is not there already.
|
||||
|
@ -316,7 +337,8 @@ def createCFileBuilders(env):
|
|||
emitter = {},
|
||||
suffix = {None:'$CFILESUFFIX'})
|
||||
env['BUILDERS']['CFile'] = c_file
|
||||
env['CFILESUFFIX'] = '.c'
|
||||
|
||||
env.SetDefault(CFILESUFFIX = '.c')
|
||||
|
||||
try:
|
||||
cxx_file = env['BUILDERS']['CXXFile']
|
||||
|
@ -325,10 +347,130 @@ def createCFileBuilders(env):
|
|||
emitter = {},
|
||||
suffix = {None:'$CXXFILESUFFIX'})
|
||||
env['BUILDERS']['CXXFile'] = cxx_file
|
||||
env['CXXFILESUFFIX'] = '.cc'
|
||||
env.SetDefault(CXXFILESUFFIX = '.cc')
|
||||
|
||||
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):
|
||||
for tool in tools:
|
||||
t = Tool(tool)
|
||||
|
@ -438,6 +580,7 @@ def tool_list(platform, env):
|
|||
|
||||
other_tools = FindAllTools(['BitKeeper', 'CVS',
|
||||
'dmd',
|
||||
'filesystem',
|
||||
'dvipdf', 'dvips', 'gs',
|
||||
'jar', 'javac', 'javah',
|
||||
'latex', 'lex',
|
||||
|
@ -448,7 +591,7 @@ def tool_list(platform, env):
|
|||
# 'Subversion',
|
||||
'swig',
|
||||
'tar', 'tex',
|
||||
'yacc', 'zip'],
|
||||
'yacc', 'zip', 'rpm', 'wix'],
|
||||
env)
|
||||
|
||||
tools = ([linker, c_compiler, cxx_compiler,
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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.path
|
||||
|
@ -44,7 +44,7 @@ cplusplus = __import__('c++', globals(), locals(), [])
|
|||
|
||||
def smart_linkflags(source, target, env, for_signature):
|
||||
if cplusplus.iscplusplus(source):
|
||||
build_dir = env.subst('$BUILDDIR')
|
||||
build_dir = env.subst('$BUILDDIR', target=target, source=source)
|
||||
if build_dir:
|
||||
return '-qtempinc=' + os.path.join(build_dir, 'tempinc')
|
||||
return ''
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Tool
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Tool
|
|
@ -27,7 +27,7 @@ XXX
|
|||
# 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.path
|
||||
|
@ -42,12 +42,7 @@ def findIt(program, env):
|
|||
borwin = env.WhereIs(program) or SCons.Util.WhereIs(program)
|
||||
if borwin:
|
||||
dir = os.path.dirname(borwin)
|
||||
path = env['ENV'].get('PATH', [])
|
||||
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)
|
||||
env.PrependENVPath('PATH', dir)
|
||||
return borwin
|
||||
|
||||
def generate(env):
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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.Defaults
|
||||
|
@ -73,6 +73,18 @@ def generate(env):
|
|||
shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
|
||||
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
||||
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)
|
||||
|
|
@ -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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -53,7 +53,7 @@ Lib tool variables:
|
|||
# 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 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.
|
||||
#
|
||||
|
||||
__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.Tool
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Defaults
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Builder
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Scanner.Fortran
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Scanner.Fortran
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.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.
|
||||
#
|
||||
|
||||
__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 string
|
||||
|
@ -78,8 +78,8 @@ def _fortranEmitter(target, source, env):
|
|||
# Remove unique items from the list
|
||||
modules = SCons.Util.unique(modules)
|
||||
# Convert module name to a .mod filename
|
||||
suffix = env.subst('$FORTRANMODSUFFIX')
|
||||
moddir = env.subst('$FORTRANMODDIR')
|
||||
suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source)
|
||||
moddir = env.subst('$FORTRANMODDIR', target=target, source=source)
|
||||
modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
|
||||
for m in modules:
|
||||
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.
|
||||
#
|
||||
|
||||
__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 re
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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(), [])
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Platform
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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 string
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -30,7 +30,7 @@ selection method.
|
|||
# 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.path
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -32,7 +32,7 @@ selection method.
|
|||
# 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
|
||||
|
|
@ -31,7 +31,7 @@ selection method.
|
|||
# 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.Tool
|
|
@ -27,7 +27,7 @@ XXX
|
|||
# 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.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.
|
||||
#
|
||||
|
||||
__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
|
||||
|
||||
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'
|
||||
|
||||
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)
|
||||
"""
|
||||
# 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:
|
||||
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
|
||||
except SCons.Util.RegError:
|
||||
|
@ -160,7 +166,10 @@ def get_all_compiler_versions():
|
|||
"""
|
||||
versions=[]
|
||||
if is_windows:
|
||||
keyname = 'Software\\Intel\\Compilers\\C++'
|
||||
if is_win64:
|
||||
keyname = 'Software\\WoW6432Node\\Intel\\Compilers\\C++'
|
||||
else:
|
||||
keyname = 'Software\\Intel\\Compilers\\C++'
|
||||
try:
|
||||
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
|
||||
keyname)
|
||||
|
@ -178,7 +187,7 @@ def get_all_compiler_versions():
|
|||
# than uninstalling properly), so the registry values
|
||||
# are still there.
|
||||
ok = False
|
||||
for try_abi in ('IA32', 'IA32e', 'IA64'):
|
||||
for try_abi in ('IA32', 'IA32e', 'IA64', 'EM64T'):
|
||||
try:
|
||||
d = get_intel_registry_value('ProductDir', subkey, try_abi)
|
||||
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 include dir is <top>/include, etc.
|
||||
"""
|
||||
|
||||
if is_windows:
|
||||
if not SCons.Util.can_read_reg:
|
||||
raise NoRegistryModuleError, "No Windows registry module was found"
|
||||
|
@ -282,8 +292,10 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
|
|||
else:
|
||||
abi = 'ia32'
|
||||
else:
|
||||
# XXX: how would we do the same test on Windows?
|
||||
abi = "ia32"
|
||||
if is_win64:
|
||||
abi = 'em64t'
|
||||
else:
|
||||
abi = 'ia32'
|
||||
|
||||
if version and not topdir:
|
||||
try:
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue