upgrade to the latest scons (0.97)
This commit is contained in:
parent
8887b9eb99
commit
6752dda07e
165 changed files with 20697 additions and 11194 deletions
|
@ -1,9 +1,4 @@
|
||||||
Copyright and license for SCons - a software construction tool
|
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
|
|
||||||
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 The SCons Foundation
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,42 +1,28 @@
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
|
# src/README.txt 0.97.D001 2007/05/17 11:35:19 knight
|
||||||
|
|
||||||
|
|
||||||
SCons - a software construction tool
|
SCons - a software construction tool
|
||||||
|
|
||||||
This is the scons-README file for a version of SCons packaged for local
|
Version 0.97
|
||||||
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:
|
|
||||||
|
|
||||||
1) You have unpacked an scons-local-{version} package and are
|
This is a beta release of SCons, a tool for building software (and other
|
||||||
examining the contents.
|
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.
|
||||||
|
|
||||||
In this case, you are presumably interested in using this
|
See the RELEASE.txt file for notes about this specific release,
|
||||||
package to include a local copy of SCons with some other
|
including known problems. See the CHANGES.txt file for a list of
|
||||||
software that you package, so that you can use SCons to build
|
changes since the previous release.
|
||||||
your software without forcing all of your users to have it fully
|
|
||||||
installed. Instructions for this can be found below.
|
|
||||||
|
|
||||||
If you are not looking to use SCons in this way, then please
|
|
||||||
use either the scons-{version} package to install SCons on your
|
|
||||||
system, or the scons-src-{version} package if you want the full
|
|
||||||
source to SCons, including its packaging code and underlying
|
|
||||||
tests and testing infrastructure.
|
|
||||||
|
|
||||||
2) This file was included in some other software package so that
|
|
||||||
the package could be built using SCons.
|
|
||||||
|
|
||||||
In this case, follow the instructions provided with the
|
|
||||||
rest of the software package for how to use SCons to build
|
|
||||||
and/or install the software. The file containing build and
|
|
||||||
installation instructions will typically be named README or
|
|
||||||
INSTALL.
|
|
||||||
|
|
||||||
LATEST VERSION
|
LATEST VERSION
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Before going further, you can check for the latest version of the
|
Before going further, you can check that this package you have is
|
||||||
scons-local package, or any SCons package, at the SCons download page:
|
the latest version by checking the SCons download page at:
|
||||||
|
|
||||||
http://www.scons.org/download.html
|
http://www.scons.org/download.html
|
||||||
|
|
||||||
|
@ -45,93 +31,149 @@ EXECUTION REQUIREMENTS
|
||||||
======================
|
======================
|
||||||
|
|
||||||
Running SCons requires Python version 1.5.2 or later. There should be
|
Running SCons requires Python version 1.5.2 or later. There should be
|
||||||
no other dependencies or requirements to run SCons.
|
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.)
|
||||||
|
|
||||||
The default SCons configuration assumes use of the Microsoft Visual C++
|
By default, SCons knows how to search for available programming tools
|
||||||
compiler suite on WIN32 systems, and assumes a C compiler named 'cc',
|
on various systems--see the SCons man page for details. You may,
|
||||||
a C++ compiler named 'c++', and a Fortran compiler named 'g77' (such
|
of course, override the default SCons choices made by appropriate
|
||||||
as found in the GNU C compiler suite) on any other type of system.
|
|
||||||
You may, of course, override these default values by appropriate
|
|
||||||
configuration of Environment construction variables.
|
configuration of Environment construction variables.
|
||||||
|
|
||||||
|
|
||||||
|
INSTALLATION REQUIREMENTS
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Installing SCons from this package requires the Python distutils
|
||||||
|
package. The distutils package was not shipped as a standard part of
|
||||||
|
Python until Python version 1.6, so if your system is running Python
|
||||||
|
1.5.2, you may not have distutils installed. If you are running
|
||||||
|
Python version 1.6 or later, you should be fine.
|
||||||
|
|
||||||
|
NOTE TO RED HAT USERS: Red Hat shipped Python 1.5.2 as the default all
|
||||||
|
the way up to Red Hat Linux 7.3, so you probably do *not* have distutils
|
||||||
|
installed, unless you have already done so manually or are running Red
|
||||||
|
Hat 8.0 or later.
|
||||||
|
|
||||||
|
In this case, your options are:
|
||||||
|
|
||||||
|
-- (Recommended.) Install from a pre-packaged SCons package that
|
||||||
|
does not require distutils:
|
||||||
|
|
||||||
|
Red Hat Linux scons-0.97-1.noarch.rpm
|
||||||
|
|
||||||
|
Debian GNU/Linux scons_0.97-1_all.deb
|
||||||
|
(or use apt-get)
|
||||||
|
|
||||||
|
Windows scons-0.97.win32.exe
|
||||||
|
|
||||||
|
-- (Optional.) Download the latest distutils package from the
|
||||||
|
following URL:
|
||||||
|
|
||||||
|
http://www.python.org/sigs/distutils-sig/download.html
|
||||||
|
|
||||||
|
Install the distutils according to the instructions on the page.
|
||||||
|
You can then proceed to the next section to install SCons from
|
||||||
|
this package.
|
||||||
|
|
||||||
|
|
||||||
INSTALLATION
|
INSTALLATION
|
||||||
============
|
============
|
||||||
|
|
||||||
Installation of this package should be as simple as unpacking the
|
Assuming your system satisfies the installation requirements in the
|
||||||
archive (either .tar.gz or .zip) in any directory (top-level or a
|
previous section, install SCons from this package simply by running the
|
||||||
subdirectory) within the software package with which you want to ship
|
provided Python-standard setup script as follows:
|
||||||
SCons.
|
|
||||||
|
|
||||||
Once you have installed this package, you should write an SConstruct
|
# python setup.py install
|
||||||
file at the top level of your source tree to build your software as you
|
|
||||||
see fit.
|
|
||||||
|
|
||||||
Then modify the build/install instructions for your package to instruct
|
By default, the above command will do the following:
|
||||||
your users to execute SCons as follows (if you installed this package in
|
|
||||||
your top-level directory):
|
|
||||||
|
|
||||||
$ python scons.py
|
-- 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.
|
||||||
|
|
||||||
Or (if, for example, you installed this package in a subdirectory named
|
-- Install scripts named "scons" and "sconsign" scripts in the
|
||||||
"scons"):
|
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.
|
||||||
|
|
||||||
$ python scons/scons.py
|
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.
|
||||||
|
|
||||||
That should be all you have to do. (If it isn't that simple, please let
|
-- Install "scons-0.97.bat" and "scons.bat" wrapper scripts in the
|
||||||
us know!)
|
Python prefix directory on Windows (C:\Python*, for example).
|
||||||
|
This can be disabled by specifying the "--no-install-bat" option
|
||||||
|
on the command line.
|
||||||
|
|
||||||
|
On UNIX or Linux systems, the "--install-bat" option may be
|
||||||
|
specified to have "scons-0.97.bat" and "scons.bat" files
|
||||||
|
installed in the default system script directory, which is useful
|
||||||
|
if you want to install SCons in a shared file system directory
|
||||||
|
that can be used to execute SCons from both UNIX/Linux and
|
||||||
|
Windows systems.
|
||||||
|
|
||||||
CONTENTS OF THIS PACKAGE
|
-- 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.
|
||||||
|
|
||||||
This scons-local package consists of the following:
|
-- 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.
|
||||||
|
|
||||||
scons-LICENSE
|
Note that, by default, SCons does not install its build engine library
|
||||||
A copy of the copyright and terms under which SCons is
|
in the standard Python library directories. If you want to be able to
|
||||||
distributed (the Open Source Initiative-approved MIT license).
|
use the SCons library modules (the build engine) in other Python
|
||||||
|
scripts, specify the "--standard-lib" option on the command line, as
|
||||||
|
follows:
|
||||||
|
|
||||||
A disclaimer has been added to the beginning to make clear that
|
# python setup.py install --standard-lib
|
||||||
this license applies only to SCons, and not to any separate
|
|
||||||
software you've written with which you're planning to package
|
|
||||||
SCons.
|
|
||||||
|
|
||||||
scons-README
|
This will install the build engine in the standard Python library
|
||||||
What you're looking at right now.
|
directory (/usr/lib/python*/site-packages or
|
||||||
|
C:\Python*\Lib\site-packages).
|
||||||
|
|
||||||
scons-local-{version}/
|
Alternatively, you can have SCons install its build engine library in a
|
||||||
The SCons build engine. This is structured as a Python
|
hard-coded standalone library directory, instead of the default
|
||||||
library.
|
version-numbered directory, by specifying the "--standalone-lib" option
|
||||||
|
on the command line, as follows:
|
||||||
|
|
||||||
scons.py
|
# python setup.py install --standalone-lib
|
||||||
The SCons script itself. The script sets up the Python
|
|
||||||
sys.path variable to use the build engine found in the
|
This is usually not recommended, however.
|
||||||
scons-local-{version}/ directory in preference to any other
|
|
||||||
SCons build engine installed on your system.
|
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.
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION
|
DOCUMENTATION
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Because this package is intended to be included with other software by
|
See the RELEASE.txt file for notes about this specific release,
|
||||||
experienced users, we have not included any SCons documentation in this
|
including known problems. See the CHANGES.txt file for a list of
|
||||||
package (other than this scons-README file you're reading right now).
|
changes since the previous release.
|
||||||
|
|
||||||
If, however, you need documentation about SCons, then consult any of the
|
The scons.1 man page is included in this package, and contains a section
|
||||||
following from the corresponding scons-{version} or scons-src-{version}
|
of small examples for getting started using SCons.
|
||||||
package:
|
|
||||||
|
|
||||||
The RELEASE.txt file (src/RELEASE.txt file in the
|
|
||||||
scons-src-{version} package), which contains notes about this
|
|
||||||
specific release, including known problems.
|
|
||||||
|
|
||||||
The CHANGES.txt file (src/CHANGES.txt file in the
|
|
||||||
scons-src-{version} package), which contains a list of changes
|
|
||||||
since the previous release.
|
|
||||||
|
|
||||||
The scons.1 man page (doc/man/scons.1 in the scons-src-{version}
|
|
||||||
package), which contains a section of small examples for getting
|
|
||||||
started using SCons.
|
|
||||||
|
|
||||||
Additional documentation for SCons is available at:
|
Additional documentation for SCons is available at:
|
||||||
|
|
||||||
|
@ -142,8 +184,8 @@ LICENSING
|
||||||
=========
|
=========
|
||||||
|
|
||||||
SCons is distributed under the MIT license, a full copy of which is
|
SCons is distributed under the MIT license, a full copy of which is
|
||||||
available in the scons-LICENSE file in this package. The MIT license is
|
available in the LICENSE.txt file. The MIT license is an approved Open
|
||||||
an approved Open Source license, which means:
|
Source license, which means:
|
||||||
|
|
||||||
This software is OSI Certified Open Source Software. OSI
|
This software is OSI Certified Open Source Software. OSI
|
||||||
Certified is a certification mark of the Open Source Initiative.
|
Certified is a certification mark of the Open Source Initiative.
|
||||||
|
@ -157,27 +199,51 @@ available at:
|
||||||
REPORTING BUGS
|
REPORTING BUGS
|
||||||
==============
|
==============
|
||||||
|
|
||||||
You can report bugs either by following the "Tracker - Bugs" link
|
Please report bugs by following the detailed instructions on our Bug
|
||||||
on the SCons project page:
|
Submission page:
|
||||||
|
|
||||||
http://sourceforge.net/projects/scons/
|
http://scons.tigris.org/bug-submission.html
|
||||||
|
|
||||||
or by sending mail to the SCons developers mailing list:
|
You can also send mail to the SCons developers' mailing list:
|
||||||
|
|
||||||
scons-devel@lists.sourceforge.net
|
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.
|
||||||
|
|
||||||
|
|
||||||
MAILING LISTS
|
MAILING LISTS
|
||||||
=============
|
=============
|
||||||
|
|
||||||
A mailing list for users of SCons is available. You may send questions
|
An active mailing list for users of SCons is available. You may send
|
||||||
or comments to the list at:
|
questions or comments to the list at:
|
||||||
|
|
||||||
scons-users@lists.sourceforge.net
|
users@scons.tigris.org
|
||||||
|
|
||||||
You may subscribe to the scons-users mailing list at:
|
You may subscribe to the mailing list by sending email to:
|
||||||
|
|
||||||
http://lists.sourceforge.net/lists/listinfo/scons-users
|
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
|
||||||
|
|
||||||
|
|
||||||
FOR MORE INFORMATION
|
FOR MORE INFORMATION
|
||||||
|
@ -199,6 +265,9 @@ With plenty of help from the SCons Development team:
|
||||||
Chad Austin
|
Chad Austin
|
||||||
Charles Crain
|
Charles Crain
|
||||||
Steve Leblanc
|
Steve Leblanc
|
||||||
|
Greg Noel
|
||||||
|
Gary Oberbrunner
|
||||||
Anthony Roach
|
Anthony Roach
|
||||||
Terrel Shumway
|
Greg Spencer
|
||||||
|
Christoph Wiedemann
|
||||||
|
|
||||||
|
|
|
@ -1,642 +0,0 @@
|
||||||
"""SCons.Action
|
|
||||||
|
|
||||||
This encapsulates information about executing any sort of action that
|
|
||||||
can build one or more target Nodes (typically files) from one or more
|
|
||||||
source Nodes (also typically files) given a specific Environment.
|
|
||||||
|
|
||||||
The base class here is ActionBase. The base class supplies just a few
|
|
||||||
OO utility methods and some generic methods for displaying information
|
|
||||||
about an Action in response to the various commands that control printing.
|
|
||||||
|
|
||||||
The heavy lifting is handled by subclasses for the different types of
|
|
||||||
actions we might execute:
|
|
||||||
|
|
||||||
CommandAction
|
|
||||||
CommandGeneratorAction
|
|
||||||
FunctionAction
|
|
||||||
ListAction
|
|
||||||
|
|
||||||
The subclasses supply the following public interface methods used by
|
|
||||||
other modules:
|
|
||||||
|
|
||||||
__call__()
|
|
||||||
THE public interface, "calling" an Action object executes the
|
|
||||||
command or Python function. This also takes care of printing
|
|
||||||
a pre-substitution command for debugging purposes.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
genstring()
|
|
||||||
Returns a string representation of the Action *without* command
|
|
||||||
substitution, but allows a CommandGeneratorAction to generate
|
|
||||||
the right action based on the specified target, source and env.
|
|
||||||
This is used by the Signature subsystem (through the Executor)
|
|
||||||
to compare the actions used to build a target last time and
|
|
||||||
this time.
|
|
||||||
|
|
||||||
Subclasses also supply the following methods for internal use within
|
|
||||||
this module:
|
|
||||||
|
|
||||||
__str__()
|
|
||||||
Returns a string representation of the Action *without* command
|
|
||||||
substitution. This is used by the __call__() methods to display
|
|
||||||
the pre-substitution command whenever the --debug=presub option
|
|
||||||
is used.
|
|
||||||
|
|
||||||
strfunction()
|
|
||||||
Returns a substituted string representation of the Action.
|
|
||||||
This is used by the ActionBase.show() command to display the
|
|
||||||
command/function that will be executed to generate the target(s).
|
|
||||||
|
|
||||||
execute()
|
|
||||||
The internal method that really, truly, actually handles the
|
|
||||||
execution of a command or Python function. This is used so
|
|
||||||
that the __call__() methods can take care of displaying any
|
|
||||||
pre-substitution representations, and *then* execute an action
|
|
||||||
without worrying about the specific Actions involved.
|
|
||||||
|
|
||||||
There is a related independent ActionCaller class that looks like a
|
|
||||||
regular Action, and which serves as a wrapper for arbitrary functions
|
|
||||||
that we want to let the user specify the arguments to now, but actually
|
|
||||||
execute later (when an out-of-date check determines that it's needed to
|
|
||||||
be executed, for example). Objects of this class are returned by an
|
|
||||||
ActionFactory class that provides a __call__() method as a convenient
|
|
||||||
way for wrapping up the functions.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 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/engine/SCons/Action.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from SCons.Debug import logInstanceCreation
|
|
||||||
import SCons.Errors
|
|
||||||
import SCons.Util
|
|
||||||
|
|
||||||
class _Null:
|
|
||||||
pass
|
|
||||||
|
|
||||||
_null = _Null
|
|
||||||
|
|
||||||
print_actions = 1
|
|
||||||
execute_actions = 1
|
|
||||||
print_actions_presub = 0
|
|
||||||
|
|
||||||
default_ENV = None
|
|
||||||
|
|
||||||
def rfile(n):
|
|
||||||
try:
|
|
||||||
return n.rfile()
|
|
||||||
except AttributeError:
|
|
||||||
return n
|
|
||||||
|
|
||||||
def _actionAppend(act1, act2):
|
|
||||||
# This function knows how to slap two actions together.
|
|
||||||
# Mainly, it handles ListActions by concatenating into
|
|
||||||
# a single ListAction.
|
|
||||||
a1 = Action(act1)
|
|
||||||
a2 = Action(act2)
|
|
||||||
if a1 is None or a2 is None:
|
|
||||||
raise TypeError, "Cannot append %s to %s" % (type(act1), type(act2))
|
|
||||||
if isinstance(a1, ListAction):
|
|
||||||
if isinstance(a2, ListAction):
|
|
||||||
return ListAction(a1.list + a2.list)
|
|
||||||
else:
|
|
||||||
return ListAction(a1.list + [ a2 ])
|
|
||||||
else:
|
|
||||||
if isinstance(a2, ListAction):
|
|
||||||
return ListAction([ a1 ] + a2.list)
|
|
||||||
else:
|
|
||||||
return ListAction([ a1, a2 ])
|
|
||||||
|
|
||||||
class CommandGenerator:
|
|
||||||
"""
|
|
||||||
Wraps a command generator function so the Action() factory
|
|
||||||
function can tell a generator function from a function action.
|
|
||||||
"""
|
|
||||||
def __init__(self, generator):
|
|
||||||
self.generator = generator
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
return _actionAppend(self, other)
|
|
||||||
|
|
||||||
def __radd__(self, other):
|
|
||||||
return _actionAppend(other, self)
|
|
||||||
|
|
||||||
def _do_create_action(act, *args, **kw):
|
|
||||||
"""This is the actual "implementation" for the
|
|
||||||
Action factory method, below. This handles the
|
|
||||||
fact that passing lists to Action() itself has
|
|
||||||
different semantics than passing lists as elements
|
|
||||||
of lists.
|
|
||||||
|
|
||||||
The former will create a ListAction, the latter
|
|
||||||
will create a CommandAction by converting the inner
|
|
||||||
list elements to strings."""
|
|
||||||
|
|
||||||
if isinstance(act, ActionBase):
|
|
||||||
return act
|
|
||||||
if SCons.Util.is_List(act):
|
|
||||||
return apply(CommandAction, (act,)+args, kw)
|
|
||||||
if isinstance(act, CommandGenerator):
|
|
||||||
return apply(CommandGeneratorAction, (act.generator,)+args, kw)
|
|
||||||
if callable(act):
|
|
||||||
return apply(FunctionAction, (act,)+args, kw)
|
|
||||||
if SCons.Util.is_String(act):
|
|
||||||
var=SCons.Util.get_environment_var(act)
|
|
||||||
if var:
|
|
||||||
# This looks like a string that is purely an Environment
|
|
||||||
# variable reference, like "$FOO" or "${FOO}". We do
|
|
||||||
# something special here...we lazily evaluate the contents
|
|
||||||
# of that Environment variable, so a user could put something
|
|
||||||
# like a function or a CommandGenerator in that variable
|
|
||||||
# instead of a string.
|
|
||||||
lcg = LazyCmdGenerator(var)
|
|
||||||
return apply(CommandGeneratorAction, (lcg,)+args, kw)
|
|
||||||
commands = string.split(str(act), '\n')
|
|
||||||
if len(commands) == 1:
|
|
||||||
return apply(CommandAction, (commands[0],)+args, kw)
|
|
||||||
else:
|
|
||||||
listCmdActions = map(lambda x: CommandAction(x), commands)
|
|
||||||
return apply(ListAction, (listCmdActions,)+args, kw)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def Action(act, strfunction=_null, varlist=[], presub=_null):
|
|
||||||
"""A factory for action objects."""
|
|
||||||
if SCons.Util.is_List(act):
|
|
||||||
acts = map(lambda x, s=strfunction, v=varlist, ps=presub:
|
|
||||||
_do_create_action(x, strfunction=s, varlist=v, presub=ps),
|
|
||||||
act)
|
|
||||||
acts = filter(lambda x: not x is None, acts)
|
|
||||||
if len(acts) == 1:
|
|
||||||
return acts[0]
|
|
||||||
else:
|
|
||||||
return ListAction(acts, strfunction=strfunction, varlist=varlist, presub=presub)
|
|
||||||
else:
|
|
||||||
return _do_create_action(act, strfunction=strfunction, varlist=varlist, presub=presub)
|
|
||||||
|
|
||||||
class ActionBase:
|
|
||||||
"""Base class for actions that create output objects."""
|
|
||||||
def __init__(self, strfunction=_null, presub=_null, **kw):
|
|
||||||
if not strfunction is _null:
|
|
||||||
self.strfunction = strfunction
|
|
||||||
if presub is _null:
|
|
||||||
self.presub = print_actions_presub
|
|
||||||
else:
|
|
||||||
self.presub = presub
|
|
||||||
|
|
||||||
def __cmp__(self, other):
|
|
||||||
return cmp(self.__dict__, other.__dict__)
|
|
||||||
|
|
||||||
def __call__(self, target, source, env,
|
|
||||||
errfunc=None,
|
|
||||||
presub=_null,
|
|
||||||
show=_null,
|
|
||||||
execute=_null):
|
|
||||||
if not SCons.Util.is_List(target):
|
|
||||||
target = [target]
|
|
||||||
if not SCons.Util.is_List(source):
|
|
||||||
source = [source]
|
|
||||||
if presub is _null: presub = self.presub
|
|
||||||
if show is _null: show = print_actions
|
|
||||||
if execute is _null: execute = execute_actions
|
|
||||||
if presub:
|
|
||||||
t = string.join(map(str, target), 'and')
|
|
||||||
l = string.join(self.presub_lines(env), '\n ')
|
|
||||||
out = "Building %s with action(s):\n %s\n" % (t, l)
|
|
||||||
sys.stdout.write(out)
|
|
||||||
if show and self.strfunction:
|
|
||||||
s = self.strfunction(target, source, env)
|
|
||||||
if s:
|
|
||||||
sys.stdout.write(s + '\n')
|
|
||||||
if execute:
|
|
||||||
stat = self.execute(target, source, env)
|
|
||||||
if stat and errfunc:
|
|
||||||
errfunc(stat)
|
|
||||||
return stat
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def presub_lines(self, env):
|
|
||||||
# CommandGeneratorAction needs a real environment
|
|
||||||
# in order to return the proper string here, since
|
|
||||||
# it may call LazyCmdGenerator, which looks up a key
|
|
||||||
# in that env. So we temporarily remember the env here,
|
|
||||||
# and CommandGeneratorAction will use this env
|
|
||||||
# when it calls its __generate method.
|
|
||||||
self.presub_env = env
|
|
||||||
lines = string.split(str(self), '\n')
|
|
||||||
self.presub_env = None # don't need this any more
|
|
||||||
return lines
|
|
||||||
|
|
||||||
def genstring(self, target, source, env):
|
|
||||||
return str(self)
|
|
||||||
|
|
||||||
def get_actions(self):
|
|
||||||
return [self]
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
return _actionAppend(self, other)
|
|
||||||
|
|
||||||
def __radd__(self, other):
|
|
||||||
return _actionAppend(other, self)
|
|
||||||
|
|
||||||
def _string_from_cmd_list(cmd_list):
|
|
||||||
"""Takes a list of command line arguments and returns a pretty
|
|
||||||
representation for printing."""
|
|
||||||
cl = []
|
|
||||||
for arg in map(str, cmd_list):
|
|
||||||
if ' ' in arg or '\t' in arg:
|
|
||||||
arg = '"' + arg + '"'
|
|
||||||
cl.append(arg)
|
|
||||||
return string.join(cl)
|
|
||||||
|
|
||||||
class CommandAction(ActionBase):
|
|
||||||
"""Class for command-execution actions."""
|
|
||||||
def __init__(self, cmd, **kw):
|
|
||||||
# Cmd list can actually be a list or a single item...basically
|
|
||||||
# anything that we could pass in as the first arg to
|
|
||||||
# Environment.subst_list().
|
|
||||||
if __debug__: logInstanceCreation(self)
|
|
||||||
apply(ActionBase.__init__, (self,), kw)
|
|
||||||
self.cmd_list = cmd
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.cmd_list)
|
|
||||||
|
|
||||||
def strfunction(self, target, source, env):
|
|
||||||
cmd_list = env.subst_list(self.cmd_list, 0, target, source)
|
|
||||||
return string.join(map(_string_from_cmd_list, cmd_list), "\n")
|
|
||||||
|
|
||||||
def execute(self, target, source, env):
|
|
||||||
"""Execute a command action.
|
|
||||||
|
|
||||||
This will handle lists of commands as well as individual commands,
|
|
||||||
because construction variable substitution may turn a single
|
|
||||||
"command" into a list. This means that this class can actually
|
|
||||||
handle lists of commands, even though that's not how we use it
|
|
||||||
externally.
|
|
||||||
"""
|
|
||||||
import SCons.Util
|
|
||||||
|
|
||||||
escape = env.get('ESCAPE', lambda x: x)
|
|
||||||
|
|
||||||
if env.has_key('SHELL'):
|
|
||||||
shell = env['SHELL']
|
|
||||||
else:
|
|
||||||
raise SCons.Errors.UserError('Missing SHELL construction variable.')
|
|
||||||
|
|
||||||
# for SConf support (by now): check, if we want to pipe the command
|
|
||||||
# output to somewhere else
|
|
||||||
if env.has_key('PIPE_BUILD'):
|
|
||||||
pipe_build = 1
|
|
||||||
if env.has_key('PSPAWN'):
|
|
||||||
pspawn = env['PSPAWN']
|
|
||||||
else:
|
|
||||||
raise SCons.Errors.UserError('Missing PSPAWN construction variable.')
|
|
||||||
if env.has_key('PSTDOUT'):
|
|
||||||
pstdout = env['PSTDOUT']
|
|
||||||
else:
|
|
||||||
raise SCons.Errors.UserError('Missing PSTDOUT construction variable.')
|
|
||||||
if env.has_key('PSTDERR'):
|
|
||||||
pstderr = env['PSTDERR']
|
|
||||||
else:
|
|
||||||
raise SCons.Errors.UserError('Missing PSTDOUT construction variable.')
|
|
||||||
else:
|
|
||||||
pipe_build = 0
|
|
||||||
if env.has_key('SPAWN'):
|
|
||||||
spawn = env['SPAWN']
|
|
||||||
else:
|
|
||||||
raise SCons.Errors.UserError('Missing SPAWN construction variable.')
|
|
||||||
|
|
||||||
cmd_list = env.subst_list(self.cmd_list, 0, target, source)
|
|
||||||
for cmd_line in cmd_list:
|
|
||||||
if len(cmd_line):
|
|
||||||
try:
|
|
||||||
ENV = env['ENV']
|
|
||||||
except KeyError:
|
|
||||||
global default_ENV
|
|
||||||
if not default_ENV:
|
|
||||||
import SCons.Environment
|
|
||||||
default_ENV = SCons.Environment.Environment()['ENV']
|
|
||||||
ENV = default_ENV
|
|
||||||
|
|
||||||
# ensure that the ENV values are all strings:
|
|
||||||
for key, value in ENV.items():
|
|
||||||
if SCons.Util.is_List(value):
|
|
||||||
# If the value is a list, then we assume
|
|
||||||
# it is a path list, because that's a pretty
|
|
||||||
# common list like value to stick in an environment
|
|
||||||
# variable:
|
|
||||||
value = SCons.Util.flatten(value)
|
|
||||||
ENV[key] = string.join(map(str, value), os.pathsep)
|
|
||||||
elif not SCons.Util.is_String(value):
|
|
||||||
# If it isn't a string or a list, then
|
|
||||||
# we just coerce it to a string, which
|
|
||||||
# is proper way to handle Dir and File instances
|
|
||||||
# and will produce something reasonable for
|
|
||||||
# just about everything else:
|
|
||||||
ENV[key] = str(value)
|
|
||||||
|
|
||||||
# Escape the command line for the command
|
|
||||||
# interpreter we are using
|
|
||||||
cmd_line = SCons.Util.escape_list(cmd_line, escape)
|
|
||||||
if pipe_build:
|
|
||||||
ret = pspawn( shell, escape, cmd_line[0], cmd_line,
|
|
||||||
ENV, pstdout, pstderr )
|
|
||||||
else:
|
|
||||||
ret = spawn(shell, escape, cmd_line[0], cmd_line, ENV)
|
|
||||||
if ret:
|
|
||||||
return ret
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def get_contents(self, target, source, env, dict=None):
|
|
||||||
"""Return the signature contents of this action's command line.
|
|
||||||
|
|
||||||
This strips $(-$) and everything in between the string,
|
|
||||||
since those parts don't affect signatures.
|
|
||||||
"""
|
|
||||||
cmd = self.cmd_list
|
|
||||||
if SCons.Util.is_List(cmd):
|
|
||||||
cmd = string.join(map(str, cmd))
|
|
||||||
else:
|
|
||||||
cmd = str(cmd)
|
|
||||||
return env.subst_target_source(cmd, SCons.Util.SUBST_SIG, target, source, dict)
|
|
||||||
|
|
||||||
class CommandGeneratorAction(ActionBase):
|
|
||||||
"""Class for command-generator actions."""
|
|
||||||
def __init__(self, generator, **kw):
|
|
||||||
if __debug__: logInstanceCreation(self)
|
|
||||||
apply(ActionBase.__init__, (self,), kw)
|
|
||||||
self.generator = generator
|
|
||||||
|
|
||||||
def __generate(self, target, source, env, for_signature):
|
|
||||||
# ensure that target is a list, to make it easier to write
|
|
||||||
# generator functions:
|
|
||||||
if not SCons.Util.is_List(target):
|
|
||||||
target = [target]
|
|
||||||
|
|
||||||
ret = self.generator(target=target, source=source, env=env, for_signature=for_signature)
|
|
||||||
gen_cmd = Action(ret)
|
|
||||||
if not gen_cmd:
|
|
||||||
raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret))
|
|
||||||
return gen_cmd
|
|
||||||
|
|
||||||
def strfunction(self, target, source, env):
|
|
||||||
if not SCons.Util.is_List(source):
|
|
||||||
source = [source]
|
|
||||||
rsources = map(rfile, source)
|
|
||||||
act = self.__generate(target, source, env, 0)
|
|
||||||
if act.strfunction:
|
|
||||||
return act.strfunction(target, rsources, env)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
try:
|
|
||||||
env = self.presub_env or {}
|
|
||||||
except AttributeError:
|
|
||||||
env = {}
|
|
||||||
act = self.__generate([], [], env, 0)
|
|
||||||
return str(act)
|
|
||||||
|
|
||||||
def genstring(self, target, source, env):
|
|
||||||
return str(self.__generate(target, source, env, 0))
|
|
||||||
|
|
||||||
def execute(self, target, source, env):
|
|
||||||
rsources = map(rfile, source)
|
|
||||||
act = self.__generate(target, source, env, 0)
|
|
||||||
return act.execute(target, source, env)
|
|
||||||
|
|
||||||
def get_contents(self, target, source, env, dict=None):
|
|
||||||
"""Return the signature contents of this action's command line.
|
|
||||||
|
|
||||||
This strips $(-$) and everything in between the string,
|
|
||||||
since those parts don't affect signatures.
|
|
||||||
"""
|
|
||||||
return self.__generate(target, source, env, 1).get_contents(target, source, env, dict=None)
|
|
||||||
|
|
||||||
class LazyCmdGenerator:
|
|
||||||
"""This is not really an Action, although it kind of looks like one.
|
|
||||||
This is really a simple callable class that acts as a command
|
|
||||||
generator. It holds on to a key into an Environment dictionary,
|
|
||||||
then waits until execution time to see what type it is, then tries
|
|
||||||
to create an Action out of it."""
|
|
||||||
def __init__(self, var):
|
|
||||||
if __debug__: logInstanceCreation(self)
|
|
||||||
self.var = SCons.Util.to_String(var)
|
|
||||||
|
|
||||||
def strfunction(self, target, source, env):
|
|
||||||
try:
|
|
||||||
return env[self.var]
|
|
||||||
except KeyError:
|
|
||||||
# The variable reference substitutes to nothing.
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return 'LazyCmdGenerator: %s'%str(self.var)
|
|
||||||
|
|
||||||
def __call__(self, target, source, env, for_signature):
|
|
||||||
try:
|
|
||||||
return env[self.var]
|
|
||||||
except KeyError:
|
|
||||||
# The variable reference substitutes to nothing.
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def __cmp__(self, other):
|
|
||||||
return cmp(self.__dict__, other.__dict__)
|
|
||||||
|
|
||||||
class FunctionAction(ActionBase):
|
|
||||||
"""Class for Python function actions."""
|
|
||||||
|
|
||||||
def __init__(self, execfunction, **kw):
|
|
||||||
if __debug__: logInstanceCreation(self)
|
|
||||||
self.execfunction = execfunction
|
|
||||||
apply(ActionBase.__init__, (self,), kw)
|
|
||||||
self.varlist = kw.get('varlist', [])
|
|
||||||
|
|
||||||
def function_name(self):
|
|
||||||
try:
|
|
||||||
return self.execfunction.__name__
|
|
||||||
except AttributeError:
|
|
||||||
try:
|
|
||||||
return self.execfunction.__class__.__name__
|
|
||||||
except AttributeError:
|
|
||||||
return "unknown_python_function"
|
|
||||||
|
|
||||||
def strfunction(self, target, source, env):
|
|
||||||
def array(a):
|
|
||||||
def quote(s):
|
|
||||||
return '"' + str(s) + '"'
|
|
||||||
return '[' + string.join(map(quote, a), ", ") + ']'
|
|
||||||
name = self.function_name()
|
|
||||||
tstr = array(target)
|
|
||||||
sstr = array(source)
|
|
||||||
return "%s(%s, %s)" % (name, tstr, sstr)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "%s(env, target, source)" % self.function_name()
|
|
||||||
|
|
||||||
def execute(self, target, source, env):
|
|
||||||
rsources = map(rfile, source)
|
|
||||||
return self.execfunction(target=target, source=rsources, env=env)
|
|
||||||
|
|
||||||
def get_contents(self, target, source, env, dict=None):
|
|
||||||
"""Return the signature contents of this callable action.
|
|
||||||
|
|
||||||
By providing direct access to the code object of the
|
|
||||||
function, Python makes this extremely easy. Hooray!
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# "self.execfunction" is a function.
|
|
||||||
contents = str(self.execfunction.func_code.co_code)
|
|
||||||
except AttributeError:
|
|
||||||
# "self.execfunction" is a callable object.
|
|
||||||
try:
|
|
||||||
contents = str(self.execfunction.__call__.im_func.func_code.co_code)
|
|
||||||
except AttributeError:
|
|
||||||
try:
|
|
||||||
# See if execfunction will do the heavy lifting for us.
|
|
||||||
gc = self.execfunction.get_contents
|
|
||||||
except AttributeError:
|
|
||||||
# This is weird, just do the best we can.
|
|
||||||
contents = str(self.execfunction)
|
|
||||||
else:
|
|
||||||
contents = gc(target, source, env, dict)
|
|
||||||
return contents + env.subst(string.join(map(lambda v: '${'+v+'}',
|
|
||||||
self.varlist)))
|
|
||||||
|
|
||||||
class ListAction(ActionBase):
|
|
||||||
"""Class for lists of other actions."""
|
|
||||||
def __init__(self, list, **kw):
|
|
||||||
if __debug__: logInstanceCreation(self)
|
|
||||||
apply(ActionBase.__init__, (self,), kw)
|
|
||||||
self.list = map(lambda x: Action(x), list)
|
|
||||||
|
|
||||||
def get_actions(self):
|
|
||||||
return self.list
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
s = []
|
|
||||||
for l in self.list:
|
|
||||||
s.append(str(l))
|
|
||||||
return string.join(s, "\n")
|
|
||||||
|
|
||||||
def strfunction(self, target, source, env):
|
|
||||||
s = []
|
|
||||||
for l in self.list:
|
|
||||||
if l.strfunction:
|
|
||||||
x = l.strfunction(target, source, env)
|
|
||||||
if not SCons.Util.is_List(x):
|
|
||||||
x = [x]
|
|
||||||
s.extend(x)
|
|
||||||
return string.join(s, "\n")
|
|
||||||
|
|
||||||
def execute(self, target, source, env):
|
|
||||||
for l in self.list:
|
|
||||||
r = l.execute(target, source, env)
|
|
||||||
if r:
|
|
||||||
return r
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def get_contents(self, target, source, env, dict=None):
|
|
||||||
"""Return the signature contents of this action list.
|
|
||||||
|
|
||||||
Simple concatenation of the signatures of the elements.
|
|
||||||
"""
|
|
||||||
dict = SCons.Util.subst_dict(target, source)
|
|
||||||
return string.join(map(lambda x, t=target, s=source, e=env, d=dict:
|
|
||||||
x.get_contents(t, s, e, d),
|
|
||||||
self.list),
|
|
||||||
"")
|
|
||||||
|
|
||||||
class ActionCaller:
|
|
||||||
"""A class for delaying calling an Action function with specific
|
|
||||||
(positional and keyword) arguments until the Action is actually
|
|
||||||
executed.
|
|
||||||
|
|
||||||
This class looks to the rest of the world like a normal Action object,
|
|
||||||
but what it's really doing is hanging on to the arguments until we
|
|
||||||
have a target, source and env to use for the expansion.
|
|
||||||
"""
|
|
||||||
def __init__(self, parent, args, kw):
|
|
||||||
self.parent = parent
|
|
||||||
self.args = args
|
|
||||||
self.kw = kw
|
|
||||||
def get_contents(self, target, source, env, dict=None):
|
|
||||||
actfunc = self.parent.actfunc
|
|
||||||
try:
|
|
||||||
# "self.actfunc" is a function.
|
|
||||||
contents = str(actfunc.func_code.co_code)
|
|
||||||
except AttributeError:
|
|
||||||
# "self.actfunc" is a callable object.
|
|
||||||
try:
|
|
||||||
contents = str(actfunc.__call__.im_func.func_code.co_code)
|
|
||||||
except AttributeError:
|
|
||||||
# No __call__() method, so it might be a builtin
|
|
||||||
# or something like that. Do the best we can.
|
|
||||||
contents = str(actfunc)
|
|
||||||
return contents
|
|
||||||
def subst_args(self, target, source, env):
|
|
||||||
return map(lambda x, e=env, t=target, s=source:
|
|
||||||
e.subst(x, 0, t, s),
|
|
||||||
self.args)
|
|
||||||
def subst_kw(self, target, source, env):
|
|
||||||
kw = {}
|
|
||||||
for key in self.kw.keys():
|
|
||||||
kw[key] = env.subst(self.kw[key], 0, target, source)
|
|
||||||
return kw
|
|
||||||
def __call__(self, target, source, env):
|
|
||||||
args = self.subst_args(target, source, env)
|
|
||||||
kw = self.subst_kw(target, source, env)
|
|
||||||
return apply(self.parent.actfunc, args, kw)
|
|
||||||
def strfunction(self, target, source, env):
|
|
||||||
args = self.subst_args(target, source, env)
|
|
||||||
kw = self.subst_kw(target, source, env)
|
|
||||||
return apply(self.parent.strfunc, args, kw)
|
|
||||||
|
|
||||||
class ActionFactory:
|
|
||||||
"""A factory class that will wrap up an arbitrary function
|
|
||||||
as an SCons-executable Action object.
|
|
||||||
|
|
||||||
The real heavy lifting here is done by the ActionCaller class.
|
|
||||||
We just collect the (positional and keyword) arguments that we're
|
|
||||||
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):
|
|
||||||
self.actfunc = actfunc
|
|
||||||
self.strfunc = strfunc
|
|
||||||
def __call__(self, *args, **kw):
|
|
||||||
ac = ActionCaller(self, args, kw)
|
|
||||||
return Action(ac, strfunction=ac.strfunction)
|
|
|
@ -1,356 +0,0 @@
|
||||||
"""SCons.Defaults
|
|
||||||
|
|
||||||
Builders and other things for the local site. Here's where we'll
|
|
||||||
duplicate the functionality of autoconf until we move it into the
|
|
||||||
installation procedure or use something like qmconf.
|
|
||||||
|
|
||||||
The code that reads the registry to find MSVC components was borrowed
|
|
||||||
from distutils.msvccompiler.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 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/branch.96/baseline/src/engine/SCons/Defaults.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import shutil
|
|
||||||
import stat
|
|
||||||
import string
|
|
||||||
import time
|
|
||||||
import types
|
|
||||||
|
|
||||||
import SCons.Action
|
|
||||||
import SCons.Builder
|
|
||||||
import SCons.Environment
|
|
||||||
import SCons.Scanner.C
|
|
||||||
import SCons.Scanner.D
|
|
||||||
import SCons.Scanner.Prog
|
|
||||||
import SCons.Sig
|
|
||||||
|
|
||||||
# A placeholder for a default Environment (for fetching source files
|
|
||||||
# from source code management systems and the like). This must be
|
|
||||||
# initialized later, after the top-level directory is set by the calling
|
|
||||||
# interface.
|
|
||||||
_default_env = None
|
|
||||||
|
|
||||||
# Lazily instantiate the default environment so the overhead of creating
|
|
||||||
# it doesn't apply when it's not needed.
|
|
||||||
def DefaultEnvironment(*args, **kw):
|
|
||||||
global _default_env
|
|
||||||
if not _default_env:
|
|
||||||
_default_env = apply(SCons.Environment.Environment, args, kw)
|
|
||||||
_default_env._build_signature = 1
|
|
||||||
_default_env._calc_module = SCons.Sig.default_module
|
|
||||||
return _default_env
|
|
||||||
|
|
||||||
# Emitters for setting the shared attribute on object files,
|
|
||||||
# and an action for checking that all of the source files
|
|
||||||
# going into a shared library are, in fact, shared.
|
|
||||||
def StaticObjectEmitter(target, source, env):
|
|
||||||
for tgt in target:
|
|
||||||
tgt.attributes.shared = None
|
|
||||||
return (target, source)
|
|
||||||
|
|
||||||
def SharedObjectEmitter(target, source, env):
|
|
||||||
for tgt in target:
|
|
||||||
tgt.attributes.shared = 1
|
|
||||||
return (target, source)
|
|
||||||
|
|
||||||
def SharedFlagChecker(source, target, env):
|
|
||||||
same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME')
|
|
||||||
if same == '0' or same == '' or same == 'False':
|
|
||||||
for src in source:
|
|
||||||
try:
|
|
||||||
shared = src.attributes.shared
|
|
||||||
except AttributeError:
|
|
||||||
shared = None
|
|
||||||
if not shared:
|
|
||||||
raise SCons.Errors.UserError, "Source file: %s is static and is not compatible with shared target: %s" % (src, target[0])
|
|
||||||
|
|
||||||
SharedCheck = SCons.Action.Action(SharedFlagChecker, None)
|
|
||||||
|
|
||||||
# Scanners and suffixes for common languages.
|
|
||||||
ObjSourceScan = SCons.Scanner.Scanner({})
|
|
||||||
|
|
||||||
CScan = SCons.Scanner.C.CScan()
|
|
||||||
|
|
||||||
CSuffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc",
|
|
||||||
".h", ".H", ".hxx", ".hpp", ".hh",
|
|
||||||
".F", ".fpp", ".FPP",
|
|
||||||
".S", ".spp", ".SPP"]
|
|
||||||
|
|
||||||
for suffix in CSuffixes:
|
|
||||||
ObjSourceScan.add_scanner(suffix, CScan)
|
|
||||||
|
|
||||||
DScan = SCons.Scanner.D.DScan()
|
|
||||||
|
|
||||||
DSuffixes = ['.d']
|
|
||||||
|
|
||||||
for suffix in DSuffixes:
|
|
||||||
ObjSourceScan.add_scanner(suffix, DScan)
|
|
||||||
|
|
||||||
IDLSuffixes = [".idl", ".IDL"]
|
|
||||||
|
|
||||||
# cleanup
|
|
||||||
del suffix
|
|
||||||
|
|
||||||
# Actions for common languages.
|
|
||||||
CAction = SCons.Action.Action("$CCCOM")
|
|
||||||
DAction = SCons.Action.Action("$DCOM")
|
|
||||||
ShCAction = SCons.Action.Action("$SHCCCOM")
|
|
||||||
CXXAction = SCons.Action.Action("$CXXCOM")
|
|
||||||
ShCXXAction = SCons.Action.Action("$SHCXXCOM")
|
|
||||||
|
|
||||||
ASAction = SCons.Action.Action("$ASCOM")
|
|
||||||
ASPPAction = SCons.Action.Action("$ASPPCOM")
|
|
||||||
|
|
||||||
LinkAction = SCons.Action.Action("$LINKCOM")
|
|
||||||
ShLinkAction = SCons.Action.Action("$SHLINKCOM")
|
|
||||||
|
|
||||||
ArAction = SCons.Action.Action("$ARCOM")
|
|
||||||
|
|
||||||
LexAction = SCons.Action.Action("$LEXCOM")
|
|
||||||
YaccAction = SCons.Action.Action("$YACCCOM")
|
|
||||||
|
|
||||||
ProgScan = SCons.Scanner.Prog.ProgScan()
|
|
||||||
|
|
||||||
def DVI():
|
|
||||||
"""Common function to generate a DVI file Builder."""
|
|
||||||
return SCons.Builder.Builder(action = {},
|
|
||||||
# The suffix is not configurable via a
|
|
||||||
# construction variable like $DVISUFFIX
|
|
||||||
# because the output file name is
|
|
||||||
# hard-coded within TeX.
|
|
||||||
suffix = '.dvi')
|
|
||||||
|
|
||||||
def PDF():
|
|
||||||
"""A function for generating the PDF Builder."""
|
|
||||||
return SCons.Builder.Builder(action = { },
|
|
||||||
prefix = '$PDFPREFIX',
|
|
||||||
suffix = '$PDFSUFFIX')
|
|
||||||
|
|
||||||
# Common tasks that we allow users to perform in platform-independent
|
|
||||||
# ways by creating ActionFactory instances.
|
|
||||||
ActionFactory = SCons.Action.ActionFactory
|
|
||||||
|
|
||||||
Chmod = ActionFactory(os.chmod,
|
|
||||||
lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
|
|
||||||
|
|
||||||
def Copy(dest, src):
|
|
||||||
def _copy_func(target, source, env, dest=dest, src=src):
|
|
||||||
dest = str(env.arg2nodes(dest, env.fs.Entry)[0])
|
|
||||||
src = str(env.arg2nodes(src, env.fs.Entry)[0])
|
|
||||||
shutil.copytree(src, dest, 1)
|
|
||||||
def _copy_str(target, source, env, dest=dest, src=src):
|
|
||||||
dest = str(env.arg2nodes(dest, env.fs.Entry)[0])
|
|
||||||
src = str(env.arg2nodes(src, env.fs.Entry)[0])
|
|
||||||
return 'Copy("%s", "%s")' % (dest, src)
|
|
||||||
return SCons.Action.Action(_copy_func, strfunction=_copy_str)
|
|
||||||
|
|
||||||
def copy_func(dest, src):
|
|
||||||
if 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))
|
|
||||||
|
|
||||||
def delete_func(entry, must_exist=0):
|
|
||||||
if not must_exist and not os.path.exists(entry):
|
|
||||||
return None
|
|
||||||
if os.path.isfile(entry):
|
|
||||||
return os.unlink(entry)
|
|
||||||
else:
|
|
||||||
return shutil.rmtree(entry, 1)
|
|
||||||
|
|
||||||
def delete_strfunc(entry, must_exist=0):
|
|
||||||
return 'Delete("%s")' % entry
|
|
||||||
|
|
||||||
Delete = ActionFactory(delete_func, delete_strfunc)
|
|
||||||
|
|
||||||
Mkdir = ActionFactory(os.makedirs,
|
|
||||||
lambda dir: 'Mkdir("%s")' % dir)
|
|
||||||
|
|
||||||
Move = ActionFactory(lambda dest, src: os.rename(src, dest),
|
|
||||||
lambda dest, src: 'Move("%s", "%s")' % (dest, src))
|
|
||||||
|
|
||||||
def touch_func(file):
|
|
||||||
mtime = int(time.time())
|
|
||||||
if os.path.exists(file):
|
|
||||||
atime = os.path.getatime(file)
|
|
||||||
else:
|
|
||||||
open(file, 'w')
|
|
||||||
atime = mtime
|
|
||||||
return os.utime(file, (atime, mtime))
|
|
||||||
|
|
||||||
Touch = ActionFactory(touch_func,
|
|
||||||
lambda file: 'Touch("%s")' % file)
|
|
||||||
|
|
||||||
# Internal utility functions
|
|
||||||
def copyFunc(dest, source, env):
|
|
||||||
"""Install a source file into a destination by copying it (and its
|
|
||||||
permission/mode bits)."""
|
|
||||||
shutil.copy2(source, dest)
|
|
||||||
st = os.stat(source)
|
|
||||||
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def _concat(prefix, list, suffix, env, f=lambda x: x):
|
|
||||||
"""Creates a new list from 'list' by first interpolating each
|
|
||||||
element in the list using the 'env' dictionary and then calling f
|
|
||||||
on the list, and finally concatenating 'prefix' and 'suffix' onto
|
|
||||||
each element of the list. A trailing space on 'prefix' or leading
|
|
||||||
space on 'suffix' will cause them to be put into separate list
|
|
||||||
elements rather than being concatenated."""
|
|
||||||
|
|
||||||
if not list:
|
|
||||||
return list
|
|
||||||
|
|
||||||
list = f(env.subst_path(list))
|
|
||||||
|
|
||||||
ret = []
|
|
||||||
|
|
||||||
# ensure that prefix and suffix are strings
|
|
||||||
prefix = str(env.subst(prefix, SCons.Util.SUBST_RAW))
|
|
||||||
suffix = str(env.subst(suffix, SCons.Util.SUBST_RAW))
|
|
||||||
|
|
||||||
for x in list:
|
|
||||||
x = str(x)
|
|
||||||
if x:
|
|
||||||
|
|
||||||
if prefix:
|
|
||||||
if prefix[-1] == ' ':
|
|
||||||
ret.append(prefix[:-1])
|
|
||||||
elif x[:len(prefix)] != prefix:
|
|
||||||
x = prefix + x
|
|
||||||
|
|
||||||
ret.append(x)
|
|
||||||
|
|
||||||
if suffix:
|
|
||||||
if suffix[0] == ' ':
|
|
||||||
ret.append(suffix[1:])
|
|
||||||
elif x[-len(suffix):] != suffix:
|
|
||||||
ret[-1] = ret[-1]+suffix
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
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'."""
|
|
||||||
|
|
||||||
if not callable(c):
|
|
||||||
if callable(env["_concat"]):
|
|
||||||
c = env["_concat"]
|
|
||||||
else:
|
|
||||||
c = _concat
|
|
||||||
def f(list, sp=stripprefix, ss=stripsuffix):
|
|
||||||
ret = []
|
|
||||||
for l in list:
|
|
||||||
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)]
|
|
||||||
ret.append(l)
|
|
||||||
return ret
|
|
||||||
return c(prefix, list, suffix, env, f)
|
|
||||||
|
|
||||||
def _defines(prefix, defs, suffix, env, c=_concat):
|
|
||||||
"""A wrapper around _concat that turns a list or string
|
|
||||||
into a list of C preprocessor command-line definitions.
|
|
||||||
"""
|
|
||||||
if SCons.Util.is_List(defs):
|
|
||||||
l = []
|
|
||||||
for d in defs:
|
|
||||||
if SCons.Util.is_List(d) or type(d) is types.TupleType:
|
|
||||||
l.append(str(d[0]) + '=' + str(d[1]))
|
|
||||||
else:
|
|
||||||
l.append(str(d))
|
|
||||||
elif SCons.Util.is_Dict(defs):
|
|
||||||
# The items in a dictionary are stored in random order, but
|
|
||||||
# if the order of the command-line options changes from
|
|
||||||
# invocation to invocation, then the signature of the command
|
|
||||||
# line will change and we'll get random unnecessary rebuilds.
|
|
||||||
# Consequently, we have to sort the keys to ensure a
|
|
||||||
# consistent order...
|
|
||||||
l = []
|
|
||||||
keys = defs.keys()
|
|
||||||
keys.sort()
|
|
||||||
for k in keys:
|
|
||||||
v = defs[k]
|
|
||||||
if v is None:
|
|
||||||
l.append(str(k))
|
|
||||||
else:
|
|
||||||
l.append(str(k) + '=' + str(v))
|
|
||||||
else:
|
|
||||||
l = [str(defs)]
|
|
||||||
return c(prefix, l, suffix, env)
|
|
||||||
|
|
||||||
class NullCmdGenerator:
|
|
||||||
"""This is a callable class that can be used in place of other
|
|
||||||
command generators if you don't want them to do anything.
|
|
||||||
|
|
||||||
The __call__ method for this class simply returns the thing
|
|
||||||
you instantiated it with.
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
env["DO_NOTHING"] = NullCmdGenerator
|
|
||||||
env["LINKCOM"] = "${DO_NOTHING('$LINK $SOURCES $TARGET')}"
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, cmd):
|
|
||||||
self.cmd = cmd
|
|
||||||
|
|
||||||
def __call__(self, target, source, env, for_signature=None):
|
|
||||||
return self.cmd
|
|
||||||
|
|
||||||
ConstructionEnvironment = {
|
|
||||||
'BUILDERS' : {},
|
|
||||||
'SCANNERS' : [],
|
|
||||||
'CPPSUFFIXES': CSuffixes,
|
|
||||||
'DSUFFIXES' : DSuffixes,
|
|
||||||
'IDLSUFFIXES': IDLSuffixes,
|
|
||||||
'PDFPREFIX' : '',
|
|
||||||
'PDFSUFFIX' : '.pdf',
|
|
||||||
'PSPREFIX' : '',
|
|
||||||
'PSSUFFIX' : '.ps',
|
|
||||||
'ENV' : {},
|
|
||||||
'INSTALL' : copyFunc,
|
|
||||||
'_concat' : _concat,
|
|
||||||
'_defines' : _defines,
|
|
||||||
'_stripixes' : _stripixes,
|
|
||||||
'_LIBFLAGS' : '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
|
|
||||||
'_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs)} $)',
|
|
||||||
'_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs)} $)',
|
|
||||||
'_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
|
|
||||||
'TEMPFILE' : NullCmdGenerator
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,175 +0,0 @@
|
||||||
"""SCons.Executor
|
|
||||||
|
|
||||||
A module for executing actions with specific lists of target and source
|
|
||||||
Nodes.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 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/engine/SCons/Executor.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
||||||
|
|
||||||
|
|
||||||
from SCons.Debug import logInstanceCreation
|
|
||||||
import SCons.Util
|
|
||||||
|
|
||||||
|
|
||||||
class Executor:
|
|
||||||
"""A class for controlling instances of executing an action.
|
|
||||||
|
|
||||||
This largely exists to hold a single association of an action,
|
|
||||||
environment, list of environment override dictionaries, targets
|
|
||||||
and sources for later processing as needed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, action, env=None, overridelist=[], targets=[], sources=[]):
|
|
||||||
if __debug__: logInstanceCreation(self)
|
|
||||||
self.action = action
|
|
||||||
self.env = env
|
|
||||||
self.overridelist = overridelist
|
|
||||||
self.targets = targets
|
|
||||||
self.sources = sources[:]
|
|
||||||
|
|
||||||
def get_build_env(self):
|
|
||||||
"""Fetch or create the appropriate build Environment
|
|
||||||
for this Executor.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return self.build_env
|
|
||||||
except AttributeError:
|
|
||||||
# Create the build environment instance with appropriate
|
|
||||||
# overrides. These get evaluated against the current
|
|
||||||
# environment's construction variables so that users can
|
|
||||||
# add to existing values by referencing the variable in
|
|
||||||
# the expansion.
|
|
||||||
overrides = {}
|
|
||||||
for odict in self.overridelist:
|
|
||||||
overrides.update(odict)
|
|
||||||
try:
|
|
||||||
generate_build_dict = self.targets[0].generate_build_dict
|
|
||||||
except (AttributeError, IndexError):
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
overrides.update(generate_build_dict())
|
|
||||||
|
|
||||||
import SCons.Defaults
|
|
||||||
env = self.env or SCons.Defaults.DefaultEnvironment()
|
|
||||||
self.build_env = env.Override(overrides)
|
|
||||||
|
|
||||||
# Now update the build environment with the things that we
|
|
||||||
# don't want expanded against the current construction
|
|
||||||
# variables.
|
|
||||||
self.build_env._update(SCons.Util.subst_dict(self.targets,
|
|
||||||
self.sources))
|
|
||||||
return self.build_env
|
|
||||||
|
|
||||||
def get_action_list(self, target):
|
|
||||||
"""Fetch or create the appropriate action list (for this target).
|
|
||||||
|
|
||||||
There is an architectural mistake here: we cache the action list
|
|
||||||
for the Executor and re-use it regardless of which target is
|
|
||||||
being asked for. In practice, this doesn't seem to be a problem
|
|
||||||
because executing the action list will update all of the targets
|
|
||||||
involved, so only one target's pre- and post-actions will win,
|
|
||||||
anyway. This is probably a bug we should fix...
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
al = self.action_list
|
|
||||||
except AttributeError:
|
|
||||||
al = self.action.get_actions()
|
|
||||||
self.action_list = al
|
|
||||||
try:
|
|
||||||
# XXX shouldn't reach into node attributes like this
|
|
||||||
return target.pre_actions + al + target.post_actions
|
|
||||||
except AttributeError:
|
|
||||||
return al
|
|
||||||
|
|
||||||
def __call__(self, target, errfunc, **kw):
|
|
||||||
"""Actually execute the action list."""
|
|
||||||
action_list = self.get_action_list(target)
|
|
||||||
if not action_list:
|
|
||||||
return
|
|
||||||
env = self.get_build_env()
|
|
||||||
for action in action_list:
|
|
||||||
apply(action, (self.targets, self.sources, env, errfunc), kw)
|
|
||||||
|
|
||||||
def cleanup(self):
|
|
||||||
try:
|
|
||||||
del self.build_env
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def add_sources(self, sources):
|
|
||||||
"""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)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
try:
|
|
||||||
return self.string
|
|
||||||
except AttributeError:
|
|
||||||
action = self.action
|
|
||||||
self.string = action.genstring(self.targets,
|
|
||||||
self.sources,
|
|
||||||
self.get_build_env())
|
|
||||||
return self.string
|
|
||||||
|
|
||||||
def get_raw_contents(self):
|
|
||||||
"""Fetch the raw signature contents. This, along with
|
|
||||||
get_contents(), is the real reason this class exists, so we can
|
|
||||||
compute this once and cache it regardless of how many target or
|
|
||||||
source Nodes there are.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return self.raw_contents
|
|
||||||
except AttributeError:
|
|
||||||
action = self.action
|
|
||||||
self.raw_contents = action.get_raw_contents(self.targets,
|
|
||||||
self.sources,
|
|
||||||
self.get_build_env())
|
|
||||||
return self.raw_contents
|
|
||||||
|
|
||||||
def get_contents(self):
|
|
||||||
"""Fetch the signature contents. This, along with
|
|
||||||
get_raw_contents(), is the real reason this class exists, so we
|
|
||||||
can compute this once and cache it regardless of how many target
|
|
||||||
or source Nodes there are.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return self.contents
|
|
||||||
except AttributeError:
|
|
||||||
action = self.action
|
|
||||||
self.contents = action.get_contents(self.targets,
|
|
||||||
self.sources,
|
|
||||||
self.get_build_env())
|
|
||||||
return self.contents
|
|
||||||
|
|
||||||
def get_timestamp(self):
|
|
||||||
"""Fetch a time stamp for this Executor. We don't have one, of
|
|
||||||
course (only files do), but this is the interface used by the
|
|
||||||
timestamp module.
|
|
||||||
"""
|
|
||||||
return 0
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,85 +0,0 @@
|
||||||
"""engine.SCons.Options.PathOption
|
|
||||||
|
|
||||||
This file defines an option type for SCons implementing 'package
|
|
||||||
activation'.
|
|
||||||
|
|
||||||
To be used whenever a 'package' may be enabled/disabled and the
|
|
||||||
package path may be specified.
|
|
||||||
|
|
||||||
Usage example:
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
x11=no (disables X11 support)
|
|
||||||
x11=yes (will search for the package installation dir)
|
|
||||||
x11=/usr/local/X11 (will check this path for existance)
|
|
||||||
|
|
||||||
To replace autoconf's --with-xxx=yyy
|
|
||||||
|
|
||||||
opts = Options()
|
|
||||||
|
|
||||||
opts = Options()
|
|
||||||
opts.Add(PathOption('qtdir',
|
|
||||||
'where the root of Qt is installed',
|
|
||||||
qtdir))
|
|
||||||
opts.Add(PathOption('qt_includes',
|
|
||||||
'where the Qt includes are installed',
|
|
||||||
'$qtdir/includes'))
|
|
||||||
opts.Add(PathOption('qt_libraries',
|
|
||||||
'where the Qt library is installed',
|
|
||||||
'$qtdir/lib'))
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 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/engine/SCons/Options/PathOption.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
||||||
|
|
||||||
__all__ = ('PathOption',)
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
import SCons.Errors
|
|
||||||
|
|
||||||
def _validator(key, val, env):
|
|
||||||
"""
|
|
||||||
"""
|
|
||||||
# todo: write validator, check for path
|
|
||||||
if not os.path.exists(val):
|
|
||||||
raise SCons.Errors.UserError(
|
|
||||||
'Path does not exist for option %s: %s' % (key, val))
|
|
||||||
|
|
||||||
|
|
||||||
def PathOption(key, help, default):
|
|
||||||
# NB: searchfunc is currenty undocumented and unsupported
|
|
||||||
"""
|
|
||||||
The input parameters describe a 'path list' option, thus they
|
|
||||||
are returned with the correct converter and validator appended. The
|
|
||||||
result is usable for input to opts.Add() .
|
|
||||||
|
|
||||||
A 'package list' option may either be 'all', 'none' or a list of
|
|
||||||
package names (seperated by space).
|
|
||||||
"""
|
|
||||||
return (key, '%s ( /path/to/%s )' % (help, key), default,
|
|
||||||
_validator, None)
|
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
"""SCons.Platform
|
|
||||||
|
|
||||||
SCons platform selection.
|
|
||||||
|
|
||||||
This looks for modules that define a callable object that can modify a
|
|
||||||
construction environment as appropriate for a given platform.
|
|
||||||
|
|
||||||
Note that we take a more simplistic view of "platform" than Python does.
|
|
||||||
We're looking for a single string that determines a set of
|
|
||||||
tool-independent variables with which to initialize a construction
|
|
||||||
environment. Consequently, we'll examine both sys.platform and os.name
|
|
||||||
(and anything else that might come in to play) in order to return some
|
|
||||||
specification which is unique enough for our purposes.
|
|
||||||
|
|
||||||
Note that because this subsysem just *selects* a callable that can
|
|
||||||
modify a construction environment, it's possible for people to define
|
|
||||||
their own "platform specification" in an arbitrary callable function.
|
|
||||||
No one needs to use or tie in to this subsystem in order to roll
|
|
||||||
their own platform definition.
|
|
||||||
"""
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 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/engine/SCons/Platform/__init__.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
||||||
|
|
||||||
import imp
|
|
||||||
import os
|
|
||||||
import string
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import SCons.Errors
|
|
||||||
import SCons.Tool
|
|
||||||
|
|
||||||
def platform_default():
|
|
||||||
"""Return the platform string for our execution environment.
|
|
||||||
|
|
||||||
The returned value should map to one of the SCons/Platform/*.py
|
|
||||||
files. Since we're architecture independent, though, we don't
|
|
||||||
care about the machine architecture.
|
|
||||||
"""
|
|
||||||
osname = os.name
|
|
||||||
if osname == 'java':
|
|
||||||
osname = os._osType
|
|
||||||
if osname == 'posix':
|
|
||||||
if sys.platform == 'cygwin':
|
|
||||||
return 'cygwin'
|
|
||||||
elif string.find(sys.platform, 'irix') != -1:
|
|
||||||
return 'irix'
|
|
||||||
elif string.find(sys.platform, 'sunos') != -1:
|
|
||||||
return 'sunos'
|
|
||||||
elif string.find(sys.platform, 'hp-ux') != -1:
|
|
||||||
return 'hpux'
|
|
||||||
elif string.find(sys.platform, 'aix') != -1:
|
|
||||||
return 'aix'
|
|
||||||
elif string.find(sys.platform, 'darwin') != -1:
|
|
||||||
return 'darwin'
|
|
||||||
else:
|
|
||||||
return 'posix'
|
|
||||||
elif os.name == 'os2':
|
|
||||||
return 'os2'
|
|
||||||
else:
|
|
||||||
return sys.platform
|
|
||||||
|
|
||||||
def platform_module(name = platform_default()):
|
|
||||||
"""Return the imported module for the platform.
|
|
||||||
|
|
||||||
This looks for a module name that matches the specified argument.
|
|
||||||
If the name is unspecified, we fetch the appropriate default for
|
|
||||||
our execution environment.
|
|
||||||
"""
|
|
||||||
full_name = 'SCons.Platform.' + name
|
|
||||||
if not sys.modules.has_key(full_name):
|
|
||||||
if os.name == 'java':
|
|
||||||
eval(full_name)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
file, path, desc = imp.find_module(name,
|
|
||||||
sys.modules['SCons.Platform'].__path__)
|
|
||||||
mod = imp.load_module(full_name, file, path, desc)
|
|
||||||
setattr(SCons.Platform, name, mod)
|
|
||||||
except ImportError:
|
|
||||||
raise SCons.Errors.UserError, "No platform named '%s'" % name
|
|
||||||
if file:
|
|
||||||
file.close()
|
|
||||||
return sys.modules[full_name]
|
|
||||||
|
|
||||||
def DefaultToolList(platform, env):
|
|
||||||
"""Select a default tool list for the specified platform.
|
|
||||||
"""
|
|
||||||
return SCons.Tool.tool_list(platform, env)
|
|
||||||
|
|
||||||
class PlatformSpec:
|
|
||||||
def __init__(self, name):
|
|
||||||
self.name = name
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
def Platform(name = platform_default()):
|
|
||||||
"""Select a canned Platform specification.
|
|
||||||
"""
|
|
||||||
module = platform_module(name)
|
|
||||||
spec = PlatformSpec(name)
|
|
||||||
spec.__call__ = module.generate
|
|
||||||
return spec
|
|
|
@ -1,452 +0,0 @@
|
||||||
"""SCons.Taskmaster
|
|
||||||
|
|
||||||
Generic Taskmaster.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 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/engine/SCons/Taskmaster.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
||||||
|
|
||||||
import string
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
import SCons.Node
|
|
||||||
import SCons.Errors
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
"""Default SCons build engine task.
|
|
||||||
|
|
||||||
This controls the interaction of the actual building of node
|
|
||||||
and the rest of the engine.
|
|
||||||
|
|
||||||
This is expected to handle all of the normally-customizable
|
|
||||||
aspects of controlling a build, so any given application
|
|
||||||
*should* be able to do what it wants by sub-classing this
|
|
||||||
class and overriding methods as appropriate. If an application
|
|
||||||
needs to customze something by sub-classing Taskmaster (or
|
|
||||||
some other build engine class), we should first try to migrate
|
|
||||||
that functionality into this class.
|
|
||||||
|
|
||||||
Note that it's generally a good idea for sub-classes to call
|
|
||||||
these methods explicitly to update state, etc., rather than
|
|
||||||
roll their own interaction with Taskmaster from scratch."""
|
|
||||||
def __init__(self, tm, targets, top, node):
|
|
||||||
self.tm = tm
|
|
||||||
self.targets = targets
|
|
||||||
self.top = top
|
|
||||||
self.node = node
|
|
||||||
|
|
||||||
def display(self, message):
|
|
||||||
"""Allow the calling interface to display a message
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def prepare(self):
|
|
||||||
"""Called just before the task is executed.
|
|
||||||
|
|
||||||
This unlinks all targets and makes all directories before
|
|
||||||
building anything."""
|
|
||||||
|
|
||||||
# Now that it's the appropriate time, give the TaskMaster a
|
|
||||||
# chance to raise any exceptions it encountered while preparing
|
|
||||||
# this task.
|
|
||||||
self.tm.exception_raise()
|
|
||||||
|
|
||||||
if self.tm.message:
|
|
||||||
self.display(self.tm.message)
|
|
||||||
self.tm.message = None
|
|
||||||
|
|
||||||
for t in self.targets:
|
|
||||||
t.prepare()
|
|
||||||
for s in t.side_effects:
|
|
||||||
s.prepare()
|
|
||||||
|
|
||||||
def execute(self):
|
|
||||||
"""Called to execute the task.
|
|
||||||
|
|
||||||
This method is called from multiple threads in a parallel build,
|
|
||||||
so only do thread safe stuff here. Do thread unsafe stuff in
|
|
||||||
prepare(), executed() or failed()."""
|
|
||||||
|
|
||||||
try:
|
|
||||||
everything_was_cached = 1
|
|
||||||
for t in self.targets:
|
|
||||||
if not t.retrieve_from_cache():
|
|
||||||
everything_was_cached = 0
|
|
||||||
break
|
|
||||||
if not everything_was_cached:
|
|
||||||
self.targets[0].build()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except SystemExit:
|
|
||||||
exc_value = sys.exc_info()[1]
|
|
||||||
raise SCons.Errors.ExplicitExit(self.targets[0], exc_value.code)
|
|
||||||
except SCons.Errors.UserError:
|
|
||||||
raise
|
|
||||||
except SCons.Errors.BuildError:
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
|
||||||
raise SCons.Errors.BuildError(self.targets[0],
|
|
||||||
"Exception",
|
|
||||||
exc_type,
|
|
||||||
exc_value,
|
|
||||||
exc_traceback)
|
|
||||||
|
|
||||||
def get_target(self):
|
|
||||||
"""Fetch the target being built or updated by this task.
|
|
||||||
"""
|
|
||||||
return self.node
|
|
||||||
|
|
||||||
def executed(self):
|
|
||||||
"""Called when the task has been successfully executed.
|
|
||||||
|
|
||||||
This may have been a do-nothing operation (to preserve
|
|
||||||
build order), so check the node's state before updating
|
|
||||||
things. Most importantly, this calls back to the
|
|
||||||
Taskmaster to put any node tasks waiting on this one
|
|
||||||
back on the pending list."""
|
|
||||||
|
|
||||||
if self.targets[0].get_state() == SCons.Node.executing:
|
|
||||||
for t in self.targets:
|
|
||||||
for side_effect in t.side_effects:
|
|
||||||
side_effect.set_state(None)
|
|
||||||
t.set_state(SCons.Node.executed)
|
|
||||||
t.built()
|
|
||||||
else:
|
|
||||||
for t in self.targets:
|
|
||||||
t.visited()
|
|
||||||
|
|
||||||
self.tm.executed(self.node)
|
|
||||||
|
|
||||||
def failed(self):
|
|
||||||
"""Default action when a task fails: stop the build."""
|
|
||||||
self.fail_stop()
|
|
||||||
|
|
||||||
def fail_stop(self):
|
|
||||||
"""Explicit stop-the-build failure."""
|
|
||||||
for t in self.targets:
|
|
||||||
t.set_state(SCons.Node.failed)
|
|
||||||
self.tm.failed(self.node)
|
|
||||||
self.tm.stop()
|
|
||||||
|
|
||||||
def fail_continue(self):
|
|
||||||
"""Explicit continue-the-build failure.
|
|
||||||
|
|
||||||
This sets failure status on the target nodes and all of
|
|
||||||
their dependent parent nodes.
|
|
||||||
"""
|
|
||||||
for t in self.targets:
|
|
||||||
# Set failure state on all of the parents that were dependent
|
|
||||||
# on this failed build.
|
|
||||||
def set_state(node): node.set_state(SCons.Node.failed)
|
|
||||||
t.call_for_all_waiting_parents(set_state)
|
|
||||||
|
|
||||||
self.tm.executed(self.node)
|
|
||||||
|
|
||||||
def mark_targets(self, state):
|
|
||||||
for t in self.targets:
|
|
||||||
t.set_state(state)
|
|
||||||
|
|
||||||
def mark_targets_and_side_effects(self, state):
|
|
||||||
for t in self.targets:
|
|
||||||
for side_effect in t.side_effects:
|
|
||||||
side_effect.set_state(state)
|
|
||||||
t.set_state(state)
|
|
||||||
|
|
||||||
def make_ready_all(self):
|
|
||||||
"""Mark all targets in a task ready for execution.
|
|
||||||
|
|
||||||
This is used when the interface needs every target Node to be
|
|
||||||
visited--the canonical example being the "scons -c" option.
|
|
||||||
"""
|
|
||||||
self.out_of_date = self.targets[:]
|
|
||||||
self.mark_targets_and_side_effects(SCons.Node.executing)
|
|
||||||
|
|
||||||
def make_ready_current(self):
|
|
||||||
"""Mark all targets in a task ready for execution if any target
|
|
||||||
is not current.
|
|
||||||
|
|
||||||
This is the default behavior for building only what's necessary.
|
|
||||||
"""
|
|
||||||
self.out_of_date = []
|
|
||||||
for t in self.targets:
|
|
||||||
if not t.current():
|
|
||||||
self.out_of_date.append(t)
|
|
||||||
if self.out_of_date:
|
|
||||||
self.mark_targets_and_side_effects(SCons.Node.executing)
|
|
||||||
else:
|
|
||||||
self.mark_targets(SCons.Node.up_to_date)
|
|
||||||
|
|
||||||
make_ready = make_ready_current
|
|
||||||
|
|
||||||
def postprocess(self):
|
|
||||||
"""Post process a task after it's been executed."""
|
|
||||||
for t in self.targets:
|
|
||||||
t.postprocess()
|
|
||||||
|
|
||||||
def exc_info(self):
|
|
||||||
return self.tm.exception
|
|
||||||
|
|
||||||
def exc_clear(self):
|
|
||||||
self.tm.exception_clear()
|
|
||||||
|
|
||||||
def exception_set(self):
|
|
||||||
self.tm.exception_set()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def order(dependencies):
|
|
||||||
"""Re-order a list of dependencies (if we need to)."""
|
|
||||||
return dependencies
|
|
||||||
|
|
||||||
|
|
||||||
class Taskmaster:
|
|
||||||
"""A generic Taskmaster for handling a bunch of targets.
|
|
||||||
|
|
||||||
Classes that override methods of this class should call
|
|
||||||
the base class method, so this class can do its thing.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, targets=[], tasker=Task, order=order):
|
|
||||||
self.targets = targets # top level targets
|
|
||||||
self.candidates = targets[:] # nodes that might be ready to be executed
|
|
||||||
self.candidates.reverse()
|
|
||||||
self.executing = [] # nodes that are currently executing
|
|
||||||
self.pending = [] # nodes that depend on a currently executing node
|
|
||||||
self.tasker = tasker
|
|
||||||
self.ready = None # the next task that is ready to be executed
|
|
||||||
self.order = order
|
|
||||||
self.exception_clear()
|
|
||||||
self.message = None
|
|
||||||
|
|
||||||
def _find_next_ready_node(self):
|
|
||||||
"""Find the next node that is ready to be built"""
|
|
||||||
|
|
||||||
if self.ready:
|
|
||||||
return
|
|
||||||
|
|
||||||
while self.candidates:
|
|
||||||
node = self.candidates[-1]
|
|
||||||
state = node.get_state()
|
|
||||||
|
|
||||||
# Skip this node if it has already been executed:
|
|
||||||
if state != None and state != SCons.Node.stack:
|
|
||||||
self.candidates.pop()
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Mark this node as being on the execution stack:
|
|
||||||
node.set_state(SCons.Node.stack)
|
|
||||||
|
|
||||||
try:
|
|
||||||
children = node.children()
|
|
||||||
except SystemExit:
|
|
||||||
exc_value = sys.exc_info()[1]
|
|
||||||
e = SCons.Errors.ExplicitExit(node, exc_value.code)
|
|
||||||
self.exception_set((SCons.Errors.ExplicitExit, e))
|
|
||||||
self.candidates.pop()
|
|
||||||
self.ready = node
|
|
||||||
break
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
# We had a problem just trying to figure out the
|
|
||||||
# children (like a child couldn't be linked in to a
|
|
||||||
# BuildDir, or a Scanner threw something). Arrange to
|
|
||||||
# raise the exception when the Task is "executed."
|
|
||||||
self.exception_set()
|
|
||||||
self.candidates.pop()
|
|
||||||
self.ready = node
|
|
||||||
break
|
|
||||||
|
|
||||||
# Detect dependency cycles:
|
|
||||||
def in_stack(node): return node.get_state() == SCons.Node.stack
|
|
||||||
cycle = filter(in_stack, children)
|
|
||||||
if cycle:
|
|
||||||
nodes = filter(in_stack, self.candidates) + cycle
|
|
||||||
nodes.reverse()
|
|
||||||
desc = "Dependency cycle: " + string.join(map(str, nodes), " -> ")
|
|
||||||
raise SCons.Errors.UserError, desc
|
|
||||||
|
|
||||||
# Find all of the derived dependencies (that is,
|
|
||||||
# children who have builders or are side effects):
|
|
||||||
try:
|
|
||||||
def derived_nodes(node): return node.is_derived() or node.is_pseudo_derived()
|
|
||||||
derived = filter(derived_nodes, children)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
# We had a problem just trying to figure out if any of
|
|
||||||
# the kids are derived (like a child couldn't be linked
|
|
||||||
# from a repository). Arrange to raise the exception
|
|
||||||
# when the Task is "executed."
|
|
||||||
self.exception_set()
|
|
||||||
self.candidates.pop()
|
|
||||||
self.ready = node
|
|
||||||
break
|
|
||||||
|
|
||||||
# If there aren't any children with builders and this
|
|
||||||
# was a top-level argument, then see if we can find any
|
|
||||||
# corresponding targets in linked build directories:
|
|
||||||
if not derived and node in self.targets:
|
|
||||||
alt, message = node.alter_targets()
|
|
||||||
if alt:
|
|
||||||
self.message = message
|
|
||||||
self.candidates.pop()
|
|
||||||
self.candidates.extend(alt)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Add derived files that have not been built
|
|
||||||
# to the candidates list:
|
|
||||||
def unbuilt_nodes(node): return node.get_state() == None
|
|
||||||
not_built = filter(unbuilt_nodes, derived)
|
|
||||||
if not_built:
|
|
||||||
# We're waiting on one more derived files that have not
|
|
||||||
# yet been built. Add this node to the waiting_parents
|
|
||||||
# list of each of those derived files.
|
|
||||||
def add_to_waiting_parents(child, parent=node):
|
|
||||||
child.add_to_waiting_parents(parent)
|
|
||||||
map(add_to_waiting_parents, not_built)
|
|
||||||
not_built.reverse()
|
|
||||||
self.candidates.extend(self.order(not_built))
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Skip this node if it has side-effects that are
|
|
||||||
# currently being built:
|
|
||||||
cont = 0
|
|
||||||
for side_effect in node.side_effects:
|
|
||||||
if side_effect.get_state() == SCons.Node.executing:
|
|
||||||
self.pending.append(node)
|
|
||||||
node.set_state(SCons.Node.pending)
|
|
||||||
self.candidates.pop()
|
|
||||||
cont = 1
|
|
||||||
break
|
|
||||||
if cont: continue
|
|
||||||
|
|
||||||
# Skip this node if it is pending on a currently
|
|
||||||
# executing node:
|
|
||||||
if node.depends_on(self.executing) or node.depends_on(self.pending):
|
|
||||||
self.pending.append(node)
|
|
||||||
node.set_state(SCons.Node.pending)
|
|
||||||
self.candidates.pop()
|
|
||||||
continue
|
|
||||||
|
|
||||||
# The default when we've gotten through all of the checks above:
|
|
||||||
# this node is ready to be built.
|
|
||||||
self.candidates.pop()
|
|
||||||
self.ready = node
|
|
||||||
break
|
|
||||||
|
|
||||||
def next_task(self):
|
|
||||||
"""Return the next task to be executed."""
|
|
||||||
|
|
||||||
self._find_next_ready_node()
|
|
||||||
|
|
||||||
node = self.ready
|
|
||||||
|
|
||||||
if node is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
|
||||||
tlist = node.builder.targets(node)
|
|
||||||
except AttributeError:
|
|
||||||
tlist = [node]
|
|
||||||
self.executing.extend(tlist)
|
|
||||||
self.executing.extend(node.side_effects)
|
|
||||||
|
|
||||||
task = self.tasker(self, tlist, node in self.targets, node)
|
|
||||||
try:
|
|
||||||
task.make_ready()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
# We had a problem just trying to get this task ready (like
|
|
||||||
# a child couldn't be linked in to a BuildDir when deciding
|
|
||||||
# whether this node is current). Arrange to raise the
|
|
||||||
# exception when the Task is "executed."
|
|
||||||
self.exception_set()
|
|
||||||
self.ready = None
|
|
||||||
|
|
||||||
return task
|
|
||||||
|
|
||||||
def is_blocked(self):
|
|
||||||
self._find_next_ready_node()
|
|
||||||
|
|
||||||
return not self.ready and (self.pending or self.executing)
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
"""Stop the current build completely."""
|
|
||||||
self.candidates = []
|
|
||||||
self.ready = None
|
|
||||||
self.pending = []
|
|
||||||
|
|
||||||
def failed(self, node):
|
|
||||||
try:
|
|
||||||
tlist = node.builder.targets(node)
|
|
||||||
except AttributeError:
|
|
||||||
tlist = [node]
|
|
||||||
for t in tlist:
|
|
||||||
self.executing.remove(t)
|
|
||||||
for side_effect in node.side_effects:
|
|
||||||
self.executing.remove(side_effect)
|
|
||||||
|
|
||||||
def executed(self, node):
|
|
||||||
try:
|
|
||||||
tlist = node.builder.targets(node)
|
|
||||||
except AttributeError:
|
|
||||||
tlist = [node]
|
|
||||||
for t in tlist:
|
|
||||||
self.executing.remove(t)
|
|
||||||
for side_effect in node.side_effects:
|
|
||||||
self.executing.remove(side_effect)
|
|
||||||
|
|
||||||
# move the current pending nodes to the candidates list:
|
|
||||||
# (they may not all be ready to build, but _find_next_ready_node()
|
|
||||||
# will figure out which ones are really ready)
|
|
||||||
for node in self.pending:
|
|
||||||
node.set_state(None)
|
|
||||||
self.pending.reverse()
|
|
||||||
self.candidates.extend(self.pending)
|
|
||||||
self.pending = []
|
|
||||||
|
|
||||||
def exception_set(self, exception=None):
|
|
||||||
if exception is None:
|
|
||||||
exception = sys.exc_info()
|
|
||||||
self.exception = exception
|
|
||||||
self.exception_raise = self._exception_raise
|
|
||||||
|
|
||||||
def exception_clear(self):
|
|
||||||
self.exception = (None, None, None)
|
|
||||||
self.exception_raise = self._no_exception_to_raise
|
|
||||||
|
|
||||||
def _no_exception_to_raise(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _exception_raise(self):
|
|
||||||
"""Raise a pending exception that was recorded while
|
|
||||||
getting a Task ready for execution."""
|
|
||||||
exc_type, exc_value = self.exception[:2]
|
|
||||||
raise exc_type, exc_value
|
|
|
@ -1,138 +0,0 @@
|
||||||
"""engine.SCons.Tool.icl
|
|
||||||
|
|
||||||
Tool-specific initialization for the Intel C/C++ compiler.
|
|
||||||
|
|
||||||
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 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/engine/SCons/Tool/icl.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
import SCons.Tool.msvc
|
|
||||||
import SCons.Util
|
|
||||||
import SCons.Warnings
|
|
||||||
|
|
||||||
# Find Intel compiler:
|
|
||||||
# Could enumerate subkeys here to be more flexible.
|
|
||||||
def get_intel_compiler_top(version):
|
|
||||||
"""
|
|
||||||
Return the main path to the top-level dir of the Intel compiler,
|
|
||||||
using the given version or latest if 0.
|
|
||||||
The compiler will be in <top>/Bin/icl.exe,
|
|
||||||
the include dir is <top>/Include, etc.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if version == 0:
|
|
||||||
version = "7.0" # XXX: should scan for latest
|
|
||||||
|
|
||||||
if not SCons.Util.can_read_reg:
|
|
||||||
raise SCons.Errors.InternalError, "No Windows registry module was found"
|
|
||||||
|
|
||||||
K = ('Software\\Intel\\' +
|
|
||||||
'Intel(R) C/C++ Compiler for 32-bit apps, Version ' + version)
|
|
||||||
# Note: v5 had slightly different key:
|
|
||||||
# HKCU\Software\Intel\Intel C/C++ Compiler for 32-bit apps, Version 5.0
|
|
||||||
# Note no (R).
|
|
||||||
try:
|
|
||||||
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_CURRENT_USER, K)
|
|
||||||
except SCons.Util.RegError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
|
||||||
# On my machine, this returns:
|
|
||||||
# c:\Program Files\Intel\Compiler70
|
|
||||||
top = SCons.Util.RegQueryValueEx(k, "Directory")[0]
|
|
||||||
except SCons.Util.RegError:
|
|
||||||
raise SCons.Errors.InternalError, "%s was not found in the registry."%K
|
|
||||||
|
|
||||||
if os.path.exists(os.path.join(top, "ia32")):
|
|
||||||
top = os.path.join(top, "ia32")
|
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(top, "Bin", "icl.exe")):
|
|
||||||
raise SCons.Errors.InternalError, "Can't find Intel compiler in %s"%top
|
|
||||||
|
|
||||||
return top
|
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
|
||||||
"""Add Builders and construction variables for icl to an Environment."""
|
|
||||||
SCons.Tool.msvc.generate(env)
|
|
||||||
|
|
||||||
try:
|
|
||||||
icltop = get_intel_compiler_top(0)
|
|
||||||
except (SCons.Util.RegError, SCons.Errors.InternalError):
|
|
||||||
icltop = None
|
|
||||||
|
|
||||||
if icltop:
|
|
||||||
env.PrependENVPath('INCLUDE', os.path.join(icltop, 'Include'))
|
|
||||||
env.PrependENVPath('LIB', os.path.join(icltop, 'Lib'))
|
|
||||||
env.PrependENVPath('PATH', os.path.join(icltop, 'Bin'))
|
|
||||||
|
|
||||||
env['CC'] = 'icl'
|
|
||||||
env['CXX'] = 'icl'
|
|
||||||
env['LINK'] = 'xilink'
|
|
||||||
|
|
||||||
# Look for license file dir.
|
|
||||||
envlicdir = os.environ.get("INTEL_LICENSE_FILE", '')
|
|
||||||
K = ('SOFTWARE\Intel\Licenses')
|
|
||||||
try:
|
|
||||||
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
|
|
||||||
reglicdir = SCons.Util.RegQueryValueEx(k, "w_cpp")[0]
|
|
||||||
except (AttributeError, SCons.Util.RegError):
|
|
||||||
reglicdir = ""
|
|
||||||
defaultlicdir = r'C:\Program Files\Common Files\Intel\Licenses'
|
|
||||||
|
|
||||||
licdir = None
|
|
||||||
for ld in [envlicdir, reglicdir]:
|
|
||||||
if ld and os.path.exists(ld):
|
|
||||||
licdir = ld
|
|
||||||
break
|
|
||||||
if not licdir:
|
|
||||||
licdir = defaultlicdir
|
|
||||||
if not os.path.exists(licdir):
|
|
||||||
class ICLLicenseDirWarning(SCons.Warnings.Warning):
|
|
||||||
pass
|
|
||||||
SCons.Warnings.enableWarningClass(ICLLicenseDirWarning)
|
|
||||||
SCons.Warnings.warn(ICLLicenseDirWarning,
|
|
||||||
"Intel license dir was not found."
|
|
||||||
" Tried using the INTEL_LICENSE_FILE environment variable (%s), the registry (%s) and the default path (%s)."
|
|
||||||
" Using the default path as a last resort."
|
|
||||||
% (envlicdir, reglicdir, defaultlicdir))
|
|
||||||
env['ENV']['INTEL_LICENSE_FILE'] = licdir
|
|
||||||
|
|
||||||
def exists(env):
|
|
||||||
try:
|
|
||||||
top = get_intel_compiler_top(0)
|
|
||||||
except (SCons.Util.RegError, SCons.Errors.InternalError):
|
|
||||||
top = None
|
|
||||||
|
|
||||||
if not top:
|
|
||||||
return env.Detect('icl')
|
|
||||||
return top is not None
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,118 +0,0 @@
|
||||||
"""SCons.Tool.tex
|
|
||||||
|
|
||||||
Tool-specific initialization for TeX.
|
|
||||||
|
|
||||||
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 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/engine/SCons/Tool/tex.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
|
||||||
|
|
||||||
import os.path
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
|
|
||||||
import SCons.Action
|
|
||||||
import SCons.Defaults
|
|
||||||
import SCons.Node
|
|
||||||
import SCons.Node.FS
|
|
||||||
import SCons.Util
|
|
||||||
|
|
||||||
# Define an action to build a generic tex file. This is sufficient for all
|
|
||||||
# tex files.
|
|
||||||
TeXAction = SCons.Action.CommandAction("$TEXCOM")
|
|
||||||
|
|
||||||
# Define an action to build a latex file. This action might be needed more
|
|
||||||
# than once if we are dealing with labels and bibtex
|
|
||||||
LaTeXAction = SCons.Action.CommandAction("$LATEXCOM")
|
|
||||||
|
|
||||||
# Define an action to run BibTeX on a file.
|
|
||||||
BibTeXAction = SCons.Action.CommandAction("$BIBTEXCOM")
|
|
||||||
|
|
||||||
def LaTeXAuxAction(target = None, source= None, env=None):
|
|
||||||
"""A builder for LaTeX files that checks the output in the aux file
|
|
||||||
and decides how many times to use LaTeXAction, and BibTeXAction."""
|
|
||||||
# Get the base name of the target
|
|
||||||
basename, ext = os.path.splitext(str(target[0]))
|
|
||||||
# Run LaTeX once to generate a new aux file.
|
|
||||||
LaTeXAction(target,source,env)
|
|
||||||
# Now if bibtex will need to be run.
|
|
||||||
content = open(basename + ".aux","rb").read()
|
|
||||||
if string.find(content, "bibdata") != -1:
|
|
||||||
bibfile = env.fs.File(basename)
|
|
||||||
BibTeXAction(None,bibfile,env)
|
|
||||||
# Now check if latex needs to be run yet again.
|
|
||||||
for trial in range(3):
|
|
||||||
content = open(basename + ".log","rb").read()
|
|
||||||
if not re.search("^LaTeX Warning:.*Rerun",content,re.MULTILINE):
|
|
||||||
break
|
|
||||||
LaTeXAction(target,source,env)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def TeXLaTeXAction(target = None, source= None, env=None):
|
|
||||||
"""A builder for TeX and LaTeX that scans the source file to
|
|
||||||
decide the "flavor" of the source and then executes the appropriate
|
|
||||||
program."""
|
|
||||||
LaTeXFile = None
|
|
||||||
for src in source:
|
|
||||||
content = src.get_contents()
|
|
||||||
if re.search("\\\\document(style|class)",content):
|
|
||||||
LaTeXFile = 1
|
|
||||||
break
|
|
||||||
if LaTeXFile:
|
|
||||||
LaTeXAuxAction(target,source,env)
|
|
||||||
else:
|
|
||||||
TeXAction(target,source,env)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def generate(env):
|
|
||||||
"""Add Builders and construction variables for TeX to an Environment."""
|
|
||||||
try:
|
|
||||||
bld = env['BUILDERS']['DVI']
|
|
||||||
except KeyError:
|
|
||||||
bld = SCons.Defaults.DVI()
|
|
||||||
env['BUILDERS']['DVI'] = bld
|
|
||||||
|
|
||||||
bld.add_action('.tex', TeXLaTeXAction)
|
|
||||||
|
|
||||||
env['TEX'] = 'tex'
|
|
||||||
env['TEXFLAGS'] = SCons.Util.CLVar('')
|
|
||||||
env['TEXCOM'] = '$TEX $TEXFLAGS $SOURCES'
|
|
||||||
|
|
||||||
# Duplicate from latex.py. If latex.py goes away, then this is still OK.
|
|
||||||
env['LATEX'] = 'latex'
|
|
||||||
env['LATEXFLAGS'] = SCons.Util.CLVar('')
|
|
||||||
env['LATEXCOM'] = '$LATEX $LATEXFLAGS $SOURCES'
|
|
||||||
|
|
||||||
env['BIBTEX'] = 'bibtex'
|
|
||||||
env['BIBTEXFLAGS'] = SCons.Util.CLVar('')
|
|
||||||
env['BIBTEXCOM'] = '$BIBTEX $BIBTEXFLAGS $SOURCES'
|
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
|
||||||
return env.Detect('tex')
|
|
File diff suppressed because it is too large
Load diff
830
scons/scons-local-0.97/SCons/Action.py
Normal file
830
scons/scons-local-0.97/SCons/Action.py
Normal file
|
@ -0,0 +1,830 @@
|
||||||
|
"""SCons.Action
|
||||||
|
|
||||||
|
This encapsulates information about executing any sort of action that
|
||||||
|
can build one or more target Nodes (typically files) from one or more
|
||||||
|
source Nodes (also typically files) given a specific Environment.
|
||||||
|
|
||||||
|
The base class here is ActionBase. The base class supplies just a few
|
||||||
|
OO utility methods and some generic methods for displaying information
|
||||||
|
about an Action in response to the various commands that control printing.
|
||||||
|
|
||||||
|
A second-level base class is _ActionAction. This extends ActionBase
|
||||||
|
by providing the methods that can be used to show and perform an
|
||||||
|
action. True Action objects will subclass _ActionAction; Action
|
||||||
|
factory class objects will subclass ActionBase.
|
||||||
|
|
||||||
|
The heavy lifting is handled by subclasses for the different types of
|
||||||
|
actions we might execute:
|
||||||
|
|
||||||
|
CommandAction
|
||||||
|
CommandGeneratorAction
|
||||||
|
FunctionAction
|
||||||
|
ListAction
|
||||||
|
|
||||||
|
The subclasses supply the following public interface methods used by
|
||||||
|
other modules:
|
||||||
|
|
||||||
|
__call__()
|
||||||
|
THE public interface, "calling" an Action object executes the
|
||||||
|
command or Python function. This also takes care of printing
|
||||||
|
a pre-substitution command for debugging purposes.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
genstring()
|
||||||
|
Returns a string representation of the Action *without*
|
||||||
|
command substitution, but allows a CommandGeneratorAction to
|
||||||
|
generate the right action based on the specified target,
|
||||||
|
source and env. This is used by the Signature subsystem
|
||||||
|
(through the Executor) to obtain an (imprecise) representation
|
||||||
|
of the Action operation for informative purposes.
|
||||||
|
|
||||||
|
|
||||||
|
Subclasses also supply the following methods for internal use within
|
||||||
|
this module:
|
||||||
|
|
||||||
|
__str__()
|
||||||
|
Returns a string approximation of the Action; no variable
|
||||||
|
substitution is performed.
|
||||||
|
|
||||||
|
execute()
|
||||||
|
The internal method that really, truly, actually handles the
|
||||||
|
execution of a command or Python function. This is used so
|
||||||
|
that the __call__() methods can take care of displaying any
|
||||||
|
pre-substitution representations, and *then* execute an action
|
||||||
|
without worrying about the specific Actions involved.
|
||||||
|
|
||||||
|
strfunction()
|
||||||
|
Returns a substituted string representation of the Action.
|
||||||
|
This is used by the _ActionAction.show() command to display the
|
||||||
|
command/function that will be executed to generate the target(s).
|
||||||
|
|
||||||
|
There is a related independent ActionCaller class that looks like a
|
||||||
|
regular Action, and which serves as a wrapper for arbitrary functions
|
||||||
|
that we want to let the user specify the arguments to now, but actually
|
||||||
|
execute later (when an out-of-date check determines that it's needed to
|
||||||
|
be executed, for example). Objects of this class are returned by an
|
||||||
|
ActionFactory class that provides a __call__() method as a convenient
|
||||||
|
way for wrapping up the functions.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Action.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import dis
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from SCons.Debug import logInstanceCreation
|
||||||
|
import SCons.Errors
|
||||||
|
import SCons.Executor
|
||||||
|
import SCons.Util
|
||||||
|
|
||||||
|
class _Null:
|
||||||
|
pass
|
||||||
|
|
||||||
|
_null = _Null
|
||||||
|
|
||||||
|
print_actions = 1
|
||||||
|
execute_actions = 1
|
||||||
|
print_actions_presub = 0
|
||||||
|
|
||||||
|
default_ENV = None
|
||||||
|
|
||||||
|
def rfile(n):
|
||||||
|
try:
|
||||||
|
return n.rfile()
|
||||||
|
except AttributeError:
|
||||||
|
return n
|
||||||
|
|
||||||
|
def default_exitstatfunc(s):
|
||||||
|
return s
|
||||||
|
|
||||||
|
try:
|
||||||
|
SET_LINENO = dis.SET_LINENO
|
||||||
|
HAVE_ARGUMENT = dis.HAVE_ARGUMENT
|
||||||
|
except AttributeError:
|
||||||
|
remove_set_lineno_codes = lambda x: x
|
||||||
|
else:
|
||||||
|
def remove_set_lineno_codes(code):
|
||||||
|
result = []
|
||||||
|
n = len(code)
|
||||||
|
i = 0
|
||||||
|
while i < n:
|
||||||
|
c = code[i]
|
||||||
|
op = ord(c)
|
||||||
|
if op >= HAVE_ARGUMENT:
|
||||||
|
if op != SET_LINENO:
|
||||||
|
result.append(code[i:i+3])
|
||||||
|
i = i+3
|
||||||
|
else:
|
||||||
|
result.append(c)
|
||||||
|
i = i+1
|
||||||
|
return string.join(result, '')
|
||||||
|
|
||||||
|
def _actionAppend(act1, act2):
|
||||||
|
# This function knows how to slap two actions together.
|
||||||
|
# Mainly, it handles ListActions by concatenating into
|
||||||
|
# a single ListAction.
|
||||||
|
a1 = Action(act1)
|
||||||
|
a2 = Action(act2)
|
||||||
|
if a1 is None or a2 is None:
|
||||||
|
raise TypeError, "Cannot append %s to %s" % (type(act1), type(act2))
|
||||||
|
if isinstance(a1, ListAction):
|
||||||
|
if isinstance(a2, ListAction):
|
||||||
|
return ListAction(a1.list + a2.list)
|
||||||
|
else:
|
||||||
|
return ListAction(a1.list + [ a2 ])
|
||||||
|
else:
|
||||||
|
if isinstance(a2, ListAction):
|
||||||
|
return ListAction([ a1 ] + a2.list)
|
||||||
|
else:
|
||||||
|
return ListAction([ a1, a2 ])
|
||||||
|
|
||||||
|
def _do_create_action(act, *args, **kw):
|
||||||
|
"""This is the actual "implementation" for the
|
||||||
|
Action factory method, below. This handles the
|
||||||
|
fact that passing lists to Action() itself has
|
||||||
|
different semantics than passing lists as elements
|
||||||
|
of lists.
|
||||||
|
|
||||||
|
The former will create a ListAction, the latter
|
||||||
|
will create a CommandAction by converting the inner
|
||||||
|
list elements to strings."""
|
||||||
|
|
||||||
|
if isinstance(act, ActionBase):
|
||||||
|
return act
|
||||||
|
if SCons.Util.is_List(act):
|
||||||
|
return apply(CommandAction, (act,)+args, kw)
|
||||||
|
if callable(act):
|
||||||
|
try:
|
||||||
|
gen = kw['generator']
|
||||||
|
del kw['generator']
|
||||||
|
except KeyError:
|
||||||
|
gen = 0
|
||||||
|
if gen:
|
||||||
|
action_type = CommandGeneratorAction
|
||||||
|
else:
|
||||||
|
action_type = FunctionAction
|
||||||
|
return apply(action_type, (act,)+args, kw)
|
||||||
|
if SCons.Util.is_String(act):
|
||||||
|
var=SCons.Util.get_environment_var(act)
|
||||||
|
if var:
|
||||||
|
# This looks like a string that is purely an Environment
|
||||||
|
# variable reference, like "$FOO" or "${FOO}". We do
|
||||||
|
# something special here...we lazily evaluate the contents
|
||||||
|
# of that Environment variable, so a user could put something
|
||||||
|
# like a function or a CommandGenerator in that variable
|
||||||
|
# instead of a string.
|
||||||
|
return apply(LazyAction, (var,)+args, kw)
|
||||||
|
commands = string.split(str(act), '\n')
|
||||||
|
if len(commands) == 1:
|
||||||
|
return apply(CommandAction, (commands[0],)+args, kw)
|
||||||
|
else:
|
||||||
|
listCmdActions = map(lambda x, args=args, kw=kw:
|
||||||
|
apply(CommandAction, (x,)+args, kw),
|
||||||
|
commands)
|
||||||
|
return ListAction(listCmdActions)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def Action(act, *args, **kw):
|
||||||
|
"""A factory for action objects."""
|
||||||
|
if SCons.Util.is_List(act):
|
||||||
|
acts = map(lambda a, args=args, kw=kw:
|
||||||
|
apply(_do_create_action, (a,)+args, kw),
|
||||||
|
act)
|
||||||
|
acts = filter(None, acts)
|
||||||
|
if len(acts) == 1:
|
||||||
|
return acts[0]
|
||||||
|
else:
|
||||||
|
return ListAction(acts)
|
||||||
|
else:
|
||||||
|
return apply(_do_create_action, (act,)+args, kw)
|
||||||
|
|
||||||
|
class ActionBase:
|
||||||
|
"""Base class for all types of action objects that can be held by
|
||||||
|
other objects (Builders, Executors, etc.) This provides the
|
||||||
|
common methods for manipulating and combining those actions."""
|
||||||
|
|
||||||
|
def __cmp__(self, other):
|
||||||
|
return cmp(self.__dict__, other)
|
||||||
|
|
||||||
|
def genstring(self, target, source, env):
|
||||||
|
return str(self)
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
return _actionAppend(self, other)
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
return _actionAppend(other, self)
|
||||||
|
|
||||||
|
def presub_lines(self, env):
|
||||||
|
# CommandGeneratorAction needs a real environment
|
||||||
|
# in order to return the proper string here, since
|
||||||
|
# it may call LazyAction, which looks up a key
|
||||||
|
# in that env. So we temporarily remember the env here,
|
||||||
|
# and CommandGeneratorAction will use this env
|
||||||
|
# when it calls its _generate method.
|
||||||
|
self.presub_env = env
|
||||||
|
lines = string.split(str(self), '\n')
|
||||||
|
self.presub_env = None # don't need this any more
|
||||||
|
return lines
|
||||||
|
|
||||||
|
def get_executor(self, env, overrides, tlist, slist, executor_kw):
|
||||||
|
"""Return the Executor for this Action."""
|
||||||
|
return SCons.Executor.Executor(self, env, overrides,
|
||||||
|
tlist, slist, executor_kw)
|
||||||
|
|
||||||
|
class _ActionAction(ActionBase):
|
||||||
|
"""Base class for actions that create output objects."""
|
||||||
|
def __init__(self, strfunction=_null, presub=_null, chdir=None, exitstatfunc=None, **kw):
|
||||||
|
if not strfunction is _null:
|
||||||
|
self.strfunction = strfunction
|
||||||
|
self.presub = presub
|
||||||
|
self.chdir = chdir
|
||||||
|
if not exitstatfunc:
|
||||||
|
exitstatfunc = default_exitstatfunc
|
||||||
|
self.exitstatfunc = exitstatfunc
|
||||||
|
|
||||||
|
def print_cmd_line(self, s, target, source, env):
|
||||||
|
sys.stdout.write(s + "\n")
|
||||||
|
|
||||||
|
def __call__(self, target, source, env,
|
||||||
|
exitstatfunc=_null,
|
||||||
|
presub=_null,
|
||||||
|
show=_null,
|
||||||
|
execute=_null,
|
||||||
|
chdir=_null):
|
||||||
|
if not SCons.Util.is_List(target):
|
||||||
|
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
|
||||||
|
if presub is _null:
|
||||||
|
presub = print_actions_presub
|
||||||
|
if show is _null: show = print_actions
|
||||||
|
if execute is _null: execute = execute_actions
|
||||||
|
if chdir is _null: chdir = self.chdir
|
||||||
|
save_cwd = None
|
||||||
|
if chdir:
|
||||||
|
save_cwd = os.getcwd()
|
||||||
|
try:
|
||||||
|
chdir = str(chdir.abspath)
|
||||||
|
except AttributeError:
|
||||||
|
if not SCons.Util.is_String(chdir):
|
||||||
|
chdir = str(target[0].dir)
|
||||||
|
if presub:
|
||||||
|
t = string.join(map(str, target), ' and ')
|
||||||
|
l = string.join(self.presub_lines(env), '\n ')
|
||||||
|
out = "Building %s with action:\n %s\n" % (t, l)
|
||||||
|
sys.stdout.write(out)
|
||||||
|
s = None
|
||||||
|
if show and self.strfunction:
|
||||||
|
s = self.strfunction(target, source, env)
|
||||||
|
if s:
|
||||||
|
if chdir:
|
||||||
|
s = ('os.chdir(%s)\n' % repr(chdir)) + s
|
||||||
|
try:
|
||||||
|
get = env.get
|
||||||
|
except AttributeError:
|
||||||
|
print_func = self.print_cmd_line
|
||||||
|
else:
|
||||||
|
print_func = get('PRINT_CMD_LINE_FUNC')
|
||||||
|
if not print_func:
|
||||||
|
print_func = self.print_cmd_line
|
||||||
|
print_func(s, target, source, env)
|
||||||
|
stat = 0
|
||||||
|
if execute:
|
||||||
|
if chdir:
|
||||||
|
os.chdir(chdir)
|
||||||
|
try:
|
||||||
|
stat = self.execute(target, source, env)
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def _string_from_cmd_list(cmd_list):
|
||||||
|
"""Takes a list of command line arguments and returns a pretty
|
||||||
|
representation for printing."""
|
||||||
|
cl = []
|
||||||
|
for arg in map(str, cmd_list):
|
||||||
|
if ' ' in arg or '\t' in arg:
|
||||||
|
arg = '"' + arg + '"'
|
||||||
|
cl.append(arg)
|
||||||
|
return string.join(cl)
|
||||||
|
|
||||||
|
class CommandAction(_ActionAction):
|
||||||
|
"""Class for command-execution actions."""
|
||||||
|
def __init__(self, cmd, cmdstr=None, *args, **kw):
|
||||||
|
# Cmd can actually be a list or a single item; if it's a
|
||||||
|
# single item it should be the command string to execute; if a
|
||||||
|
# list then it should be the words of the command string to
|
||||||
|
# execute. Only a single command should be executed by this
|
||||||
|
# object; lists of commands should be handled by embedding
|
||||||
|
# these objects in a ListAction object (which the Action()
|
||||||
|
# factory above does). cmd will be passed to
|
||||||
|
# Environment.subst_list() for substituting environment
|
||||||
|
# variables.
|
||||||
|
if __debug__: logInstanceCreation(self, 'Action.CommandAction')
|
||||||
|
|
||||||
|
if not cmdstr is None:
|
||||||
|
if callable(cmdstr):
|
||||||
|
args = (cmdstr,)+args
|
||||||
|
elif not SCons.Util.is_String(cmdstr):
|
||||||
|
raise SCons.Errors.UserError(\
|
||||||
|
'Invalid command display variable type. ' \
|
||||||
|
'You must either pass a string or a callback which ' \
|
||||||
|
'accepts (target, source, env) as parameters.')
|
||||||
|
|
||||||
|
apply(_ActionAction.__init__, (self,)+args, kw)
|
||||||
|
if SCons.Util.is_List(cmd):
|
||||||
|
if filter(SCons.Util.is_List, cmd):
|
||||||
|
raise TypeError, "CommandAction should be given only " \
|
||||||
|
"a single command"
|
||||||
|
self.cmd_list = cmd
|
||||||
|
self.cmdstr = cmdstr
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if SCons.Util.is_List(self.cmd_list):
|
||||||
|
return string.join(map(str, self.cmd_list), ' ')
|
||||||
|
return str(self.cmd_list)
|
||||||
|
|
||||||
|
def process(self, target, source, env):
|
||||||
|
result = env.subst_list(self.cmd_list, 0, target, source)
|
||||||
|
silent = None
|
||||||
|
ignore = None
|
||||||
|
while 1:
|
||||||
|
try: c = result[0][0][0]
|
||||||
|
except IndexError: c = None
|
||||||
|
if c == '@': silent = 1
|
||||||
|
elif c == '-': ignore = 1
|
||||||
|
else: break
|
||||||
|
result[0][0] = result[0][0][1:]
|
||||||
|
try:
|
||||||
|
if not result[0][0]:
|
||||||
|
result[0] = result[0][1:]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
return result, ignore, silent
|
||||||
|
|
||||||
|
def strfunction(self, target, source, env):
|
||||||
|
if not self.cmdstr is None:
|
||||||
|
from SCons.Subst import SUBST_RAW
|
||||||
|
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
||||||
|
if c:
|
||||||
|
return c
|
||||||
|
cmd_list, ignore, silent = self.process(target, source, env)
|
||||||
|
if silent:
|
||||||
|
return ''
|
||||||
|
return _string_from_cmd_list(cmd_list[0])
|
||||||
|
|
||||||
|
def execute(self, target, source, env):
|
||||||
|
"""Execute a command action.
|
||||||
|
|
||||||
|
This will handle lists of commands as well as individual commands,
|
||||||
|
because construction variable substitution may turn a single
|
||||||
|
"command" into a list. This means that this class can actually
|
||||||
|
handle lists of commands, even though that's not how we use it
|
||||||
|
externally.
|
||||||
|
"""
|
||||||
|
from SCons.Subst import escape_list
|
||||||
|
import SCons.Util
|
||||||
|
flatten = SCons.Util.flatten
|
||||||
|
is_String = SCons.Util.is_String
|
||||||
|
is_List = SCons.Util.is_List
|
||||||
|
|
||||||
|
try:
|
||||||
|
shell = env['SHELL']
|
||||||
|
except KeyError:
|
||||||
|
raise SCons.Errors.UserError('Missing SHELL construction variable.')
|
||||||
|
|
||||||
|
try:
|
||||||
|
spawn = env['SPAWN']
|
||||||
|
except KeyError:
|
||||||
|
raise SCons.Errors.UserError('Missing SPAWN construction variable.')
|
||||||
|
else:
|
||||||
|
if is_String(spawn):
|
||||||
|
spawn = env.subst(spawn, raw=1, conv=lambda x: x)
|
||||||
|
|
||||||
|
escape = env.get('ESCAPE', lambda x: x)
|
||||||
|
|
||||||
|
try:
|
||||||
|
ENV = env['ENV']
|
||||||
|
except KeyError:
|
||||||
|
global default_ENV
|
||||||
|
if not default_ENV:
|
||||||
|
import SCons.Environment
|
||||||
|
default_ENV = SCons.Environment.Environment()['ENV']
|
||||||
|
ENV = default_ENV
|
||||||
|
|
||||||
|
# Ensure that the ENV values are all strings:
|
||||||
|
for key, value in ENV.items():
|
||||||
|
if not is_String(value):
|
||||||
|
if is_List(value):
|
||||||
|
# If the value is a list, then we assume it is a
|
||||||
|
# path list, because that's a pretty common list-like
|
||||||
|
# value to stick in an environment variable:
|
||||||
|
value = flatten(value)
|
||||||
|
ENV[key] = string.join(map(str, value), os.pathsep)
|
||||||
|
else:
|
||||||
|
# If it isn't a string or a list, then we just coerce
|
||||||
|
# it to a string, which is the proper way to handle
|
||||||
|
# Dir and File instances and will produce something
|
||||||
|
# reasonable for just about everything else:
|
||||||
|
ENV[key] = str(value)
|
||||||
|
|
||||||
|
cmd_list, ignore, silent = self.process(target, map(rfile, source), env)
|
||||||
|
|
||||||
|
# Use len() to filter out any "command" that's zero-length.
|
||||||
|
for cmd_line in filter(len, cmd_list):
|
||||||
|
# Escape the command line for the interpreter we are using.
|
||||||
|
cmd_line = escape_list(cmd_line, escape)
|
||||||
|
result = spawn(shell, escape, cmd_line[0], cmd_line, ENV)
|
||||||
|
if not ignore and result:
|
||||||
|
return result
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def get_contents(self, target, source, env):
|
||||||
|
"""Return the signature contents of this action's command line.
|
||||||
|
|
||||||
|
This strips $(-$) and everything in between the string,
|
||||||
|
since those parts don't affect signatures.
|
||||||
|
"""
|
||||||
|
from SCons.Subst import SUBST_SIG
|
||||||
|
cmd = self.cmd_list
|
||||||
|
if SCons.Util.is_List(cmd):
|
||||||
|
cmd = string.join(map(str, cmd))
|
||||||
|
else:
|
||||||
|
cmd = str(cmd)
|
||||||
|
return env.subst_target_source(cmd, SUBST_SIG, target, source)
|
||||||
|
|
||||||
|
class CommandGeneratorAction(ActionBase):
|
||||||
|
"""Class for command-generator actions."""
|
||||||
|
def __init__(self, generator, *args, **kw):
|
||||||
|
if __debug__: logInstanceCreation(self, 'Action.CommandGeneratorAction')
|
||||||
|
self.generator = generator
|
||||||
|
self.gen_args = args
|
||||||
|
self.gen_kw = kw
|
||||||
|
|
||||||
|
def _generate(self, target, source, env, for_signature):
|
||||||
|
# ensure that target is a list, to make it easier to write
|
||||||
|
# generator functions:
|
||||||
|
if not SCons.Util.is_List(target):
|
||||||
|
target = [target]
|
||||||
|
|
||||||
|
ret = self.generator(target=target, source=source, env=env, for_signature=for_signature)
|
||||||
|
gen_cmd = apply(Action, (ret,)+self.gen_args, self.gen_kw)
|
||||||
|
if not gen_cmd:
|
||||||
|
raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret))
|
||||||
|
return gen_cmd
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
try:
|
||||||
|
env = self.presub_env or {}
|
||||||
|
except AttributeError:
|
||||||
|
env = {}
|
||||||
|
act = self._generate([], [], env, 1)
|
||||||
|
return str(act)
|
||||||
|
|
||||||
|
def genstring(self, target, source, env):
|
||||||
|
return self._generate(target, source, env, 1).genstring(target, source, env)
|
||||||
|
|
||||||
|
def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
|
||||||
|
show=_null, execute=_null, chdir=_null):
|
||||||
|
act = self._generate(target, source, env, 0)
|
||||||
|
return act(target, source, env, exitstatfunc, presub,
|
||||||
|
show, execute, chdir)
|
||||||
|
|
||||||
|
def get_contents(self, target, source, env):
|
||||||
|
"""Return the signature contents of this action's command line.
|
||||||
|
|
||||||
|
This strips $(-$) and everything in between the string,
|
||||||
|
since those parts don't affect signatures.
|
||||||
|
"""
|
||||||
|
return self._generate(target, source, env, 1).get_contents(target, source, env)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# A LazyAction is a kind of hybrid generator and command action for
|
||||||
|
# strings of the form "$VAR". These strings normally expand to other
|
||||||
|
# strings (think "$CCCOM" to "$CC -c -o $TARGET $SOURCE"), but we also
|
||||||
|
# want to be able to replace them with functions in the construction
|
||||||
|
# environment. Consequently, we want lazy evaluation and creation of
|
||||||
|
# an Action in the case of the function, but that's overkill in the more
|
||||||
|
# normal case of expansion to other strings.
|
||||||
|
#
|
||||||
|
# So we do this with a subclass that's both a generator *and*
|
||||||
|
# a command action. The overridden methods all do a quick check
|
||||||
|
# of the construction variable, and if it's a string we just call
|
||||||
|
# the corresponding CommandAction method to do the heavy lifting.
|
||||||
|
# If not, then we call the same-named CommandGeneratorAction method.
|
||||||
|
# The CommandGeneratorAction methods work by using the overridden
|
||||||
|
# _generate() method, that is, our own way of handling "generation" of
|
||||||
|
# an action based on what's in the construction variable.
|
||||||
|
|
||||||
|
class LazyAction(CommandGeneratorAction, CommandAction):
|
||||||
|
|
||||||
|
def __init__(self, var, *args, **kw):
|
||||||
|
if __debug__: logInstanceCreation(self, 'Action.LazyAction')
|
||||||
|
apply(CommandAction.__init__, (self, '$'+var)+args, kw)
|
||||||
|
self.var = SCons.Util.to_String(var)
|
||||||
|
self.gen_args = args
|
||||||
|
self.gen_kw = kw
|
||||||
|
|
||||||
|
def get_parent_class(self, env):
|
||||||
|
c = env.get(self.var)
|
||||||
|
if SCons.Util.is_String(c) and not '\n' in c:
|
||||||
|
return CommandAction
|
||||||
|
return CommandGeneratorAction
|
||||||
|
|
||||||
|
def _generate_cache(self, env):
|
||||||
|
c = env.get(self.var, '')
|
||||||
|
gen_cmd = apply(Action, (c,)+self.gen_args, self.gen_kw)
|
||||||
|
if not gen_cmd:
|
||||||
|
raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c)))
|
||||||
|
return gen_cmd
|
||||||
|
|
||||||
|
def _generate(self, target, source, env, for_signature):
|
||||||
|
return self._generate_cache(env)
|
||||||
|
|
||||||
|
def __call__(self, target, source, env, *args, **kw):
|
||||||
|
args = (self, target, source, env) + args
|
||||||
|
c = self.get_parent_class(env)
|
||||||
|
return apply(c.__call__, args, kw)
|
||||||
|
|
||||||
|
def get_contents(self, target, source, env):
|
||||||
|
c = self.get_parent_class(env)
|
||||||
|
return c.get_contents(self, target, source, env)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionAction(_ActionAction):
|
||||||
|
"""Class for Python function actions."""
|
||||||
|
|
||||||
|
def __init__(self, execfunction, cmdstr=_null, *args, **kw):
|
||||||
|
if __debug__: logInstanceCreation(self, 'Action.FunctionAction')
|
||||||
|
|
||||||
|
if not cmdstr is _null:
|
||||||
|
if callable(cmdstr):
|
||||||
|
args = (cmdstr,)+args
|
||||||
|
elif not (cmdstr is None or SCons.Util.is_String(cmdstr)):
|
||||||
|
raise SCons.Errors.UserError(\
|
||||||
|
'Invalid function display variable type. ' \
|
||||||
|
'You must either pass a string or a callback which ' \
|
||||||
|
'accepts (target, source, env) as parameters.')
|
||||||
|
|
||||||
|
self.execfunction = execfunction
|
||||||
|
apply(_ActionAction.__init__, (self,)+args, kw)
|
||||||
|
self.varlist = kw.get('varlist', [])
|
||||||
|
self.cmdstr = cmdstr
|
||||||
|
|
||||||
|
def function_name(self):
|
||||||
|
try:
|
||||||
|
return self.execfunction.__name__
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
return self.execfunction.__class__.__name__
|
||||||
|
except AttributeError:
|
||||||
|
return "unknown_python_function"
|
||||||
|
|
||||||
|
def strfunction(self, target, source, env):
|
||||||
|
if self.cmdstr is None:
|
||||||
|
return None
|
||||||
|
if not self.cmdstr is _null:
|
||||||
|
from SCons.Subst import SUBST_RAW
|
||||||
|
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
||||||
|
if c:
|
||||||
|
return c
|
||||||
|
def array(a):
|
||||||
|
def quote(s):
|
||||||
|
return '"' + str(s) + '"'
|
||||||
|
return '[' + string.join(map(quote, a), ", ") + ']'
|
||||||
|
try:
|
||||||
|
strfunc = self.execfunction.strfunction
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if strfunc is None:
|
||||||
|
return None
|
||||||
|
if callable(strfunc):
|
||||||
|
return strfunc(target, source, env)
|
||||||
|
name = self.function_name()
|
||||||
|
tstr = array(target)
|
||||||
|
sstr = array(source)
|
||||||
|
return "%s(%s, %s)" % (name, tstr, sstr)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
name = self.function_name()
|
||||||
|
if name == 'ActionCaller':
|
||||||
|
return str(self.execfunction)
|
||||||
|
return "%s(target, source, env)" % name
|
||||||
|
|
||||||
|
def execute(self, target, source, env):
|
||||||
|
rsources = map(rfile, source)
|
||||||
|
try:
|
||||||
|
result = self.execfunction(target=target, source=rsources, env=env)
|
||||||
|
except EnvironmentError, e:
|
||||||
|
# If an IOError/OSError happens, raise a BuildError.
|
||||||
|
# Report the name of the file or directory that caused the
|
||||||
|
# error, which might be different from the target being built
|
||||||
|
# (for example, failure to create the directory in which the
|
||||||
|
# target file will appear).
|
||||||
|
try: filename = e.filename
|
||||||
|
except AttributeError: filename = None
|
||||||
|
raise SCons.Errors.BuildError(node=target,
|
||||||
|
errstr=e.strerror,
|
||||||
|
filename=filename)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_contents(self, target, source, env):
|
||||||
|
"""Return the signature contents of this callable action.
|
||||||
|
|
||||||
|
By providing direct access to the code object of the
|
||||||
|
function, Python makes this extremely easy. Hooray!
|
||||||
|
|
||||||
|
Unfortunately, older versions of Python include line
|
||||||
|
number indications in the compiled byte code. Boo!
|
||||||
|
So we remove the line number byte codes to prevent
|
||||||
|
recompilations from moving a Python function.
|
||||||
|
"""
|
||||||
|
execfunction = self.execfunction
|
||||||
|
try:
|
||||||
|
# Test if execfunction is a function.
|
||||||
|
code = execfunction.func_code.co_code
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
# Test if execfunction is a method.
|
||||||
|
code = execfunction.im_func.func_code.co_code
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
# Test if execfunction is a callable object.
|
||||||
|
code = execfunction.__call__.im_func.func_code.co_code
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
# See if execfunction will do the heavy lifting for us.
|
||||||
|
gc = self.execfunction.get_contents
|
||||||
|
except AttributeError:
|
||||||
|
# This is weird, just do the best we can.
|
||||||
|
contents = str(self.execfunction)
|
||||||
|
else:
|
||||||
|
contents = gc(target, source, env)
|
||||||
|
else:
|
||||||
|
contents = str(code)
|
||||||
|
else:
|
||||||
|
contents = str(code)
|
||||||
|
else:
|
||||||
|
contents = str(code)
|
||||||
|
contents = remove_set_lineno_codes(contents)
|
||||||
|
return contents + env.subst(string.join(map(lambda v: '${'+v+'}',
|
||||||
|
self.varlist)))
|
||||||
|
|
||||||
|
class ListAction(ActionBase):
|
||||||
|
"""Class for lists of other actions."""
|
||||||
|
def __init__(self, list):
|
||||||
|
if __debug__: logInstanceCreation(self, 'Action.ListAction')
|
||||||
|
def list_of_actions(x):
|
||||||
|
if isinstance(x, ActionBase):
|
||||||
|
return x
|
||||||
|
return Action(x)
|
||||||
|
self.list = map(list_of_actions, list)
|
||||||
|
|
||||||
|
def genstring(self, target, source, env):
|
||||||
|
return string.join(map(lambda a, t=target, s=source, e=env:
|
||||||
|
a.genstring(t, s, e),
|
||||||
|
self.list),
|
||||||
|
'\n')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return string.join(map(str, self.list), '\n')
|
||||||
|
|
||||||
|
def presub_lines(self, env):
|
||||||
|
return SCons.Util.flatten(map(lambda a, env=env:
|
||||||
|
a.presub_lines(env),
|
||||||
|
self.list))
|
||||||
|
|
||||||
|
def get_contents(self, target, source, env):
|
||||||
|
"""Return the signature contents of this action list.
|
||||||
|
|
||||||
|
Simple concatenation of the signatures of the elements.
|
||||||
|
"""
|
||||||
|
return string.join(map(lambda x, t=target, s=source, e=env:
|
||||||
|
x.get_contents(t, s, e),
|
||||||
|
self.list),
|
||||||
|
"")
|
||||||
|
|
||||||
|
def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
|
||||||
|
show=_null, execute=_null, chdir=_null):
|
||||||
|
for act in self.list:
|
||||||
|
stat = act(target, source, env, exitstatfunc, presub,
|
||||||
|
show, execute, chdir)
|
||||||
|
if stat:
|
||||||
|
return stat
|
||||||
|
return 0
|
||||||
|
|
||||||
|
class ActionCaller:
|
||||||
|
"""A class for delaying calling an Action function with specific
|
||||||
|
(positional and keyword) arguments until the Action is actually
|
||||||
|
executed.
|
||||||
|
|
||||||
|
This class looks to the rest of the world like a normal Action object,
|
||||||
|
but what it's really doing is hanging on to the arguments until we
|
||||||
|
have a target, source and env to use for the expansion.
|
||||||
|
"""
|
||||||
|
def __init__(self, parent, args, kw):
|
||||||
|
self.parent = parent
|
||||||
|
self.args = args
|
||||||
|
self.kw = kw
|
||||||
|
def get_contents(self, target, source, env):
|
||||||
|
actfunc = self.parent.actfunc
|
||||||
|
try:
|
||||||
|
# "self.actfunc" is a function.
|
||||||
|
contents = str(actfunc.func_code.co_code)
|
||||||
|
except AttributeError:
|
||||||
|
# "self.actfunc" is a callable object.
|
||||||
|
try:
|
||||||
|
contents = str(actfunc.__call__.im_func.func_code.co_code)
|
||||||
|
except AttributeError:
|
||||||
|
# No __call__() method, so it might be a builtin
|
||||||
|
# or something like that. Do the best we can.
|
||||||
|
contents = str(actfunc)
|
||||||
|
contents = remove_set_lineno_codes(contents)
|
||||||
|
return contents
|
||||||
|
def subst(self, s, target, source, env):
|
||||||
|
# Special-case hack: Let a custom function wrapped in an
|
||||||
|
# ActionCaller get at the environment through which the action
|
||||||
|
# was called by using this hard-coded value as a special return.
|
||||||
|
if s == '$__env__':
|
||||||
|
return env
|
||||||
|
else:
|
||||||
|
return env.subst(s, 0, target, source)
|
||||||
|
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),
|
||||||
|
self.args)
|
||||||
|
def subst_kw(self, target, source, env):
|
||||||
|
kw = {}
|
||||||
|
for key in self.kw.keys():
|
||||||
|
kw[key] = self.subst(self.kw[key], target, source, env)
|
||||||
|
return kw
|
||||||
|
def __call__(self, target, source, env):
|
||||||
|
args = self.subst_args(target, source, env)
|
||||||
|
kw = self.subst_kw(target, source, env)
|
||||||
|
return apply(self.parent.actfunc, args, kw)
|
||||||
|
def strfunction(self, target, source, env):
|
||||||
|
args = self.subst_args(target, source, env)
|
||||||
|
kw = self.subst_kw(target, source, env)
|
||||||
|
return apply(self.parent.strfunc, args, kw)
|
||||||
|
def __str__(self):
|
||||||
|
return apply(self.parent.strfunc, self.args, self.kw)
|
||||||
|
|
||||||
|
class ActionFactory:
|
||||||
|
"""A factory class that will wrap up an arbitrary function
|
||||||
|
as an SCons-executable Action object.
|
||||||
|
|
||||||
|
The real heavy lifting here is done by the ActionCaller class.
|
||||||
|
We just collect the (positional and keyword) arguments that we're
|
||||||
|
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):
|
||||||
|
self.actfunc = actfunc
|
||||||
|
self.strfunc = strfunc
|
||||||
|
def __call__(self, *args, **kw):
|
||||||
|
ac = ActionCaller(self, args, kw)
|
||||||
|
action = Action(ac, strfunction=ac.strfunction)
|
||||||
|
return action
|
|
@ -16,20 +16,9 @@ building new types of files in their configurations, without having to
|
||||||
dive any deeper into this subsystem.
|
dive any deeper into this subsystem.
|
||||||
|
|
||||||
The base class here is BuilderBase. This is a concrete base class which
|
The base class here is BuilderBase. This is a concrete base class which
|
||||||
does, in fact, represent most Builder objects that we (or users) create.
|
does, in fact, represent the Builder objects that we (or users) create.
|
||||||
|
|
||||||
There is (at present) one subclasses:
|
There is also a proxy that looks like a Builder:
|
||||||
|
|
||||||
MultiStepBuilder
|
|
||||||
|
|
||||||
This is a Builder that knows how to "chain" Builders so that
|
|
||||||
users can specify a source file that requires multiple steps
|
|
||||||
to turn into a target file. A canonical example is building a
|
|
||||||
program from yacc input file, which requires invoking a builder
|
|
||||||
to turn the .y into a .c, the .c into a .o, and the .o into an
|
|
||||||
executable program.
|
|
||||||
|
|
||||||
There is also two proxies that look like Builders:
|
|
||||||
|
|
||||||
CompositeBuilder
|
CompositeBuilder
|
||||||
|
|
||||||
|
@ -39,11 +28,6 @@ There is also two proxies that look like Builders:
|
||||||
(compilers, compile options) for different flavors of source
|
(compilers, compile options) for different flavors of source
|
||||||
files.
|
files.
|
||||||
|
|
||||||
ListBuilder
|
|
||||||
|
|
||||||
This proxies for a Builder *invocation* where the target
|
|
||||||
is a list of files, not a single file.
|
|
||||||
|
|
||||||
Builders and their proxies have the following public interface methods
|
Builders and their proxies have the following public interface methods
|
||||||
used by other modules:
|
used by other modules:
|
||||||
|
|
||||||
|
@ -95,7 +79,7 @@ There are the following methods for internal use within this module:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -117,7 +101,9 @@ There are the following methods for internal use within this module:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Builder.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Builder.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
|
|
||||||
import UserDict
|
import UserDict
|
||||||
import UserList
|
import UserList
|
||||||
|
@ -126,6 +112,8 @@ import SCons.Action
|
||||||
from SCons.Debug import logInstanceCreation
|
from SCons.Debug import logInstanceCreation
|
||||||
from SCons.Errors import InternalError, UserError
|
from SCons.Errors import InternalError, UserError
|
||||||
import SCons.Executor
|
import SCons.Executor
|
||||||
|
import SCons.Memoize
|
||||||
|
import SCons.Node
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
|
@ -142,6 +130,10 @@ class DictCmdGenerator(SCons.Util.Selector):
|
||||||
to return the proper action based on the file suffix of
|
to return the proper action based on the file suffix of
|
||||||
the source file."""
|
the source file."""
|
||||||
|
|
||||||
|
def __init__(self, dict=None, source_ext_match=1):
|
||||||
|
SCons.Util.Selector.__init__(self, dict)
|
||||||
|
self.source_ext_match = source_ext_match
|
||||||
|
|
||||||
def src_suffixes(self):
|
def src_suffixes(self):
|
||||||
return self.keys()
|
return self.keys()
|
||||||
|
|
||||||
|
@ -151,12 +143,18 @@ class DictCmdGenerator(SCons.Util.Selector):
|
||||||
self[suffix] = action
|
self[suffix] = action
|
||||||
|
|
||||||
def __call__(self, target, source, env, for_signature):
|
def __call__(self, target, source, env, for_signature):
|
||||||
ext = None
|
if not source:
|
||||||
for src in map(str, source):
|
return []
|
||||||
my_ext = SCons.Util.splitext(src)[1]
|
|
||||||
if ext and my_ext != ext:
|
if self.source_ext_match:
|
||||||
raise UserError("While building `%s' from `%s': Cannot build multiple sources with different extensions: %s, %s" % (repr(map(str, target)), src, ext, my_ext))
|
ext = None
|
||||||
ext = my_ext
|
for src in map(str, source):
|
||||||
|
my_ext = SCons.Util.splitext(src)[1]
|
||||||
|
if ext and my_ext != ext:
|
||||||
|
raise UserError("While building `%s' from `%s': Cannot build multiple sources with different extensions: %s, %s" % (repr(map(str, target)), src, ext, my_ext))
|
||||||
|
ext = my_ext
|
||||||
|
else:
|
||||||
|
ext = SCons.Util.splitext(str(source[0]))[1]
|
||||||
|
|
||||||
if not ext:
|
if not ext:
|
||||||
raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source))))
|
raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source))))
|
||||||
|
@ -166,7 +164,8 @@ class DictCmdGenerator(SCons.Util.Selector):
|
||||||
except KeyError, e:
|
except KeyError, e:
|
||||||
raise UserError("Ambiguous suffixes after environment substitution: %s == %s == %s" % (e[0], e[1], e[2]))
|
raise UserError("Ambiguous suffixes after environment substitution: %s == %s == %s" % (e[0], e[1], e[2]))
|
||||||
if ret is None:
|
if ret is None:
|
||||||
raise UserError("While building `%s': Don't know how to build a file with suffix `%s'." % (repr(map(str, target)), ext))
|
raise UserError("While building `%s' from `%s': Don't know how to build from a source file with suffix `%s'. Expected a suffix in this list: %s." % \
|
||||||
|
(repr(map(str, target)), repr(map(str, source)), ext, repr(self.keys())))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
class CallableSelector(SCons.Util.Selector):
|
class CallableSelector(SCons.Util.Selector):
|
||||||
|
@ -214,25 +213,22 @@ class OverrideWarner(UserDict.UserDict):
|
||||||
"""A class for warning about keyword arguments that we use as
|
"""A class for warning about keyword arguments that we use as
|
||||||
overrides in a Builder call.
|
overrides in a Builder call.
|
||||||
|
|
||||||
This class exists to handle the fact that a single MultiStepBuilder
|
This class exists to handle the fact that a single Builder call
|
||||||
call can actually invoke multiple builders as a result of a single
|
can actually invoke multiple builders. This class only emits the
|
||||||
user-level Builder call. This class only emits the warnings once,
|
warnings once, no matter how many Builders are invoked.
|
||||||
no matter how many Builders are invoked.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, dict):
|
def __init__(self, dict):
|
||||||
UserDict.UserDict.__init__(self, dict)
|
UserDict.UserDict.__init__(self, dict)
|
||||||
|
if __debug__: logInstanceCreation(self, 'Builder.OverrideWarner')
|
||||||
self.already_warned = None
|
self.already_warned = None
|
||||||
def warn(self):
|
def warn(self):
|
||||||
if self.already_warned:
|
if self.already_warned:
|
||||||
return
|
return
|
||||||
for k in self.keys():
|
for k in self.keys():
|
||||||
try:
|
if misleading_keywords.has_key(k):
|
||||||
alt = misleading_keywords[k]
|
alt = misleading_keywords[k]
|
||||||
except KeyError:
|
msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k)
|
||||||
pass
|
SCons.Warnings.warn(SCons.Warnings.MisleadingKeywordsWarning, msg)
|
||||||
else:
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.MisleadingKeywordsWarning,
|
|
||||||
"Did you mean to use `%s' instead of `%s'?" % (alt, k))
|
|
||||||
self.already_warned = 1
|
self.already_warned = 1
|
||||||
|
|
||||||
def Builder(**kw):
|
def Builder(**kw):
|
||||||
|
@ -241,12 +237,18 @@ def Builder(**kw):
|
||||||
if kw.has_key('generator'):
|
if kw.has_key('generator'):
|
||||||
if kw.has_key('action'):
|
if kw.has_key('action'):
|
||||||
raise UserError, "You must not specify both an action and a generator."
|
raise UserError, "You must not specify both an action and a generator."
|
||||||
kw['action'] = SCons.Action.CommandGenerator(kw['generator'])
|
kw['action'] = SCons.Action.CommandGeneratorAction(kw['generator'])
|
||||||
del kw['generator']
|
del kw['generator']
|
||||||
elif kw.has_key('action') and SCons.Util.is_Dict(kw['action']):
|
elif kw.has_key('action'):
|
||||||
composite = DictCmdGenerator(kw['action'])
|
source_ext_match = kw.get('source_ext_match', 1)
|
||||||
kw['action'] = SCons.Action.CommandGenerator(composite)
|
if kw.has_key('source_ext_match'):
|
||||||
kw['src_suffix'] = composite.src_suffixes()
|
del kw['source_ext_match']
|
||||||
|
if SCons.Util.is_Dict(kw['action']):
|
||||||
|
composite = DictCmdGenerator(kw['action'], source_ext_match)
|
||||||
|
kw['action'] = SCons.Action.CommandGeneratorAction(composite)
|
||||||
|
kw['src_suffix'] = composite.src_suffixes()
|
||||||
|
else:
|
||||||
|
kw['action'] = SCons.Action.Action(kw['action'])
|
||||||
|
|
||||||
if kw.has_key('emitter'):
|
if kw.has_key('emitter'):
|
||||||
emitter = kw['emitter']
|
emitter = kw['emitter']
|
||||||
|
@ -264,100 +266,51 @@ def Builder(**kw):
|
||||||
elif SCons.Util.is_List(emitter):
|
elif SCons.Util.is_List(emitter):
|
||||||
kw['emitter'] = ListEmitter(emitter)
|
kw['emitter'] = ListEmitter(emitter)
|
||||||
|
|
||||||
if kw.has_key('src_builder'):
|
result = apply(BuilderBase, (), kw)
|
||||||
ret = apply(MultiStepBuilder, (), kw)
|
|
||||||
else:
|
|
||||||
ret = apply(BuilderBase, (), kw)
|
|
||||||
|
|
||||||
if not composite is None:
|
if not composite is None:
|
||||||
ret = CompositeBuilder(ret, composite)
|
result = CompositeBuilder(result, composite)
|
||||||
|
|
||||||
return ret
|
return result
|
||||||
|
|
||||||
def _init_nodes(builder, env, overrides, tlist, slist):
|
def _node_errors(builder, env, tlist, slist):
|
||||||
"""Initialize lists of target and source nodes with all of
|
"""Validate that the lists of target and source nodes are
|
||||||
the proper Builder information.
|
legal for this builder and environment. Raise errors or
|
||||||
|
issue warnings as appropriate.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# First, figure out if there are any errors in the way the targets
|
# First, figure out if there are any errors in the way the targets
|
||||||
# were specified.
|
# were specified.
|
||||||
for t in tlist:
|
for t in tlist:
|
||||||
if t.side_effect:
|
if t.side_effect:
|
||||||
raise UserError, "Multiple ways to build the same target were specified for: %s" % str(t)
|
raise UserError, "Multiple ways to build the same target were specified for: %s" % t
|
||||||
if t.has_builder():
|
if t.has_explicit_builder():
|
||||||
if not t.env is None and not t.env is env:
|
if not t.env is None and not t.env is env:
|
||||||
t_contents = t.builder.action.get_contents(tlist, slist, t.env)
|
action = t.builder.action
|
||||||
contents = t.builder.action.get_contents(tlist, slist, env)
|
t_contents = action.get_contents(tlist, slist, t.env)
|
||||||
|
contents = action.get_contents(tlist, slist, env)
|
||||||
|
|
||||||
if t_contents == contents:
|
if t_contents == contents:
|
||||||
SCons.Warnings.warn(SCons.Warnings.DuplicateEnvironmentWarning,
|
msg = "Two different environments were specified for target %s,\n\tbut they appear to have the same action: %s" % (t, action.genstring(tlist, slist, t.env))
|
||||||
"Two different environments were specified for target %s,\n\tbut they appear to have the same action: %s"%(str(t), t.builder.action.strfunction(tlist, slist, t.env)))
|
SCons.Warnings.warn(SCons.Warnings.DuplicateEnvironmentWarning, msg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise UserError, "Two environments with different actions were specified for the same target: %s"%str(t)
|
msg = "Two environments with different actions were specified for the same target: %s" % t
|
||||||
|
raise UserError, msg
|
||||||
elif t.overrides != overrides:
|
|
||||||
raise UserError, "Two different sets of overrides were specified for the same target: %s"%str(t)
|
|
||||||
|
|
||||||
elif builder.target_scanner and t.target_scanner and builder.target_scanner != t.target_scanner:
|
|
||||||
raise UserError, "Two different scanners were specified for the same target: %s"%str(t)
|
|
||||||
|
|
||||||
if builder.multi:
|
if builder.multi:
|
||||||
if t.builder != builder:
|
if t.builder != builder:
|
||||||
if isinstance(t.builder, ListBuilder) and isinstance(builder, ListBuilder) and t.builder.builder == builder.builder:
|
msg = "Two different builders (%s and %s) were specified for the same target: %s" % (t.builder.get_name(env), builder.get_name(env), t)
|
||||||
raise UserError, "Two different target sets have a target in common: %s"%str(t)
|
raise UserError, msg
|
||||||
else:
|
if t.get_executor().targets != tlist:
|
||||||
raise UserError, "Two different builders (%s and %s) were specified for the same target: %s"%(t.builder.get_name(env), builder.get_name(env), str(t))
|
msg = "Two different target lists have a target in common: %s (from %s and from %s)" % (t, map(str, t.get_executor().targets), map(str, tlist))
|
||||||
|
raise UserError, msg
|
||||||
elif t.sources != slist:
|
elif t.sources != slist:
|
||||||
raise UserError, "Multiple ways to build the same target were specified for: %s" % str(t)
|
msg = "Multiple ways to build the same target were specified for: %s (from %s and from %s)" % (t, map(str, t.sources), map(str, slist))
|
||||||
|
raise UserError, msg
|
||||||
|
|
||||||
if builder.single_source:
|
if builder.single_source:
|
||||||
if len(slist) > 1:
|
if len(slist) > 1:
|
||||||
raise UserError, "More than one source given for single-source builder: targets=%s sources=%s" % (map(str,tlist), map(str,slist))
|
raise UserError, "More than one source given for single-source builder: targets=%s sources=%s" % (map(str,tlist), map(str,slist))
|
||||||
|
|
||||||
# The targets are fine, so find or make the appropriate Executor to
|
|
||||||
# build this particular list of targets from this particular list of
|
|
||||||
# sources.
|
|
||||||
executor = None
|
|
||||||
if builder.multi:
|
|
||||||
try:
|
|
||||||
executor = tlist[0].get_executor(create = 0)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
executor.add_sources(slist)
|
|
||||||
if executor is None:
|
|
||||||
executor = SCons.Executor.Executor(builder.action,
|
|
||||||
env or builder.env,
|
|
||||||
[builder.overrides, overrides],
|
|
||||||
tlist,
|
|
||||||
slist)
|
|
||||||
|
|
||||||
# Now set up the relevant information in the target Nodes themselves.
|
|
||||||
for t in tlist:
|
|
||||||
t.overrides = overrides
|
|
||||||
t.cwd = SCons.Node.FS.default_fs.getcwd()
|
|
||||||
t.builder_set(builder)
|
|
||||||
t.env_set(env)
|
|
||||||
t.add_source(slist)
|
|
||||||
t.set_executor(executor)
|
|
||||||
if builder.target_scanner:
|
|
||||||
t.target_scanner = builder.target_scanner
|
|
||||||
if t.source_scanner is None:
|
|
||||||
t.source_scanner = builder.source_scanner
|
|
||||||
|
|
||||||
# Add backup source scanners from the environment to the source
|
|
||||||
# nodes. This may not be necessary if the node will have a real
|
|
||||||
# source scanner added later (which is why these are the "backup"
|
|
||||||
# source scanners, not the real ones), but because source nodes may
|
|
||||||
# be used multiple times for different targets, it ends up being
|
|
||||||
# more efficient to do this calculation once here, as opposed to
|
|
||||||
# delaying it until later when we potentially have to calculate it
|
|
||||||
# over and over and over.
|
|
||||||
for s in slist:
|
|
||||||
if s.source_scanner is None and s.backup_source_scanner is None:
|
|
||||||
s.backup_source_scanner = env.get_scanner(s.scanner_key())
|
|
||||||
|
|
||||||
class EmitterProxy:
|
class EmitterProxy:
|
||||||
"""This is a callable class that can act as a
|
"""This is a callable class that can act as a
|
||||||
Builder emitter. It holds on to a string that
|
Builder emitter. It holds on to a string that
|
||||||
|
@ -393,28 +346,37 @@ class BuilderBase:
|
||||||
nodes (files) from input nodes (files).
|
nodes (files) from input nodes (files).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if SCons.Memoize.use_memoizer:
|
||||||
|
__metaclass__ = SCons.Memoize.Memoized_Metaclass
|
||||||
|
|
||||||
|
memoizer_counters = []
|
||||||
|
|
||||||
def __init__(self, action = None,
|
def __init__(self, action = None,
|
||||||
prefix = '',
|
prefix = '',
|
||||||
suffix = '',
|
suffix = '',
|
||||||
src_suffix = '',
|
src_suffix = '',
|
||||||
target_factory = SCons.Node.FS.default_fs.File,
|
target_factory = None,
|
||||||
source_factory = SCons.Node.FS.default_fs.File,
|
source_factory = None,
|
||||||
target_scanner = None,
|
target_scanner = None,
|
||||||
source_scanner = None,
|
source_scanner = None,
|
||||||
emitter = None,
|
emitter = None,
|
||||||
multi = 0,
|
multi = 0,
|
||||||
env = None,
|
env = None,
|
||||||
single_source = 0,
|
single_source = 0,
|
||||||
|
name = None,
|
||||||
|
chdir = _null,
|
||||||
|
is_explicit = 1,
|
||||||
|
src_builder = [],
|
||||||
**overrides):
|
**overrides):
|
||||||
if __debug__: logInstanceCreation(self, 'BuilderBase')
|
if __debug__: logInstanceCreation(self, 'Builder.BuilderBase')
|
||||||
self.action = SCons.Action.Action(action)
|
self._memo = {}
|
||||||
|
self.action = action
|
||||||
self.multi = multi
|
self.multi = multi
|
||||||
if SCons.Util.is_Dict(prefix):
|
if SCons.Util.is_Dict(prefix):
|
||||||
prefix = CallableSelector(prefix)
|
prefix = CallableSelector(prefix)
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
if SCons.Util.is_Dict(suffix):
|
if SCons.Util.is_Dict(suffix):
|
||||||
suffix = CallableSelector(suffix)
|
suffix = CallableSelector(suffix)
|
||||||
self.suffix = suffix
|
|
||||||
self.env = env
|
self.env = env
|
||||||
self.single_source = single_source
|
self.single_source = single_source
|
||||||
if overrides.has_key('overrides'):
|
if overrides.has_key('overrides'):
|
||||||
|
@ -423,8 +385,14 @@ class BuilderBase:
|
||||||
"\tspecify the items as keyword arguments to the Builder() call instead.")
|
"\tspecify the items as keyword arguments to the Builder() call instead.")
|
||||||
overrides.update(overrides['overrides'])
|
overrides.update(overrides['overrides'])
|
||||||
del overrides['overrides']
|
del overrides['overrides']
|
||||||
|
if overrides.has_key('scanner'):
|
||||||
|
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
|
||||||
|
"The \"scanner\" keyword to Builder() creation has been deprecated;\n"
|
||||||
|
"\tuse: source_scanner or target_scanner as appropriate.")
|
||||||
|
del overrides['scanner']
|
||||||
self.overrides = overrides
|
self.overrides = overrides
|
||||||
|
|
||||||
|
self.set_suffix(suffix)
|
||||||
self.set_src_suffix(src_suffix)
|
self.set_src_suffix(src_suffix)
|
||||||
|
|
||||||
self.target_factory = target_factory
|
self.target_factory = target_factory
|
||||||
|
@ -434,6 +402,19 @@ class BuilderBase:
|
||||||
|
|
||||||
self.emitter = emitter
|
self.emitter = emitter
|
||||||
|
|
||||||
|
# Optional Builder name should only be used for Builders
|
||||||
|
# that don't get attached to construction environments.
|
||||||
|
if name:
|
||||||
|
self.name = name
|
||||||
|
self.executor_kw = {}
|
||||||
|
if not chdir is _null:
|
||||||
|
self.executor_kw['chdir'] = chdir
|
||||||
|
self.is_explicit = is_explicit
|
||||||
|
|
||||||
|
if not SCons.Util.is_List(src_builder):
|
||||||
|
src_builder = [ src_builder ]
|
||||||
|
self.src_builder = src_builder
|
||||||
|
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
raise InternalError, "Do not test for the Node.builder attribute directly; use Node.has_builder() instead"
|
raise InternalError, "Do not test for the Node.builder attribute directly; use Node.has_builder() instead"
|
||||||
|
|
||||||
|
@ -442,21 +423,51 @@ class BuilderBase:
|
||||||
|
|
||||||
Look at the BUILDERS variable of env, expecting it to be a
|
Look at the BUILDERS variable of env, expecting it to be a
|
||||||
dictionary containing this Builder, and return the key of the
|
dictionary containing this Builder, and return the key of the
|
||||||
dictionary."""
|
dictionary. If there's no key, then return a directly-configured
|
||||||
|
name (if there is one) or the name of the class (by default)."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
index = env['BUILDERS'].values().index(self)
|
index = env['BUILDERS'].values().index(self)
|
||||||
return env['BUILDERS'].keys()[index]
|
return env['BUILDERS'].keys()[index]
|
||||||
except (AttributeError, KeyError, ValueError):
|
except (AttributeError, KeyError, TypeError, ValueError):
|
||||||
return str(self.__class__)
|
try:
|
||||||
|
return self.name
|
||||||
|
except AttributeError:
|
||||||
|
return str(self.__class__)
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
return cmp(self.__dict__, other.__dict__)
|
return cmp(self.__dict__, other.__dict__)
|
||||||
|
|
||||||
def splitext(self, path):
|
def splitext(self, path, env=None):
|
||||||
|
if not env:
|
||||||
|
env = self.env
|
||||||
|
if env:
|
||||||
|
matchsuf = filter(lambda S,path=path: path[-len(S):] == S,
|
||||||
|
self.src_suffixes(env))
|
||||||
|
if matchsuf:
|
||||||
|
suf = max(map(None, map(len, matchsuf), matchsuf))[1]
|
||||||
|
return [path[:-len(suf)], path[-len(suf):]]
|
||||||
return SCons.Util.splitext(path)
|
return SCons.Util.splitext(path)
|
||||||
|
|
||||||
def _create_nodes(self, env, overwarn, target = None, source = None):
|
def get_single_executor(self, env, tlist, slist, executor_kw):
|
||||||
|
if not self.action:
|
||||||
|
raise UserError, "Builder %s must have an action to build %s."%(self.get_name(env or self.env), map(str,tlist))
|
||||||
|
return self.action.get_executor(env or self.env,
|
||||||
|
[], # env already has overrides
|
||||||
|
tlist,
|
||||||
|
slist,
|
||||||
|
executor_kw)
|
||||||
|
|
||||||
|
def get_multi_executor(self, env, tlist, slist, executor_kw):
|
||||||
|
try:
|
||||||
|
executor = tlist[0].get_executor(create = 0)
|
||||||
|
except (AttributeError, IndexError):
|
||||||
|
return self.get_single_executor(env, tlist, slist, executor_kw)
|
||||||
|
else:
|
||||||
|
executor.add_sources(slist)
|
||||||
|
return executor
|
||||||
|
|
||||||
|
def _create_nodes(self, env, target = None, source = None):
|
||||||
"""Create and return lists of target and source nodes.
|
"""Create and return lists of target and source nodes.
|
||||||
"""
|
"""
|
||||||
def _adjustixes(files, pre, suf):
|
def _adjustixes(files, pre, suf):
|
||||||
|
@ -472,14 +483,13 @@ class BuilderBase:
|
||||||
result.append(f)
|
result.append(f)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
overwarn.warn()
|
|
||||||
|
|
||||||
env = env.Override(overwarn.data)
|
|
||||||
|
|
||||||
src_suf = self.get_src_suffix(env)
|
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 = _adjustixes(source, None, src_suf)
|
||||||
slist = env.arg2nodes(source, self.source_factory)
|
slist = env.arg2nodes(source, source_factory)
|
||||||
|
|
||||||
pre = self.get_prefix(env, slist)
|
pre = self.get_prefix(env, slist)
|
||||||
suf = self.get_suffix(env, slist)
|
suf = self.get_suffix(env, slist)
|
||||||
|
@ -489,10 +499,14 @@ class BuilderBase:
|
||||||
t_from_s = slist[0].target_from_source
|
t_from_s = slist[0].target_from_source
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise UserError("Do not know how to create a target from source `%s'" % slist[0])
|
raise UserError("Do not know how to create a target from source `%s'" % slist[0])
|
||||||
tlist = [ t_from_s(pre, suf, self.splitext) ]
|
except IndexError:
|
||||||
|
tlist = []
|
||||||
|
else:
|
||||||
|
splitext = lambda S,self=self,env=env: self.splitext(S,env)
|
||||||
|
tlist = [ t_from_s(pre, suf, splitext) ]
|
||||||
else:
|
else:
|
||||||
target = _adjustixes(target, pre, suf)
|
target = _adjustixes(target, pre, suf)
|
||||||
tlist = env.arg2nodes(target, self.target_factory)
|
tlist = env.arg2nodes(target, target_factory)
|
||||||
|
|
||||||
if self.emitter:
|
if self.emitter:
|
||||||
# The emitter is going to do str(node), but because we're
|
# The emitter is going to do str(node), but because we're
|
||||||
|
@ -503,58 +517,97 @@ class BuilderBase:
|
||||||
new_targets = []
|
new_targets = []
|
||||||
for t in tlist:
|
for t in tlist:
|
||||||
if not t.is_derived():
|
if not t.is_derived():
|
||||||
t.builder = self
|
t.builder_set(self)
|
||||||
new_targets.append(t)
|
new_targets.append(t)
|
||||||
|
|
||||||
target, source = self.emitter(target=tlist, source=slist, env=env)
|
target, source = self.emitter(target=tlist, source=slist, env=env)
|
||||||
|
|
||||||
# Now delete the temporary builders that we attached to any
|
# Now delete the temporary builders that we attached to any
|
||||||
# new targets, so that _init_nodes() doesn't do weird stuff
|
# new targets, so that _node_errors() doesn't do weird stuff
|
||||||
# to them because it thinks they already have builders.
|
# to them because it thinks they already have builders.
|
||||||
for t in new_targets:
|
for t in new_targets:
|
||||||
if t.builder is self:
|
if t.builder is self:
|
||||||
# Only delete the temporary builder if the emitter
|
# Only delete the temporary builder if the emitter
|
||||||
# didn't change it on us.
|
# didn't change it on us.
|
||||||
t.builder = None
|
t.builder_set(None)
|
||||||
|
|
||||||
# Have to call arg2nodes yet again, since it is legal for
|
# Have to call arg2nodes yet again, since it is legal for
|
||||||
# emitters to spit out strings as well as Node instances.
|
# emitters to spit out strings as well as Node instances.
|
||||||
slist = env.arg2nodes(source, self.source_factory)
|
tlist = env.arg2nodes(target, target_factory)
|
||||||
tlist = env.arg2nodes(target, self.target_factory)
|
slist = env.arg2nodes(source, source_factory)
|
||||||
|
|
||||||
return tlist, slist
|
return tlist, slist
|
||||||
|
|
||||||
def _execute(self, env, target = None, source = _null, overwarn={}):
|
def _execute(self, env, target, source, overwarn={}, executor_kw={}):
|
||||||
if source is _null:
|
# We now assume that target and source are lists or None.
|
||||||
source = target
|
if self.src_builder:
|
||||||
target = None
|
source = self.src_builder_sources(env, source, overwarn)
|
||||||
|
|
||||||
if(self.single_source and
|
if self.single_source and len(source) > 1 and target is None:
|
||||||
SCons.Util.is_List(source) and
|
|
||||||
len(source) > 1 and
|
|
||||||
target is None):
|
|
||||||
result = []
|
result = []
|
||||||
if target is None: target = [None]*len(source)
|
if target is None: target = [None]*len(source)
|
||||||
for k in range(len(source)):
|
for tgt, src in zip(target, source):
|
||||||
t = self._execute(env, target[k], source[k], overwarn)
|
if not tgt is None: tgt = [tgt]
|
||||||
if SCons.Util.is_List(t):
|
if not src is None: src = [src]
|
||||||
result.extend(t)
|
result.extend(self._execute(env, tgt, src, overwarn))
|
||||||
else:
|
|
||||||
result.append(t)
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
tlist, slist = self._create_nodes(env, overwarn, target, source)
|
overwarn.warn()
|
||||||
|
|
||||||
if len(tlist) == 1:
|
tlist, slist = self._create_nodes(env, target, source)
|
||||||
builder = self
|
|
||||||
|
# Check for errors with the specified target/source lists.
|
||||||
|
_node_errors(self, env, tlist, slist)
|
||||||
|
|
||||||
|
# The targets are fine, so find or make the appropriate Executor to
|
||||||
|
# build this particular list of targets from this particular list of
|
||||||
|
# sources.
|
||||||
|
if self.multi:
|
||||||
|
get_executor = self.get_multi_executor
|
||||||
else:
|
else:
|
||||||
builder = ListBuilder(self, env, tlist)
|
get_executor = self.get_single_executor
|
||||||
_init_nodes(builder, env, overwarn.data, tlist, slist)
|
executor = get_executor(env, tlist, slist, executor_kw)
|
||||||
|
|
||||||
return tlist
|
# Now set up the relevant information in the target Nodes themselves.
|
||||||
|
for t in tlist:
|
||||||
|
t.cwd = env.fs.getcwd()
|
||||||
|
t.builder_set(self)
|
||||||
|
t.env_set(env)
|
||||||
|
t.add_source(slist)
|
||||||
|
t.set_executor(executor)
|
||||||
|
t.set_explicit(self.is_explicit)
|
||||||
|
|
||||||
def __call__(self, env, target = None, source = _null, **kw):
|
return SCons.Node.NodeList(tlist)
|
||||||
return self._execute(env, target, source, OverrideWarner(kw))
|
|
||||||
|
def __call__(self, env, target=None, source=None, chdir=_null, **kw):
|
||||||
|
# We now assume that target and source are lists or None.
|
||||||
|
# The caller (typically Environment.BuilderWrapper) is
|
||||||
|
# responsible for converting any scalar values to lists.
|
||||||
|
if chdir is _null:
|
||||||
|
ekw = self.executor_kw
|
||||||
|
else:
|
||||||
|
ekw = self.executor_kw.copy()
|
||||||
|
ekw['chdir'] = chdir
|
||||||
|
if kw:
|
||||||
|
if kw.has_key('srcdir'):
|
||||||
|
def prependDirIfRelative(f, srcdir=kw['srcdir']):
|
||||||
|
import os.path
|
||||||
|
if SCons.Util.is_String(f) and not os.path.isabs(f):
|
||||||
|
f = os.path.join(srcdir, f)
|
||||||
|
return f
|
||||||
|
if not SCons.Util.is_List(source):
|
||||||
|
source = [source]
|
||||||
|
source = map(prependDirIfRelative, source)
|
||||||
|
del kw['srcdir']
|
||||||
|
if self.overrides:
|
||||||
|
env_kw = self.overrides.copy()
|
||||||
|
env_kw.update(kw)
|
||||||
|
else:
|
||||||
|
env_kw = kw
|
||||||
|
else:
|
||||||
|
env_kw = self.overrides
|
||||||
|
env = env.Override(env_kw)
|
||||||
|
return self._execute(env, target, source, OverrideWarner(kw), ekw)
|
||||||
|
|
||||||
def adjust_suffix(self, suff):
|
def adjust_suffix(self, suff):
|
||||||
if suff and not suff[0] in [ '.', '_', '$' ]:
|
if suff and not suff[0] in [ '.', '_', '$' ]:
|
||||||
|
@ -567,24 +620,25 @@ class BuilderBase:
|
||||||
prefix = prefix(env, sources)
|
prefix = prefix(env, sources)
|
||||||
return env.subst(prefix)
|
return env.subst(prefix)
|
||||||
|
|
||||||
|
def set_suffix(self, suffix):
|
||||||
|
if not callable(suffix):
|
||||||
|
suffix = self.adjust_suffix(suffix)
|
||||||
|
self.suffix = suffix
|
||||||
|
|
||||||
def get_suffix(self, env, sources=[]):
|
def get_suffix(self, env, sources=[]):
|
||||||
suffix = self.suffix
|
suffix = self.suffix
|
||||||
if callable(suffix):
|
if callable(suffix):
|
||||||
suffix = suffix(env, sources)
|
suffix = suffix(env, sources)
|
||||||
else:
|
|
||||||
suffix = self.adjust_suffix(suffix)
|
|
||||||
return env.subst(suffix)
|
return env.subst(suffix)
|
||||||
|
|
||||||
def src_suffixes(self, env):
|
|
||||||
return map(lambda x, s=self, e=env: e.subst(s.adjust_suffix(x)),
|
|
||||||
self.src_suffix)
|
|
||||||
|
|
||||||
def set_src_suffix(self, src_suffix):
|
def set_src_suffix(self, src_suffix):
|
||||||
if not src_suffix:
|
if not src_suffix:
|
||||||
src_suffix = []
|
src_suffix = []
|
||||||
elif not SCons.Util.is_List(src_suffix):
|
elif not SCons.Util.is_List(src_suffix):
|
||||||
src_suffix = [ src_suffix ]
|
src_suffix = [ src_suffix ]
|
||||||
self.src_suffix = src_suffix
|
adjust = lambda suf, s=self: \
|
||||||
|
callable(suf) and suf or s.adjust_suffix(suf)
|
||||||
|
self.src_suffix = map(adjust, src_suffix)
|
||||||
|
|
||||||
def get_src_suffix(self, env):
|
def get_src_suffix(self, env):
|
||||||
"""Get the first src_suffix in the list of src_suffixes."""
|
"""Get the first src_suffix in the list of src_suffixes."""
|
||||||
|
@ -610,145 +664,167 @@ class BuilderBase:
|
||||||
"""
|
"""
|
||||||
self.emitter[suffix] = emitter
|
self.emitter[suffix] = emitter
|
||||||
|
|
||||||
class ListBuilder(SCons.Util.Proxy):
|
def add_src_builder(self, builder):
|
||||||
"""A Proxy to support building an array of targets (for example,
|
|
||||||
foo.o and foo.h from foo.y) from a single Action execution.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, builder, env, tlist):
|
|
||||||
if __debug__: logInstanceCreation(self)
|
|
||||||
SCons.Util.Proxy.__init__(self, builder)
|
|
||||||
self.builder = builder
|
|
||||||
self.target_scanner = builder.target_scanner
|
|
||||||
self.source_scanner = builder.source_scanner
|
|
||||||
self.env = env
|
|
||||||
self.tlist = tlist
|
|
||||||
self.multi = builder.multi
|
|
||||||
self.single_source = builder.single_source
|
|
||||||
|
|
||||||
def targets(self, node):
|
|
||||||
"""Return the list of targets for this builder instance.
|
|
||||||
"""
|
"""
|
||||||
return self.tlist
|
Add a new Builder to the list of src_builders.
|
||||||
|
|
||||||
def __cmp__(self, other):
|
This requires wiping out cached values so that the computed
|
||||||
return cmp(self.__dict__, other.__dict__)
|
lists of source suffixes get re-calculated.
|
||||||
|
"""
|
||||||
|
self._memo = {}
|
||||||
|
self.src_builder.append(builder)
|
||||||
|
|
||||||
def get_name(self, env):
|
def _get_sdict(self, env):
|
||||||
"""Attempts to get the name of the Builder."""
|
"""
|
||||||
|
Returns a dictionary mapping all of the source suffixes of all
|
||||||
|
src_builders of this Builder to the underlying Builder that
|
||||||
|
should be called first.
|
||||||
|
|
||||||
return "ListBuilder(%s)" % self.builder.get_name(env)
|
This dictionary is used for each target specified, so we save a
|
||||||
|
lot of extra computation by memoizing it for each construction
|
||||||
|
environment.
|
||||||
|
|
||||||
class MultiStepBuilder(BuilderBase):
|
Note that this is re-computed each time, not cached, because there
|
||||||
"""This is a builder subclass that can build targets in
|
might be changes to one of our source Builders (or one of their
|
||||||
multiple steps. The src_builder parameter to the constructor
|
source Builders, and so on, and so on...) that we can't "see."
|
||||||
accepts a builder that is called to build sources supplied to
|
|
||||||
this builder. The targets of that first build then become
|
|
||||||
the sources of this builder.
|
|
||||||
|
|
||||||
If this builder has a src_suffix supplied, then the src_builder
|
The underlying methods we call cache their computed values,
|
||||||
builder is NOT invoked if the suffix of a source file matches
|
though, so we hope repeatedly aggregating them into a dictionary
|
||||||
src_suffix.
|
like this won't be too big a hit. We may need to look for a
|
||||||
"""
|
better way to do this if performance data show this has turned
|
||||||
def __init__(self, src_builder,
|
into a significant bottleneck.
|
||||||
action = None,
|
"""
|
||||||
prefix = '',
|
sdict = {}
|
||||||
suffix = '',
|
for bld in self.get_src_builders(env):
|
||||||
src_suffix = '',
|
for suf in bld.src_suffixes(env):
|
||||||
target_factory = SCons.Node.FS.default_fs.File,
|
sdict[suf] = bld
|
||||||
source_factory = SCons.Node.FS.default_fs.File,
|
return sdict
|
||||||
target_scanner = None,
|
|
||||||
source_scanner = None,
|
|
||||||
emitter=None,
|
|
||||||
single_source=0):
|
|
||||||
if __debug__: logInstanceCreation(self)
|
|
||||||
BuilderBase.__init__(self, action, prefix, suffix, src_suffix,
|
|
||||||
target_factory, source_factory,
|
|
||||||
target_scanner, source_scanner, emitter,
|
|
||||||
single_source = single_source)
|
|
||||||
if not SCons.Util.is_List(src_builder):
|
|
||||||
src_builder = [ src_builder ]
|
|
||||||
self.src_builder = src_builder
|
|
||||||
self.sdict = {}
|
|
||||||
self.cached_src_suffixes = {} # source suffixes keyed on id(env)
|
|
||||||
|
|
||||||
def _execute(self, env, target = None, source = _null, overwarn={}):
|
def src_builder_sources(self, env, source, overwarn={}):
|
||||||
if source is _null:
|
source_factory = env.get_factory(self.source_factory)
|
||||||
source = target
|
slist = env.arg2nodes(source, source_factory)
|
||||||
target = None
|
|
||||||
|
|
||||||
slist = env.arg2nodes(source, self.source_factory)
|
sdict = self._get_sdict(env)
|
||||||
final_sources = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
sdict = self.sdict[id(env)]
|
|
||||||
except KeyError:
|
|
||||||
sdict = {}
|
|
||||||
self.sdict[id(env)] = sdict
|
|
||||||
for bld in self.src_builder:
|
|
||||||
if SCons.Util.is_String(bld):
|
|
||||||
try:
|
|
||||||
bld = env['BUILDERS'][bld]
|
|
||||||
except KeyError:
|
|
||||||
continue
|
|
||||||
for suf in bld.src_suffixes(env):
|
|
||||||
sdict[suf] = bld
|
|
||||||
|
|
||||||
src_suffixes = self.src_suffixes(env)
|
src_suffixes = self.src_suffixes(env)
|
||||||
|
|
||||||
for snode in slist:
|
lengths_dict = {}
|
||||||
try:
|
for l in map(len, src_suffixes):
|
||||||
get_suffix = snode.get_suffix
|
lengths_dict[l] = None
|
||||||
except AttributeError:
|
lengths = lengths_dict.keys()
|
||||||
ext = self.splitext(str(snode))
|
|
||||||
else:
|
|
||||||
ext = get_suffix()
|
|
||||||
try:
|
|
||||||
subsidiary_builder = sdict[ext]
|
|
||||||
except KeyError:
|
|
||||||
final_sources.append(snode)
|
|
||||||
else:
|
|
||||||
tgt = subsidiary_builder._execute(env, None, snode, 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(tgt) > 1:
|
|
||||||
tgt = filter(lambda x, self=self, suf=src_suffixes:
|
|
||||||
self.splitext(SCons.Util.to_String(x))[1] in suf,
|
|
||||||
tgt)
|
|
||||||
final_sources.extend(tgt)
|
|
||||||
|
|
||||||
return BuilderBase._execute(self, env, target, final_sources, overwarn)
|
def match_src_suffix(node, src_suffixes=src_suffixes, lengths=lengths):
|
||||||
|
node_suffixes = map(lambda l, n=node: n.name[-l:], lengths)
|
||||||
|
for suf in src_suffixes:
|
||||||
|
if suf in node_suffixes:
|
||||||
|
return suf
|
||||||
|
return None
|
||||||
|
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for snode in slist:
|
||||||
|
match_suffix = match_src_suffix(snode)
|
||||||
|
if match_suffix:
|
||||||
|
try:
|
||||||
|
bld = sdict[match_suffix]
|
||||||
|
except KeyError:
|
||||||
|
result.append(snode)
|
||||||
|
else:
|
||||||
|
tlist = bld._execute(env, None, [snode], 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)
|
||||||
|
result.extend(tlist)
|
||||||
|
else:
|
||||||
|
result.append(snode)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _get_src_builders_key(self, env):
|
||||||
|
return id(env)
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountDict('get_src_builders', _get_src_builders_key))
|
||||||
|
|
||||||
def get_src_builders(self, env):
|
def get_src_builders(self, env):
|
||||||
"""Return all the src_builders for this Builder.
|
|
||||||
|
|
||||||
This is essentially a recursive descent of the src_builder "tree."
|
|
||||||
"""
|
"""
|
||||||
ret = []
|
Returns the list of source Builders for this Builder.
|
||||||
|
|
||||||
|
This exists mainly to look up Builders referenced as
|
||||||
|
strings in the 'BUILDER' variable of the construction
|
||||||
|
environment and cache the result.
|
||||||
|
"""
|
||||||
|
memo_key = id(env)
|
||||||
|
try:
|
||||||
|
memo_dict = self._memo['get_src_builders']
|
||||||
|
except KeyError:
|
||||||
|
memo_dict = {}
|
||||||
|
self._memo['get_src_builders'] = memo_dict
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return memo_dict[memo_key]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
builders = []
|
||||||
for bld in self.src_builder:
|
for bld in self.src_builder:
|
||||||
if SCons.Util.is_String(bld):
|
if SCons.Util.is_String(bld):
|
||||||
# All Environments should have a BUILDERS
|
|
||||||
# variable, so no need to check for it.
|
|
||||||
try:
|
try:
|
||||||
bld = env['BUILDERS'][bld]
|
bld = env['BUILDERS'][bld]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
continue
|
continue
|
||||||
ret.append(bld)
|
builders.append(bld)
|
||||||
return ret
|
|
||||||
|
memo_dict[memo_key] = builders
|
||||||
|
return builders
|
||||||
|
|
||||||
|
def _subst_src_suffixes_key(self, env):
|
||||||
|
return id(env)
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountDict('subst_src_suffixes', _subst_src_suffixes_key))
|
||||||
|
|
||||||
|
def subst_src_suffixes(self, env):
|
||||||
|
"""
|
||||||
|
The suffix list may contain construction variable expansions,
|
||||||
|
so we have to evaluate the individual strings. To avoid doing
|
||||||
|
this over and over, we memoize the results for each construction
|
||||||
|
environment.
|
||||||
|
"""
|
||||||
|
memo_key = id(env)
|
||||||
|
try:
|
||||||
|
memo_dict = self._memo['subst_src_suffixes']
|
||||||
|
except KeyError:
|
||||||
|
memo_dict = {}
|
||||||
|
self._memo['subst_src_suffixes'] = memo_dict
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return memo_dict[memo_key]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
suffixes = map(lambda x, s=self, e=env: e.subst(x), self.src_suffix)
|
||||||
|
memo_dict[memo_key] = suffixes
|
||||||
|
return suffixes
|
||||||
|
|
||||||
def src_suffixes(self, env):
|
def src_suffixes(self, env):
|
||||||
"""Return a list of the src_suffix attributes for all
|
|
||||||
src_builders of this Builder.
|
|
||||||
"""
|
"""
|
||||||
try:
|
Returns the list of source suffixes for all src_builders of this
|
||||||
return self.cached_src_suffixes[id(env)]
|
Builder.
|
||||||
except KeyError:
|
|
||||||
suffixes = BuilderBase.src_suffixes(self, env)
|
This is essentially a recursive descent of the src_builder "tree."
|
||||||
for builder in self.get_src_builders(env):
|
(This value isn't cached because there may be changes in a
|
||||||
suffixes.extend(builder.src_suffixes(env))
|
src_builder many levels deep that we can't see.)
|
||||||
self.cached_src_suffixes[id(env)] = suffixes
|
"""
|
||||||
return suffixes
|
sdict = {}
|
||||||
|
suffixes = self.subst_src_suffixes(env)
|
||||||
|
for s in suffixes:
|
||||||
|
sdict[s] = 1
|
||||||
|
for builder in self.get_src_builders(env):
|
||||||
|
for s in builder.src_suffixes(env):
|
||||||
|
if not sdict.has_key(s):
|
||||||
|
sdict[s] = 1
|
||||||
|
suffixes.append(s)
|
||||||
|
return suffixes
|
||||||
|
|
||||||
class CompositeBuilder(SCons.Util.Proxy):
|
class CompositeBuilder(SCons.Util.Proxy):
|
||||||
"""A Builder Proxy whose main purpose is to always have
|
"""A Builder Proxy whose main purpose is to always have
|
||||||
|
@ -757,7 +833,7 @@ class CompositeBuilder(SCons.Util.Proxy):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, builder, cmdgen):
|
def __init__(self, builder, cmdgen):
|
||||||
if __debug__: logInstanceCreation(self)
|
if __debug__: logInstanceCreation(self, 'Builder.CompositeBuilder')
|
||||||
SCons.Util.Proxy.__init__(self, builder)
|
SCons.Util.Proxy.__init__(self, builder)
|
||||||
|
|
||||||
# cmdgen should always be an instance of DictCmdGenerator.
|
# cmdgen should always be an instance of DictCmdGenerator.
|
||||||
|
@ -767,6 +843,3 @@ class CompositeBuilder(SCons.Util.Proxy):
|
||||||
def add_action(self, suffix, action):
|
def add_action(self, suffix, action):
|
||||||
self.cmdgen.add_action(suffix, action)
|
self.cmdgen.add_action(suffix, action)
|
||||||
self.set_src_suffix(self.cmdgen.src_suffixes())
|
self.set_src_suffix(self.cmdgen.src_suffixes())
|
||||||
|
|
||||||
def __cmp__(self, other):
|
|
||||||
return cmp(self.__dict__, other.__dict__)
|
|
|
@ -78,6 +78,9 @@ Autoconf-like configuration support; low level implementation of tests.
|
||||||
# The file must not exist or be empty when starting.
|
# The file must not exist or be empty when starting.
|
||||||
# Empty or None to skip this (some tests will not work!).
|
# Empty or None to skip this (some tests will not work!).
|
||||||
#
|
#
|
||||||
|
# context.config_h (may be missing). If present, must be a string, which
|
||||||
|
# will be filled with the contents of a config_h file.
|
||||||
|
#
|
||||||
# context.vardict Dictionary holding variables used for the tests and
|
# context.vardict Dictionary holding variables used for the tests and
|
||||||
# stores results from the tests, used for the build
|
# stores results from the tests, used for the build
|
||||||
# commands.
|
# commands.
|
||||||
|
@ -91,9 +94,17 @@ Autoconf-like configuration support; low level implementation of tests.
|
||||||
# be a number and "SYSTEMNAME" a string.
|
# be a number and "SYSTEMNAME" a string.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import re
|
||||||
import string
|
import string
|
||||||
from types import IntType
|
from types import IntType
|
||||||
|
|
||||||
|
#
|
||||||
|
# PUBLIC VARIABLES
|
||||||
|
#
|
||||||
|
|
||||||
|
LogInputFiles = 1 # Set that to log the input files in case of a failed test
|
||||||
|
LogErrorMessages = 1 # Set that to log Conftest-generated error messages
|
||||||
|
|
||||||
#
|
#
|
||||||
# PUBLIC FUNCTIONS
|
# PUBLIC FUNCTIONS
|
||||||
#
|
#
|
||||||
|
@ -121,9 +132,10 @@ def CheckBuilder(context, text = None, language = None):
|
||||||
|
|
||||||
if not text:
|
if not text:
|
||||||
text = """
|
text = """
|
||||||
int main() {
|
int main() {
|
||||||
return 0;
|
return 0;
|
||||||
}\n\n"""
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
context.Display("Checking if building a %s file works... " % lang)
|
context.Display("Checking if building a %s file works... " % lang)
|
||||||
ret = context.BuildProg(text, suffix)
|
ret = context.BuildProg(text, suffix)
|
||||||
|
@ -164,10 +176,10 @@ def CheckFunc(context, function_name, header = None, language = None):
|
||||||
includetext = ''
|
includetext = ''
|
||||||
if not header:
|
if not header:
|
||||||
header = """
|
header = """
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
#endif
|
#endif
|
||||||
char %s();""" % function_name
|
char %s();""" % function_name
|
||||||
|
|
||||||
lang, suffix, msg = _lang2suffix(language)
|
lang, suffix, msg = _lang2suffix(language)
|
||||||
if msg:
|
if msg:
|
||||||
|
@ -175,21 +187,22 @@ def CheckFunc(context, function_name, header = None, language = None):
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
text = """
|
text = """
|
||||||
%(include)s
|
%(include)s
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
%(hdr)s
|
%(hdr)s
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
#if defined (__stub_%(name)s) || defined (__stub___%(name)s)
|
#if defined (__stub_%(name)s) || defined (__stub___%(name)s)
|
||||||
fail fail fail
|
fail fail fail
|
||||||
#else
|
#else
|
||||||
%(name)s();
|
%(name)s();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}\n\n""" % { 'name': function_name,
|
}
|
||||||
'include': includetext,
|
""" % { 'name': function_name,
|
||||||
'hdr': header }
|
'include': includetext,
|
||||||
|
'hdr': header }
|
||||||
|
|
||||||
context.Display("Checking for %s function %s()... " % (lang, function_name))
|
context.Display("Checking for %s function %s()... " % (lang, function_name))
|
||||||
ret = context.BuildProg(text, suffix)
|
ret = context.BuildProg(text, suffix)
|
||||||
|
@ -282,17 +295,18 @@ def CheckType(context, type_name, fallback = None,
|
||||||
# - Using "sizeof(TYPE)" is valid when TYPE is actually a variable.
|
# - Using "sizeof(TYPE)" is valid when TYPE is actually a variable.
|
||||||
# - Using the previous two together works reliably.
|
# - Using the previous two together works reliably.
|
||||||
text = """
|
text = """
|
||||||
%(include)s
|
%(include)s
|
||||||
%(header)s
|
%(header)s
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
if ((%(name)s *) 0)
|
if ((%(name)s *) 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (sizeof (%(name)s))
|
if (sizeof (%(name)s))
|
||||||
return 0;
|
return 0;
|
||||||
}\n\n""" % { 'include': includetext,
|
}
|
||||||
'header': header,
|
""" % { 'include': includetext,
|
||||||
'name': type_name }
|
'header': header,
|
||||||
|
'name': type_name }
|
||||||
|
|
||||||
context.Display("Checking for %s type %s... " % (lang, type_name))
|
context.Display("Checking for %s type %s... " % (lang, type_name))
|
||||||
ret = context.BuildProg(text, suffix)
|
ret = context.BuildProg(text, suffix)
|
||||||
|
@ -305,7 +319,7 @@ def CheckType(context, type_name, fallback = None,
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def CheckLib(context, libs, func_name, header = None,
|
def CheckLib(context, libs, func_name = None, header = None,
|
||||||
extra_libs = None, call = None, language = None, autoadd = 1):
|
extra_libs = None, call = None, language = None, autoadd = 1):
|
||||||
"""
|
"""
|
||||||
Configure check for a C or C++ libraries "libs". Searches through
|
Configure check for a C or C++ libraries "libs". Searches through
|
||||||
|
@ -319,7 +333,8 @@ def CheckLib(context, libs, func_name, header = None,
|
||||||
depends on.
|
depends on.
|
||||||
Optional "call" replaces the call to "func_name" in the test code. It must
|
Optional "call" replaces the call to "func_name" in the test code. It must
|
||||||
consist of complete C statements, including a trailing ";".
|
consist of complete C statements, including a trailing ";".
|
||||||
There must either be a "func_name" or a "call" argument (or both).
|
Both "func_name" and "call" arguments are optional, and in that case, just
|
||||||
|
linking against the libs is tested.
|
||||||
"language" should be "C" or "C++" and is used to select the compiler.
|
"language" should be "C" or "C++" and is used to select the compiler.
|
||||||
Default is "C".
|
Default is "C".
|
||||||
Note that this uses the current value of compiler and linker flags, make
|
Note that this uses the current value of compiler and linker flags, make
|
||||||
|
@ -335,35 +350,40 @@ def CheckLib(context, libs, func_name, header = None,
|
||||||
header = ""
|
header = ""
|
||||||
|
|
||||||
text = """
|
text = """
|
||||||
%s
|
%s
|
||||||
%s """ % (includetext, header)
|
%s""" % (includetext, header)
|
||||||
|
|
||||||
# Add a function declaration if needed.
|
# Add a function declaration if needed.
|
||||||
if func_name and func_name != "main" and not header:
|
if func_name and func_name != "main":
|
||||||
text = text + """
|
if not header:
|
||||||
#ifdef __cplusplus
|
text = text + """
|
||||||
extern "C"
|
#ifdef __cplusplus
|
||||||
#endif
|
extern "C"
|
||||||
char %s();""" % func_name
|
#endif
|
||||||
|
char %s();
|
||||||
|
""" % func_name
|
||||||
|
|
||||||
# The actual test code.
|
# The actual test code.
|
||||||
if not call:
|
if not call:
|
||||||
call = "%s();" % func_name
|
call = "%s();" % func_name
|
||||||
|
|
||||||
|
# if no function to test, leave main() blank
|
||||||
text = text + """
|
text = text + """
|
||||||
int
|
int
|
||||||
main() {
|
main() {
|
||||||
%s
|
%s
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
\n\n""" % call
|
""" % (call or "")
|
||||||
|
|
||||||
i = string.find(call, "\n")
|
if call:
|
||||||
if i > 0:
|
i = string.find(call, "\n")
|
||||||
calltext = call[:i] + ".."
|
if i > 0:
|
||||||
elif call[-1] == ';':
|
calltext = call[:i] + ".."
|
||||||
calltext = call[:-1]
|
elif call[-1] == ';':
|
||||||
else:
|
calltext = call[:-1]
|
||||||
calltext = call
|
else:
|
||||||
|
calltext = call
|
||||||
|
|
||||||
for lib_name in libs:
|
for lib_name in libs:
|
||||||
|
|
||||||
|
@ -372,8 +392,15 @@ def CheckLib(context, libs, func_name, header = None,
|
||||||
context.Display("Cannot check for library %s: %s\n" % (lib_name, msg))
|
context.Display("Cannot check for library %s: %s\n" % (lib_name, msg))
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
context.Display("Checking for %s in %s library %s... "
|
# if a function was specified to run in main(), say it
|
||||||
% (calltext, lang, lib_name))
|
if call:
|
||||||
|
context.Display("Checking for %s in %s library %s... "
|
||||||
|
% (calltext, lang, lib_name))
|
||||||
|
# otherwise, just say the name of library and language
|
||||||
|
else:
|
||||||
|
context.Display("Checking for %s library %s... "
|
||||||
|
% (lang, lib_name))
|
||||||
|
|
||||||
if lib_name:
|
if lib_name:
|
||||||
l = [ lib_name ]
|
l = [ lib_name ]
|
||||||
if extra_libs:
|
if extra_libs:
|
||||||
|
@ -390,7 +417,7 @@ def CheckLib(context, libs, func_name, header = None,
|
||||||
if oldLIBS != -1 and (ret or not autoadd):
|
if oldLIBS != -1 and (ret or not autoadd):
|
||||||
context.SetLIBS(oldLIBS)
|
context.SetLIBS(oldLIBS)
|
||||||
|
|
||||||
if ret == "":
|
if not ret:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -418,8 +445,8 @@ def _YesNoResult(context, ret, key, text):
|
||||||
def _Have(context, key, have):
|
def _Have(context, key, have):
|
||||||
"""
|
"""
|
||||||
Store result of a test in context.havedict and context.headerfilename.
|
Store result of a test in context.havedict and context.headerfilename.
|
||||||
"key" is a "HAVE_abc" name. It is turned into all CAPITALS and ":./" are
|
"key" is a "HAVE_abc" name. It is turned into all CAPITALS and non-
|
||||||
replaced by an underscore.
|
alphanumerics are replaced by an underscore.
|
||||||
The value of "have" can be:
|
The value of "have" can be:
|
||||||
1 - Feature is defined, add "#define key".
|
1 - Feature is defined, add "#define key".
|
||||||
0 - Feature is not defined, add "/* #undef key */".
|
0 - Feature is not defined, add "/* #undef key */".
|
||||||
|
@ -432,22 +459,23 @@ def _Have(context, key, have):
|
||||||
when desired and escape special characters!
|
when desired and escape special characters!
|
||||||
"""
|
"""
|
||||||
key_up = string.upper(key)
|
key_up = string.upper(key)
|
||||||
key_up = string.replace(key_up, ':', '_')
|
key_up = re.sub('[^A-Z0-9_]', '_', key_up)
|
||||||
key_up = string.replace(key_up, '.', '_')
|
|
||||||
key_up = string.replace(key_up, '/', '_')
|
|
||||||
key_up = string.replace(key_up, ' ', '_')
|
|
||||||
context.havedict[key_up] = have
|
context.havedict[key_up] = have
|
||||||
|
if have == 1:
|
||||||
|
line = "#define %s\n" % key_up
|
||||||
|
elif have == 0:
|
||||||
|
line = "/* #undef %s */\n" % key_up
|
||||||
|
elif type(have) == IntType:
|
||||||
|
line = "#define %s %d\n" % (key_up, have)
|
||||||
|
else:
|
||||||
|
line = "#define %s %s\n" % (key_up, str(have))
|
||||||
|
|
||||||
if context.headerfilename:
|
if context.headerfilename:
|
||||||
f = open(context.headerfilename, "a")
|
f = open(context.headerfilename, "a")
|
||||||
if have == 1:
|
f.write(line)
|
||||||
f.write("#define %s\n" % key_up)
|
|
||||||
elif have == 0:
|
|
||||||
f.write("/* #undef %s */\n" % key_up)
|
|
||||||
elif type(have) == IntType:
|
|
||||||
f.write("#define %s %d\n" % (key_up, have))
|
|
||||||
else:
|
|
||||||
f.write("#define %s %s\n" % (key_up, str(have)))
|
|
||||||
f.close()
|
f.close()
|
||||||
|
elif hasattr(context,'config_h'):
|
||||||
|
context.config_h = context.config_h + line
|
||||||
|
|
||||||
|
|
||||||
def _LogFailed(context, text, msg):
|
def _LogFailed(context, text, msg):
|
||||||
|
@ -455,15 +483,17 @@ def _LogFailed(context, text, msg):
|
||||||
Write to the log about a failed program.
|
Write to the log about a failed program.
|
||||||
Add line numbers, so that error messages can be understood.
|
Add line numbers, so that error messages can be understood.
|
||||||
"""
|
"""
|
||||||
context.Log("Failed program was:\n")
|
if LogInputFiles:
|
||||||
lines = string.split(text, '\n')
|
context.Log("Failed program was:\n")
|
||||||
if len(lines) and lines[-1] == '':
|
lines = string.split(text, '\n')
|
||||||
lines = lines[:-1] # remove trailing empty line
|
if len(lines) and lines[-1] == '':
|
||||||
n = 1
|
lines = lines[:-1] # remove trailing empty line
|
||||||
for line in lines:
|
n = 1
|
||||||
context.Log("%d: %s\n" % (n, line))
|
for line in lines:
|
||||||
n = n + 1
|
context.Log("%d: %s\n" % (n, line))
|
||||||
context.Log("Error message: %s\n" % msg)
|
n = n + 1
|
||||||
|
if LogErrorMessages:
|
||||||
|
context.Log("Error message: %s\n" % msg)
|
||||||
|
|
||||||
|
|
||||||
def _lang2suffix(lang):
|
def _lang2suffix(lang):
|
|
@ -7,7 +7,7 @@ needed by most users.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -29,12 +29,13 @@ needed by most users.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Debug.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Debug.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import os
|
||||||
# Recipe 14.10 from the Python Cookbook.
|
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
# Recipe 14.10 from the Python Cookbook.
|
||||||
try:
|
try:
|
||||||
import weakref
|
import weakref
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -60,6 +61,10 @@ def string_to_classes(s):
|
||||||
else:
|
else:
|
||||||
return string.split(s)
|
return string.split(s)
|
||||||
|
|
||||||
|
def fetchLoggedInstances(classes="*"):
|
||||||
|
classnames = string_to_classes(classes)
|
||||||
|
return map(lambda cn: (cn, len(tracked_classes[cn])), classnames)
|
||||||
|
|
||||||
def countLoggedInstances(classes, file=sys.stdout):
|
def countLoggedInstances(classes, file=sys.stdout):
|
||||||
for classname in string_to_classes(classes):
|
for classname in string_to_classes(classes):
|
||||||
file.write("%s: %d\n" % (classname, len(tracked_classes[classname])))
|
file.write("%s: %d\n" % (classname, len(tracked_classes[classname])))
|
||||||
|
@ -94,9 +99,101 @@ else:
|
||||||
try:
|
try:
|
||||||
import resource
|
import resource
|
||||||
except ImportError:
|
except ImportError:
|
||||||
def memory():
|
try:
|
||||||
return 0
|
import win32process
|
||||||
|
import win32api
|
||||||
|
except ImportError:
|
||||||
|
def memory():
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
def memory():
|
||||||
|
process_handle = win32api.GetCurrentProcess()
|
||||||
|
memory_info = win32process.GetProcessMemoryInfo( process_handle )
|
||||||
|
return memory_info['PeakWorkingSetSize']
|
||||||
else:
|
else:
|
||||||
def memory():
|
def memory():
|
||||||
res = resource.getrusage(resource.RUSAGE_SELF)
|
res = resource.getrusage(resource.RUSAGE_SELF)
|
||||||
return res[4]
|
return res[4]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
caller_dicts = {}
|
||||||
|
|
||||||
|
def caller(*backlist):
|
||||||
|
import traceback
|
||||||
|
if not backlist:
|
||||||
|
backlist = [0]
|
||||||
|
result = []
|
||||||
|
for back in backlist:
|
||||||
|
tb = traceback.extract_stack(limit=3+back)
|
||||||
|
key = tb[1][:3]
|
||||||
|
try:
|
||||||
|
entry = caller_dicts[key]
|
||||||
|
except KeyError:
|
||||||
|
entry = caller_dicts[key] = {}
|
||||||
|
key = tb[0][:3]
|
||||||
|
entry[key] = entry.get(key, 0) + 1
|
||||||
|
result.append('%s:%d(%s)' % func_shorten(key))
|
||||||
|
return result
|
||||||
|
|
||||||
|
def dump_caller_counts(file=sys.stdout):
|
||||||
|
keys = caller_dicts.keys()
|
||||||
|
keys.sort()
|
||||||
|
for k in keys:
|
||||||
|
file.write("Callers of %s:%d(%s):\n" % func_shorten(k))
|
||||||
|
counts = caller_dicts[k]
|
||||||
|
callers = counts.keys()
|
||||||
|
callers.sort()
|
||||||
|
for c in callers:
|
||||||
|
#file.write(" counts[%s] = %s\n" % (c, counts[c]))
|
||||||
|
t = ((counts[c],) + func_shorten(c))
|
||||||
|
file.write(" %6d %s:%d(%s)\n" % t)
|
||||||
|
|
||||||
|
shorten_list = [
|
||||||
|
( '/scons/SCons/', 1),
|
||||||
|
( '/src/engine/SCons/', 1),
|
||||||
|
( '/usr/lib/python', 0),
|
||||||
|
]
|
||||||
|
|
||||||
|
if os.sep != '/':
|
||||||
|
def platformize(t):
|
||||||
|
return (string.replace(t[0], '/', os.sep), t[1])
|
||||||
|
shorten_list = map(platformize, shorten_list)
|
||||||
|
del platformize
|
||||||
|
|
||||||
|
def func_shorten(func_tuple):
|
||||||
|
f = func_tuple[0]
|
||||||
|
for t in shorten_list:
|
||||||
|
i = string.find(f, t[0])
|
||||||
|
if i >= 0:
|
||||||
|
if t[1]:
|
||||||
|
i = i + len(t[0])
|
||||||
|
f = f[i:]
|
||||||
|
break
|
||||||
|
return (f,)+func_tuple[1:]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TraceFP = {}
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
TraceDefault = 'con'
|
||||||
|
else:
|
||||||
|
TraceDefault = '/dev/tty'
|
||||||
|
|
||||||
|
def Trace(msg, file=None, mode='w'):
|
||||||
|
"""Write a trace message to a file. Whenever a file is specified,
|
||||||
|
it becomes the default for the next call to Trace()."""
|
||||||
|
global TraceDefault
|
||||||
|
if file is None:
|
||||||
|
file = TraceDefault
|
||||||
|
else:
|
||||||
|
TraceDefault = file
|
||||||
|
try:
|
||||||
|
fp = TraceFP[file]
|
||||||
|
except KeyError:
|
||||||
|
try:
|
||||||
|
fp = TraceFP[file] = open(file, mode)
|
||||||
|
except TypeError:
|
||||||
|
# Assume we were passed an open file pointer.
|
||||||
|
fp = file
|
||||||
|
fp.write(msg)
|
449
scons/scons-local-0.97/SCons/Defaults.py
Normal file
449
scons/scons-local-0.97/SCons/Defaults.py
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
"""SCons.Defaults
|
||||||
|
|
||||||
|
Builders and other things for the local site. Here's where we'll
|
||||||
|
duplicate the functionality of autoconf until we move it into the
|
||||||
|
installation procedure or use something like qmconf.
|
||||||
|
|
||||||
|
The code that reads the registry to find MSVC components was borrowed
|
||||||
|
from distutils.msvccompiler.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Defaults.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import shutil
|
||||||
|
import stat
|
||||||
|
import time
|
||||||
|
import types
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
|
import SCons.Builder
|
||||||
|
import SCons.Environment
|
||||||
|
import SCons.PathList
|
||||||
|
import SCons.Sig
|
||||||
|
import SCons.Subst
|
||||||
|
import SCons.Tool
|
||||||
|
|
||||||
|
# A placeholder for a default Environment (for fetching source files
|
||||||
|
# from source code management systems and the like). This must be
|
||||||
|
# initialized later, after the top-level directory is set by the calling
|
||||||
|
# interface.
|
||||||
|
_default_env = None
|
||||||
|
|
||||||
|
# Lazily instantiate the default environment so the overhead of creating
|
||||||
|
# it doesn't apply when it's not needed.
|
||||||
|
def DefaultEnvironment(*args, **kw):
|
||||||
|
global _default_env
|
||||||
|
if not _default_env:
|
||||||
|
_default_env = apply(SCons.Environment.Environment, args, kw)
|
||||||
|
_default_env._build_signature = 1
|
||||||
|
_default_env._calc_module = SCons.Sig.default_module
|
||||||
|
return _default_env
|
||||||
|
|
||||||
|
# Emitters for setting the shared attribute on object files,
|
||||||
|
# and an action for checking that all of the source files
|
||||||
|
# going into a shared library are, in fact, shared.
|
||||||
|
def StaticObjectEmitter(target, source, env):
|
||||||
|
for tgt in target:
|
||||||
|
tgt.attributes.shared = None
|
||||||
|
return (target, source)
|
||||||
|
|
||||||
|
def SharedObjectEmitter(target, source, env):
|
||||||
|
for tgt in target:
|
||||||
|
tgt.attributes.shared = 1
|
||||||
|
return (target, source)
|
||||||
|
|
||||||
|
def SharedFlagChecker(source, target, env):
|
||||||
|
same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME')
|
||||||
|
if same == '0' or same == '' or same == 'False':
|
||||||
|
for src in source:
|
||||||
|
try:
|
||||||
|
shared = src.attributes.shared
|
||||||
|
except AttributeError:
|
||||||
|
shared = None
|
||||||
|
if not shared:
|
||||||
|
raise SCons.Errors.UserError, "Source file: %s is static and is not compatible with shared target: %s" % (src, target[0])
|
||||||
|
|
||||||
|
SharedCheck = SCons.Action.Action(SharedFlagChecker, None)
|
||||||
|
|
||||||
|
# Some people were using these variable name before we made
|
||||||
|
# SourceFileScanner part of the public interface. Don't break their
|
||||||
|
# SConscript files until we've given them some fair warning and a
|
||||||
|
# transition period.
|
||||||
|
CScan = SCons.Tool.CScanner
|
||||||
|
DScan = SCons.Tool.DScanner
|
||||||
|
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.
|
||||||
|
import SCons.Scanner.Dir
|
||||||
|
DirScanner = SCons.Scanner.Dir.DirScanner()
|
||||||
|
DirEntryScanner = SCons.Scanner.Dir.DirEntryScanner()
|
||||||
|
|
||||||
|
# Actions for common languages.
|
||||||
|
CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR")
|
||||||
|
ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR")
|
||||||
|
CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR")
|
||||||
|
ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR")
|
||||||
|
|
||||||
|
ASAction = SCons.Action.Action("$ASCOM", "$ASCOMSTR")
|
||||||
|
ASPPAction = SCons.Action.Action("$ASPPCOM", "$ASPPCOMSTR")
|
||||||
|
|
||||||
|
LinkAction = SCons.Action.Action("$LINKCOM", "$LINKCOMSTR")
|
||||||
|
ShLinkAction = SCons.Action.Action("$SHLINKCOM", "$SHLINKCOMSTR")
|
||||||
|
|
||||||
|
LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR")
|
||||||
|
|
||||||
|
# Common tasks that we allow users to perform in platform-independent
|
||||||
|
# ways by creating ActionFactory instances.
|
||||||
|
ActionFactory = SCons.Action.ActionFactory
|
||||||
|
|
||||||
|
Chmod = ActionFactory(os.chmod,
|
||||||
|
lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
|
||||||
|
|
||||||
|
def copy_func(dest, src):
|
||||||
|
if 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))
|
||||||
|
|
||||||
|
def delete_func(entry, must_exist=0):
|
||||||
|
if not must_exist and not os.path.exists(entry):
|
||||||
|
return None
|
||||||
|
if not os.path.exists(entry) or os.path.isfile(entry):
|
||||||
|
return os.unlink(entry)
|
||||||
|
else:
|
||||||
|
return shutil.rmtree(entry, 1)
|
||||||
|
|
||||||
|
def delete_strfunc(entry, must_exist=0):
|
||||||
|
return 'Delete("%s")' % entry
|
||||||
|
|
||||||
|
Delete = ActionFactory(delete_func, delete_strfunc)
|
||||||
|
|
||||||
|
Mkdir = ActionFactory(os.makedirs,
|
||||||
|
lambda dir: 'Mkdir("%s")' % dir)
|
||||||
|
|
||||||
|
Move = ActionFactory(lambda dest, src: os.rename(src, dest),
|
||||||
|
lambda dest, src: 'Move("%s", "%s")' % (dest, src))
|
||||||
|
|
||||||
|
def touch_func(file):
|
||||||
|
mtime = int(time.time())
|
||||||
|
if os.path.exists(file):
|
||||||
|
atime = os.path.getatime(file)
|
||||||
|
else:
|
||||||
|
open(file, 'w')
|
||||||
|
atime = mtime
|
||||||
|
return os.utime(file, (atime, mtime))
|
||||||
|
|
||||||
|
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):
|
||||||
|
"""
|
||||||
|
Creates a new list from 'list' by first interpolating each element
|
||||||
|
in the list using the 'env' dictionary and then calling f on the
|
||||||
|
list, and finally calling _concat_ixes to concatenate 'prefix' and
|
||||||
|
'suffix' onto each element of the list.
|
||||||
|
"""
|
||||||
|
if not list:
|
||||||
|
return list
|
||||||
|
|
||||||
|
if SCons.Util.is_List(list):
|
||||||
|
list = SCons.Util.flatten(list)
|
||||||
|
|
||||||
|
l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
|
||||||
|
if not l is None:
|
||||||
|
list = l
|
||||||
|
|
||||||
|
return _concat_ixes(prefix, list, suffix, env)
|
||||||
|
|
||||||
|
def _concat_ixes(prefix, list, suffix, env):
|
||||||
|
"""
|
||||||
|
Creates a new list from 'list' by concatenating the 'prefix' and
|
||||||
|
'suffix' arguments onto each element of the list. A trailing space
|
||||||
|
on 'prefix' or leading space on 'suffix' will cause them to be put
|
||||||
|
into separate list elements rather than being concatenated.
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = []
|
||||||
|
|
||||||
|
# ensure that prefix and suffix are strings
|
||||||
|
prefix = str(env.subst(prefix, SCons.Subst.SUBST_RAW))
|
||||||
|
suffix = str(env.subst(suffix, SCons.Subst.SUBST_RAW))
|
||||||
|
|
||||||
|
for x in list:
|
||||||
|
if isinstance(x, SCons.Node.FS.File):
|
||||||
|
result.append(x)
|
||||||
|
continue
|
||||||
|
x = str(x)
|
||||||
|
if x:
|
||||||
|
|
||||||
|
if prefix:
|
||||||
|
if prefix[-1] == ' ':
|
||||||
|
result.append(prefix[:-1])
|
||||||
|
elif x[:len(prefix)] != prefix:
|
||||||
|
x = prefix + x
|
||||||
|
|
||||||
|
result.append(x)
|
||||||
|
|
||||||
|
if suffix:
|
||||||
|
if suffix[0] == ' ':
|
||||||
|
result.append(suffix[1:])
|
||||||
|
elif x[-len(suffix):] != suffix:
|
||||||
|
result[-1] = result[-1]+suffix
|
||||||
|
|
||||||
|
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'."""
|
||||||
|
|
||||||
|
if not callable(c):
|
||||||
|
if callable(env["_concat"]):
|
||||||
|
c = env["_concat"]
|
||||||
|
else:
|
||||||
|
c = _concat
|
||||||
|
def f(list, sp=stripprefix, ss=stripsuffix):
|
||||||
|
result = []
|
||||||
|
for l in list:
|
||||||
|
if isinstance(l, SCons.Node.FS.File):
|
||||||
|
result.append(l)
|
||||||
|
continue
|
||||||
|
if not SCons.Util.is_String(l):
|
||||||
|
l = str(l)
|
||||||
|
if l[:len(sp)] == sp:
|
||||||
|
l = l[len(sp):]
|
||||||
|
if l[-len(ss):] == ss:
|
||||||
|
l = l[:-len(ss)]
|
||||||
|
result.append(l)
|
||||||
|
return result
|
||||||
|
return c(prefix, list, suffix, env, f)
|
||||||
|
|
||||||
|
# This is an alternate _stripixes() function that passes all of our tests
|
||||||
|
# (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)
|
||||||
|
|
||||||
|
def _defines(prefix, defs, suffix, env, c=_concat_ixes):
|
||||||
|
"""A wrapper around _concat_ixes that turns a list or string
|
||||||
|
into a list of C preprocessor command-line definitions.
|
||||||
|
"""
|
||||||
|
if SCons.Util.is_List(defs):
|
||||||
|
l = []
|
||||||
|
for d in defs:
|
||||||
|
if SCons.Util.is_List(d) or type(d) is types.TupleType:
|
||||||
|
l.append(str(d[0]) + '=' + str(d[1]))
|
||||||
|
else:
|
||||||
|
l.append(str(d))
|
||||||
|
elif SCons.Util.is_Dict(defs):
|
||||||
|
# The items in a dictionary are stored in random order, but
|
||||||
|
# if the order of the command-line options changes from
|
||||||
|
# invocation to invocation, then the signature of the command
|
||||||
|
# line will change and we'll get random unnecessary rebuilds.
|
||||||
|
# Consequently, we have to sort the keys to ensure a
|
||||||
|
# consistent order...
|
||||||
|
l = []
|
||||||
|
keys = defs.keys()
|
||||||
|
keys.sort()
|
||||||
|
for k in keys:
|
||||||
|
v = defs[k]
|
||||||
|
if v is None:
|
||||||
|
l.append(str(k))
|
||||||
|
else:
|
||||||
|
l.append(str(k) + '=' + str(v))
|
||||||
|
else:
|
||||||
|
l = [str(defs)]
|
||||||
|
return c(prefix, env.subst_path(l), suffix, env)
|
||||||
|
|
||||||
|
class NullCmdGenerator:
|
||||||
|
"""This is a callable class that can be used in place of other
|
||||||
|
command generators if you don't want them to do anything.
|
||||||
|
|
||||||
|
The __call__ method for this class simply returns the thing
|
||||||
|
you instantiated it with.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
env["DO_NOTHING"] = NullCmdGenerator
|
||||||
|
env["LINKCOM"] = "${DO_NOTHING('$LINK $SOURCES $TARGET')}"
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, cmd):
|
||||||
|
self.cmd = cmd
|
||||||
|
|
||||||
|
def __call__(self, target, source, env, for_signature=None):
|
||||||
|
return self.cmd
|
||||||
|
|
||||||
|
class Variable_Method_Caller:
|
||||||
|
"""A class for finding a construction variable on the stack and
|
||||||
|
calling one of its methods.
|
||||||
|
|
||||||
|
We use this to support "construction variables" in our string
|
||||||
|
eval()s that actually stand in for methods--specifically, use
|
||||||
|
of "RDirs" in call to _concat that should actually execute the
|
||||||
|
"TARGET.RDirs" method. (We used to support this by creating a little
|
||||||
|
"build dictionary" that mapped RDirs to the method, but this got in
|
||||||
|
the way of Memoizing construction environments, because we had to
|
||||||
|
create new environment objects to hold the variables.)
|
||||||
|
"""
|
||||||
|
def __init__(self, variable, method):
|
||||||
|
self.variable = variable
|
||||||
|
self.method = method
|
||||||
|
def __call__(self, *args, **kw):
|
||||||
|
try: 1/0
|
||||||
|
except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame
|
||||||
|
variable = self.variable
|
||||||
|
while frame:
|
||||||
|
if frame.f_locals.has_key(variable):
|
||||||
|
v = frame.f_locals[variable]
|
||||||
|
if v:
|
||||||
|
method = getattr(v, self.method)
|
||||||
|
return apply(method, args, kw)
|
||||||
|
frame = frame.f_back
|
||||||
|
return None
|
||||||
|
|
||||||
|
ConstructionEnvironment = {
|
||||||
|
'BUILDERS' : {},
|
||||||
|
'SCANNERS' : [],
|
||||||
|
'CONFIGUREDIR' : '#/.sconf_temp',
|
||||||
|
'CONFIGURELOG' : '#/config.log',
|
||||||
|
'CPPSUFFIXES' : SCons.Tool.CSuffixes,
|
||||||
|
'DSUFFIXES' : SCons.Tool.DSuffixes,
|
||||||
|
'ENV' : {},
|
||||||
|
'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
|
||||||
|
'INSTALL' : installFunc,
|
||||||
|
'INSTALLSTR' : installStr,
|
||||||
|
'_installStr' : installStr,
|
||||||
|
'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes,
|
||||||
|
'_concat' : _concat,
|
||||||
|
'_defines' : _defines,
|
||||||
|
'_stripixes' : _stripixes,
|
||||||
|
'_LIBFLAGS' : '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
|
||||||
|
'_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
|
||||||
|
'_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
|
||||||
|
'_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
|
||||||
|
'TEMPFILE' : NullCmdGenerator,
|
||||||
|
'Dir' : Variable_Method_Caller('TARGET', 'Dir'),
|
||||||
|
'Dirs' : Variable_Method_Caller('TARGET', 'Dirs'),
|
||||||
|
'File' : Variable_Method_Caller('TARGET', 'File'),
|
||||||
|
'RDirs' : Variable_Method_Caller('TARGET', 'RDirs'),
|
||||||
|
}
|
1896
scons/scons-local-0.97/SCons/Environment.py
Normal file
1896
scons/scons-local-0.97/SCons/Environment.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,14 +28,15 @@ and user errors in SCons.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Errors.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Errors.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BuildError(Exception):
|
class BuildError(Exception):
|
||||||
def __init__(self, node=None, errstr="Unknown error", *args):
|
def __init__(self, node=None, errstr="Unknown error", filename=None, *args):
|
||||||
self.node = node
|
self.node = node
|
||||||
self.errstr = errstr
|
self.errstr = errstr
|
||||||
|
self.filename = filename
|
||||||
apply(Exception.__init__, (self,) + args)
|
apply(Exception.__init__, (self,) + args)
|
||||||
|
|
||||||
class InternalError(Exception):
|
class InternalError(Exception):
|
||||||
|
@ -53,8 +54,9 @@ class ExplicitExit(Exception):
|
||||||
self.status = status
|
self.status = status
|
||||||
apply(Exception.__init__, (self,) + args)
|
apply(Exception.__init__, (self,) + args)
|
||||||
|
|
||||||
class ConfigureDryRunError(UserError):
|
class TaskmasterException(Exception):
|
||||||
"""Raised when a file needs to be updated during a Configure process,
|
def __init__(self, node=None, exc_info=(None, None, None), *args):
|
||||||
but the user requested a dry-run"""
|
self.node = node
|
||||||
def __init__(self,file):
|
self.errstr = "Exception"
|
||||||
UserError.__init__(self,"Cannot update configure test (%s) within a dry-run." % str(file))
|
self.exc_info = exc_info
|
||||||
|
apply(Exception.__init__, (self,) + args)
|
306
scons/scons-local-0.97/SCons/Executor.py
Normal file
306
scons/scons-local-0.97/SCons/Executor.py
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
"""SCons.Executor
|
||||||
|
|
||||||
|
A module for executing actions with specific lists of target and source
|
||||||
|
Nodes.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Executor.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import string
|
||||||
|
|
||||||
|
from SCons.Debug import logInstanceCreation
|
||||||
|
import SCons.Memoize
|
||||||
|
|
||||||
|
|
||||||
|
class Executor:
|
||||||
|
"""A class for controlling instances of executing an action.
|
||||||
|
|
||||||
|
This largely exists to hold a single association of an action,
|
||||||
|
environment, list of environment override dictionaries, targets
|
||||||
|
and sources for later processing as needed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if SCons.Memoize.use_memoizer:
|
||||||
|
__metaclass__ = SCons.Memoize.Memoized_Metaclass
|
||||||
|
|
||||||
|
memoizer_counters = []
|
||||||
|
|
||||||
|
def __init__(self, action, env=None, overridelist=[{}],
|
||||||
|
targets=[], sources=[], builder_kw={}):
|
||||||
|
if __debug__: logInstanceCreation(self, 'Executor.Executor')
|
||||||
|
self.set_action_list(action)
|
||||||
|
self.pre_actions = []
|
||||||
|
self.post_actions = []
|
||||||
|
self.env = env
|
||||||
|
self.overridelist = overridelist
|
||||||
|
self.targets = targets
|
||||||
|
self.sources = sources[:]
|
||||||
|
self.builder_kw = builder_kw
|
||||||
|
self._memo = {}
|
||||||
|
|
||||||
|
def set_action_list(self, action):
|
||||||
|
import SCons.Util
|
||||||
|
if not SCons.Util.is_List(action):
|
||||||
|
if not action:
|
||||||
|
import SCons.Errors
|
||||||
|
raise SCons.Errors.UserError, "Executor must have an action."
|
||||||
|
action = [action]
|
||||||
|
self.action_list = action
|
||||||
|
|
||||||
|
def get_action_list(self):
|
||||||
|
return self.pre_actions + self.action_list + self.post_actions
|
||||||
|
|
||||||
|
def get_build_env(self):
|
||||||
|
"""Fetch or create the appropriate build Environment
|
||||||
|
for this Executor.
|
||||||
|
"""
|
||||||
|
# Create the build environment instance with appropriate
|
||||||
|
# overrides. These get evaluated against the current
|
||||||
|
# environment's construction variables so that users can
|
||||||
|
# add to existing values by referencing the variable in
|
||||||
|
# the expansion.
|
||||||
|
overrides = {}
|
||||||
|
for odict in self.overridelist:
|
||||||
|
overrides.update(odict)
|
||||||
|
|
||||||
|
import SCons.Defaults
|
||||||
|
env = self.env or SCons.Defaults.DefaultEnvironment()
|
||||||
|
build_env = env.Override(overrides)
|
||||||
|
|
||||||
|
return build_env
|
||||||
|
|
||||||
|
def get_build_scanner_path(self, scanner):
|
||||||
|
"""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)
|
||||||
|
|
||||||
|
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_execute(self, target, exitstatfunc, kw):
|
||||||
|
"""Actually execute the action list."""
|
||||||
|
env = self.get_build_env()
|
||||||
|
kw = self.get_kw(kw)
|
||||||
|
for act in self.get_action_list():
|
||||||
|
apply(act,
|
||||||
|
(self.targets, self.sources, env, exitstatfunc),
|
||||||
|
kw)
|
||||||
|
|
||||||
|
# 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 cleanup(self):
|
||||||
|
self._memo = {}
|
||||||
|
|
||||||
|
def add_sources(self, sources):
|
||||||
|
"""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)
|
||||||
|
|
||||||
|
def add_pre_action(self, action):
|
||||||
|
self.pre_actions.append(action)
|
||||||
|
|
||||||
|
def add_post_action(self, action):
|
||||||
|
self.post_actions.append(action)
|
||||||
|
|
||||||
|
# another extra indirection for new-style objects and nullify...
|
||||||
|
|
||||||
|
def my_str(self):
|
||||||
|
env = self.get_build_env()
|
||||||
|
get = lambda action, t=self.targets, s=self.sources, e=env: \
|
||||||
|
action.genstring(t, s, e)
|
||||||
|
return string.join(map(get, self.get_action_list()), "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.my_str()
|
||||||
|
|
||||||
|
def nullify(self):
|
||||||
|
self.cleanup()
|
||||||
|
self.do_execute = self.do_nothing
|
||||||
|
self.my_str = lambda S=self: ''
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountValue('get_contents'))
|
||||||
|
|
||||||
|
def get_contents(self):
|
||||||
|
"""Fetch the signature contents. This is the main reason this
|
||||||
|
class exists, so we can compute this once and cache it regardless
|
||||||
|
of how many target or source Nodes there are.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self._memo['get_contents']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
env = self.get_build_env()
|
||||||
|
get = lambda action, t=self.targets, s=self.sources, e=env: \
|
||||||
|
action.get_contents(t, s, e)
|
||||||
|
result = string.join(map(get, self.get_action_list()), "")
|
||||||
|
self._memo['get_contents'] = result
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_timestamp(self):
|
||||||
|
"""Fetch a time stamp for this Executor. We don't have one, of
|
||||||
|
course (only files do), but this is the interface used by the
|
||||||
|
timestamp module.
|
||||||
|
"""
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def scan_targets(self, scanner):
|
||||||
|
self.scan(scanner, self.targets)
|
||||||
|
|
||||||
|
def scan_sources(self, scanner):
|
||||||
|
if self.sources:
|
||||||
|
self.scan(scanner, self.sources)
|
||||||
|
|
||||||
|
def scan(self, scanner, node_list):
|
||||||
|
"""Scan a list of this Executor's files (targets or sources) for
|
||||||
|
implicit dependencies and 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.
|
||||||
|
"""
|
||||||
|
map(lambda N: N.disambiguate(), node_list)
|
||||||
|
|
||||||
|
env = self.get_build_env()
|
||||||
|
select_specific_scanner = lambda t: (t[0], t[1].select(t[0]))
|
||||||
|
remove_null_scanners = lambda t: not t[1] is None
|
||||||
|
add_scanner_path = lambda t, s=self: \
|
||||||
|
(t[0], t[1], s.get_build_scanner_path(t[1]))
|
||||||
|
if scanner:
|
||||||
|
scanner_list = map(lambda n, s=scanner: (n, s), node_list)
|
||||||
|
else:
|
||||||
|
kw = self.get_kw()
|
||||||
|
get_initial_scanners = lambda n, e=env, kw=kw: \
|
||||||
|
(n, n.get_env_scanner(e, kw))
|
||||||
|
scanner_list = map(get_initial_scanners, node_list)
|
||||||
|
scanner_list = filter(remove_null_scanners, scanner_list)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
for tgt in self.targets:
|
||||||
|
tgt.add_to_implicit(deps)
|
||||||
|
|
||||||
|
def get_missing_sources(self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
return filter(lambda s: s.missing(), self.sources)
|
||||||
|
|
||||||
|
def _get_unignored_sources_key(self, ignore=()):
|
||||||
|
return tuple(ignore)
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountDict('get_unignored_sources', _get_unignored_sources_key))
|
||||||
|
|
||||||
|
def get_unignored_sources(self, ignore=()):
|
||||||
|
ignore = tuple(ignore)
|
||||||
|
try:
|
||||||
|
memo_dict = self._memo['get_unignored_sources']
|
||||||
|
except KeyError:
|
||||||
|
memo_dict = {}
|
||||||
|
self._memo['get_unignored_sources'] = memo_dict
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return memo_dict[ignore]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
sourcelist = self.sources
|
||||||
|
if ignore:
|
||||||
|
sourcelist = filter(lambda s, i=ignore: not s in i, sourcelist)
|
||||||
|
|
||||||
|
memo_dict[ignore] = sourcelist
|
||||||
|
|
||||||
|
return sourcelist
|
||||||
|
|
||||||
|
def _process_sources_key(self, func, ignore=()):
|
||||||
|
return (func, tuple(ignore))
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountDict('process_sources', _process_sources_key))
|
||||||
|
|
||||||
|
def process_sources(self, func, ignore=()):
|
||||||
|
memo_key = (func, tuple(ignore))
|
||||||
|
try:
|
||||||
|
memo_dict = self._memo['process_sources']
|
||||||
|
except KeyError:
|
||||||
|
memo_dict = {}
|
||||||
|
self._memo['process_sources'] = memo_dict
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return memo_dict[memo_key]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
result = map(func, self.get_unignored_sources(ignore))
|
||||||
|
|
||||||
|
memo_dict[memo_key] = result
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
_Executor = Executor
|
||||||
|
|
||||||
|
class Null(_Executor):
|
||||||
|
"""A null Executor, with a null build Environment, that does
|
||||||
|
nothing when the rest of the methods call it.
|
||||||
|
|
||||||
|
This might be able to disapper when we refactor things to
|
||||||
|
disassociate Builders from Nodes entirely, so we're not
|
||||||
|
going to worry about unit tests for this--at least for now.
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kw):
|
||||||
|
if __debug__: logInstanceCreation(self, 'Executor.Null')
|
||||||
|
kw['action'] = []
|
||||||
|
apply(_Executor.__init__, (self,), kw)
|
||||||
|
def get_build_env(self):
|
||||||
|
class NullEnvironment:
|
||||||
|
def get_scanner(self, key):
|
||||||
|
return None
|
||||||
|
return NullEnvironment()
|
||||||
|
def get_build_scanner_path(self):
|
||||||
|
return None
|
||||||
|
def cleanup(self):
|
||||||
|
pass
|
|
@ -7,7 +7,7 @@ stop, and wait on jobs.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -29,7 +29,9 @@ stop, and wait on jobs.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Job.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Job.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
|
|
||||||
class Jobs:
|
class Jobs:
|
||||||
"""An instance of this class initializes N jobs, and provides
|
"""An instance of this class initializes N jobs, and provides
|
||||||
|
@ -89,8 +91,7 @@ class Serial:
|
||||||
that needs to be executed, or None if there are no more tasks. The
|
that needs to be executed, or None if there are no more tasks. The
|
||||||
taskmaster's executed() method will be called for each task when it
|
taskmaster's executed() method will be called for each task when it
|
||||||
is successfully executed or failed() will be called if it failed to
|
is successfully executed or failed() will be called if it failed to
|
||||||
execute (e.g. execute() raised an exception). The taskmaster's
|
execute (e.g. execute() raised an exception)."""
|
||||||
is_blocked() method will not be called. """
|
|
||||||
|
|
||||||
self.taskmaster = taskmaster
|
self.taskmaster = taskmaster
|
||||||
|
|
||||||
|
@ -154,9 +155,9 @@ else:
|
||||||
ok = False
|
ok = False
|
||||||
except:
|
except:
|
||||||
task.exception_set()
|
task.exception_set()
|
||||||
ok = 0
|
ok = False
|
||||||
else:
|
else:
|
||||||
ok = 1
|
ok = True
|
||||||
|
|
||||||
self.resultsQueue.put((task, ok))
|
self.resultsQueue.put((task, ok))
|
||||||
|
|
||||||
|
@ -169,21 +170,19 @@ else:
|
||||||
self.resultsQueue = Queue.Queue(0)
|
self.resultsQueue = Queue.Queue(0)
|
||||||
|
|
||||||
# Create worker threads
|
# Create worker threads
|
||||||
for i in range(num):
|
for _ in range(num):
|
||||||
Worker(self.requestQueue, self.resultsQueue)
|
Worker(self.requestQueue, self.resultsQueue)
|
||||||
|
|
||||||
def put(self, obj):
|
def put(self, obj):
|
||||||
"""Put task into request queue."""
|
"""Put task into request queue."""
|
||||||
self.requestQueue.put(obj)
|
self.requestQueue.put(obj)
|
||||||
|
|
||||||
def get(self, block = 1):
|
def get(self, block = True):
|
||||||
"""Remove and return a result tuple from the results queue."""
|
"""Remove and return a result tuple from the results queue."""
|
||||||
return self.resultsQueue.get(block)
|
return self.resultsQueue.get(block)
|
||||||
|
|
||||||
def get_nowait(self):
|
def preparation_failed(self, obj):
|
||||||
"""Remove and result a result tuple from the results queue
|
self.resultsQueue.put((obj, 0))
|
||||||
without blocking."""
|
|
||||||
return self.get(0)
|
|
||||||
|
|
||||||
class Parallel:
|
class Parallel:
|
||||||
"""This class is used to execute tasks in parallel, and is somewhat
|
"""This class is used to execute tasks in parallel, and is somewhat
|
||||||
|
@ -195,25 +194,21 @@ else:
|
||||||
def __init__(self, taskmaster, num):
|
def __init__(self, taskmaster, num):
|
||||||
"""Create a new parallel job given a taskmaster.
|
"""Create a new parallel job given a taskmaster.
|
||||||
|
|
||||||
The taskmaster's next_task() method should return the next task
|
The taskmaster's next_task() method should return the next
|
||||||
that needs to be executed, or None if there are no more tasks. The
|
task that needs to be executed, or None if there are no more
|
||||||
taskmaster's executed() method will be called for each task when it
|
tasks. The taskmaster's executed() method will be called
|
||||||
is successfully executed or failed() will be called if the task
|
for each task when it is successfully executed or failed()
|
||||||
failed to execute (i.e. execute() raised an exception). The
|
will be called if the task failed to execute (i.e. execute()
|
||||||
taskmaster's is_blocked() method should return true iff there are
|
raised an exception).
|
||||||
more tasks, but they can't be executed until one or more other
|
|
||||||
tasks have been executed. next_task() will be called iff
|
|
||||||
is_blocked() returned false.
|
|
||||||
|
|
||||||
Note: calls to taskmaster are serialized, but calls to execute() on
|
Note: calls to taskmaster are serialized, but calls to
|
||||||
distinct tasks are not serialized, because that is the whole point
|
execute() on distinct tasks are not serialized, because
|
||||||
of parallel jobs: they can execute multiple tasks
|
that is the whole point of parallel jobs: they can execute
|
||||||
simultaneously. """
|
multiple tasks simultaneously. """
|
||||||
|
|
||||||
self.taskmaster = taskmaster
|
self.taskmaster = taskmaster
|
||||||
self.tp = ThreadPool(num)
|
self.tp = ThreadPool(num)
|
||||||
|
|
||||||
self.jobs = 0
|
|
||||||
self.maxjobs = num
|
self.maxjobs = num
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
@ -222,8 +217,12 @@ else:
|
||||||
more tasks. If a task fails to execute (i.e. execute() raises
|
more tasks. If a task fails to execute (i.e. execute() raises
|
||||||
an exception), then the job will stop."""
|
an exception), then the job will stop."""
|
||||||
|
|
||||||
|
jobs = 0
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
if self.jobs < self.maxjobs:
|
# Start up as many available tasks as we're
|
||||||
|
# allowed to.
|
||||||
|
while jobs < self.maxjobs:
|
||||||
task = self.taskmaster.next_task()
|
task = self.taskmaster.next_task()
|
||||||
if task is None:
|
if task is None:
|
||||||
break
|
break
|
||||||
|
@ -234,26 +233,31 @@ else:
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
# Let the failed() callback function arrange for the
|
# Let the failed() callback function arrange
|
||||||
# build to stop if that's appropriate.
|
# for the build to stop if that's appropriate.
|
||||||
task.failed()
|
task.exception_set()
|
||||||
|
self.tp.preparation_failed(task)
|
||||||
|
jobs = jobs + 1
|
||||||
|
continue
|
||||||
|
|
||||||
# dispatch task
|
# dispatch task
|
||||||
self.tp.put(task)
|
self.tp.put(task)
|
||||||
self.jobs = self.jobs + 1
|
jobs = jobs + 1
|
||||||
|
|
||||||
|
if not task and not jobs: break
|
||||||
|
|
||||||
|
# Let any/all completed tasks finish up before we go
|
||||||
|
# back and put the next batch of tasks on the queue.
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
task, ok = self.tp.get()
|
||||||
task, ok = self.tp.get_nowait()
|
|
||||||
except Queue.Empty:
|
|
||||||
if not (self.jobs is self.maxjobs or self.taskmaster.is_blocked()):
|
|
||||||
break
|
|
||||||
task, ok = self.tp.get()
|
|
||||||
|
|
||||||
self.jobs = self.jobs - 1
|
jobs = jobs - 1
|
||||||
if ok:
|
if ok:
|
||||||
task.executed()
|
task.executed()
|
||||||
else:
|
else:
|
||||||
task.failed()
|
task.failed()
|
||||||
|
|
||||||
task.postprocess()
|
task.postprocess()
|
||||||
|
|
||||||
|
if self.tp.resultsQueue.empty():
|
||||||
|
break
|
272
scons/scons-local-0.97/SCons/Memoize.py
Normal file
272
scons/scons-local-0.97/SCons/Memoize.py
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Memoize.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
__doc__ = """Memoizer
|
||||||
|
|
||||||
|
A metaclass implementation to count hits and misses of the computed
|
||||||
|
values that various methods cache in memory.
|
||||||
|
|
||||||
|
Use of this modules assumes that wrapped methods be coded to cache their
|
||||||
|
values in a consistent way. Here is an example of wrapping a method
|
||||||
|
that returns a computed value, with no input parameters:
|
||||||
|
|
||||||
|
memoizer_counters = [] # Memoization
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountValue('foo')) # Memoization
|
||||||
|
|
||||||
|
def foo(self):
|
||||||
|
|
||||||
|
try: # Memoization
|
||||||
|
return self._memo['foo'] # Memoization
|
||||||
|
except KeyError: # Memoization
|
||||||
|
pass # Memoization
|
||||||
|
|
||||||
|
result = self.compute_foo_value()
|
||||||
|
|
||||||
|
self._memo['foo'] = result # Memoization
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
Here is an example of wrapping a method that will return different values
|
||||||
|
based on one or more input arguments:
|
||||||
|
|
||||||
|
def _bar_key(self, argument): # Memoization
|
||||||
|
return argument # Memoization
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountDict('bar', _bar_key)) # Memoization
|
||||||
|
|
||||||
|
def bar(self, argument):
|
||||||
|
|
||||||
|
memo_key = argument # Memoization
|
||||||
|
try: # Memoization
|
||||||
|
memo_dict = self._memo['bar'] # Memoization
|
||||||
|
except KeyError: # Memoization
|
||||||
|
memo_dict = {} # Memoization
|
||||||
|
self._memo['dict'] = memo_dict # Memoization
|
||||||
|
else: # Memoization
|
||||||
|
try: # Memoization
|
||||||
|
return memo_dict[memo_key] # Memoization
|
||||||
|
except KeyError: # Memoization
|
||||||
|
pass # Memoization
|
||||||
|
|
||||||
|
result = self.compute_bar_value(argument)
|
||||||
|
|
||||||
|
memo_dict[memo_key] = result # Memoization
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
At one point we avoided replicating this sort of logic in all the methods
|
||||||
|
by putting it right into this module, but we've moved away from that at
|
||||||
|
present (see the "Historical Note," below.).
|
||||||
|
|
||||||
|
Deciding what to cache is tricky, because different configurations
|
||||||
|
can have radically different performance tradeoffs, and because the
|
||||||
|
tradeoffs involved are often so non-obvious. Consequently, deciding
|
||||||
|
whether or not to cache a given method will likely be more of an art than
|
||||||
|
a science, but should still be based on available data from this module.
|
||||||
|
Here are some VERY GENERAL guidelines about deciding whether or not to
|
||||||
|
cache return values from a method that's being called a lot:
|
||||||
|
|
||||||
|
-- The first question to ask is, "Can we change the calling code
|
||||||
|
so this method isn't called so often?" Sometimes this can be
|
||||||
|
done by changing the algorithm. Sometimes the *caller* should
|
||||||
|
be memoized, not the method you're looking at.
|
||||||
|
|
||||||
|
-- The memoized function should be timed with multiple configurations
|
||||||
|
to make sure it doesn't inadvertently slow down some other
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
-- When memoizing values based on a dictionary key composed of
|
||||||
|
input arguments, you don't need to use all of the arguments
|
||||||
|
if some of them don't affect the return values.
|
||||||
|
|
||||||
|
Historical Note: The initial Memoizer implementation actually handled
|
||||||
|
the caching of values for the wrapped methods, based on a set of generic
|
||||||
|
algorithms for computing hashable values based on the method's arguments.
|
||||||
|
This collected caching logic nicely, but had two drawbacks:
|
||||||
|
|
||||||
|
Running arguments through a generic key-conversion mechanism is slower
|
||||||
|
(and less flexible) than just coding these things directly. Since the
|
||||||
|
methods that need memoized values are generally performance-critical,
|
||||||
|
slowing them down in order to collect the logic isn't the right
|
||||||
|
tradeoff.
|
||||||
|
|
||||||
|
Use of the memoizer really obscured what was being called, because
|
||||||
|
all the memoized methods were wrapped with re-used generic methods.
|
||||||
|
This made it more difficult, for example, to use the Python profiler
|
||||||
|
to figure out how to optimize the underlying methods.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import new
|
||||||
|
|
||||||
|
# A flag controlling whether or not we actually use memoization.
|
||||||
|
use_memoizer = None
|
||||||
|
|
||||||
|
CounterList = []
|
||||||
|
|
||||||
|
class Counter:
|
||||||
|
"""
|
||||||
|
Base class for counting memoization hits and misses.
|
||||||
|
|
||||||
|
We expect that the metaclass initialization will have filled in
|
||||||
|
the .name attribute that represents the name of the function
|
||||||
|
being counted.
|
||||||
|
"""
|
||||||
|
def __init__(self, method_name):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
self.method_name = method_name
|
||||||
|
self.hit = 0
|
||||||
|
self.miss = 0
|
||||||
|
CounterList.append(self)
|
||||||
|
def display(self):
|
||||||
|
fmt = " %7d hits %7d misses %s()"
|
||||||
|
print fmt % (self.hit, self.miss, self.name)
|
||||||
|
def __cmp__(self, other):
|
||||||
|
try:
|
||||||
|
return cmp(self.name, other.name)
|
||||||
|
except AttributeError:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
class CountValue(Counter):
|
||||||
|
"""
|
||||||
|
A counter class for simple, atomic memoized values.
|
||||||
|
|
||||||
|
A CountValue object should be instantiated in a class for each of
|
||||||
|
the class's methods that memoizes its return value by simply storing
|
||||||
|
the return value in its _memo dictionary.
|
||||||
|
|
||||||
|
We expect that the metaclass initialization will fill in the
|
||||||
|
.underlying_method attribute with the method that we're wrapping.
|
||||||
|
We then call the underlying_method method after counting whether
|
||||||
|
its memoized value has already been set (a hit) or not (a miss).
|
||||||
|
"""
|
||||||
|
def __call__(self, *args, **kw):
|
||||||
|
obj = args[0]
|
||||||
|
if obj._memo.has_key(self.method_name):
|
||||||
|
self.hit = self.hit + 1
|
||||||
|
else:
|
||||||
|
self.miss = self.miss + 1
|
||||||
|
return apply(self.underlying_method, args, kw)
|
||||||
|
|
||||||
|
class CountDict(Counter):
|
||||||
|
"""
|
||||||
|
A counter class for memoized values stored in a dictionary, with
|
||||||
|
keys based on the method's input arguments.
|
||||||
|
|
||||||
|
A CountDict object is instantiated in a class for each of the
|
||||||
|
class's methods that memoizes its return value in a dictionary,
|
||||||
|
indexed by some key that can be computed from one or more of
|
||||||
|
its input arguments.
|
||||||
|
|
||||||
|
We expect that the metaclass initialization will fill in the
|
||||||
|
.underlying_method attribute with the method that we're wrapping.
|
||||||
|
We then call the underlying_method method after counting whether the
|
||||||
|
computed key value is already present in the memoization dictionary
|
||||||
|
(a hit) or not (a miss).
|
||||||
|
"""
|
||||||
|
def __init__(self, method_name, keymaker):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
Counter.__init__(self, method_name)
|
||||||
|
self.keymaker = keymaker
|
||||||
|
def __call__(self, *args, **kw):
|
||||||
|
obj = args[0]
|
||||||
|
try:
|
||||||
|
memo_dict = obj._memo[self.method_name]
|
||||||
|
except KeyError:
|
||||||
|
self.miss = self.miss + 1
|
||||||
|
else:
|
||||||
|
key = apply(self.keymaker, args, kw)
|
||||||
|
if memo_dict.has_key(key):
|
||||||
|
self.hit = self.hit + 1
|
||||||
|
else:
|
||||||
|
self.miss = self.miss + 1
|
||||||
|
return apply(self.underlying_method, args, kw)
|
||||||
|
|
||||||
|
class Memoizer:
|
||||||
|
"""Object which performs caching of method calls for its 'primary'
|
||||||
|
instance."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Find out if we support metaclasses (Python 2.2 and later).
|
||||||
|
|
||||||
|
class M:
|
||||||
|
def __init__(cls, name, bases, cls_dict):
|
||||||
|
cls.has_metaclass = 1
|
||||||
|
|
||||||
|
class A:
|
||||||
|
__metaclass__ = M
|
||||||
|
|
||||||
|
try:
|
||||||
|
has_metaclass = A.has_metaclass
|
||||||
|
except AttributeError:
|
||||||
|
has_metaclass = None
|
||||||
|
|
||||||
|
del M
|
||||||
|
del A
|
||||||
|
|
||||||
|
if not has_metaclass:
|
||||||
|
|
||||||
|
def Dump(title):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Memoized_Metaclass:
|
||||||
|
# Just a place-holder so pre-metaclass Python versions don't
|
||||||
|
# have to have special code for the Memoized classes.
|
||||||
|
pass
|
||||||
|
|
||||||
|
def EnableMemoization():
|
||||||
|
import SCons.Warnings
|
||||||
|
msg = 'memoization is not supported in this version of Python (no metaclasses)'
|
||||||
|
raise SCons.Warnings.NoMetaclassSupportWarning, msg
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
def Dump(title=None):
|
||||||
|
if title:
|
||||||
|
print title
|
||||||
|
CounterList.sort()
|
||||||
|
for counter in CounterList:
|
||||||
|
counter.display()
|
||||||
|
|
||||||
|
class Memoized_Metaclass(type):
|
||||||
|
def __init__(cls, name, bases, cls_dict):
|
||||||
|
super(Memoized_Metaclass, cls).__init__(name, bases, cls_dict)
|
||||||
|
|
||||||
|
for counter in cls_dict.get('memoizer_counters', []):
|
||||||
|
method_name = counter.method_name
|
||||||
|
|
||||||
|
counter.name = cls.__name__ + '.' + method_name
|
||||||
|
counter.underlying_method = cls_dict[method_name]
|
||||||
|
|
||||||
|
replacement_method = new.instancemethod(counter, None, cls)
|
||||||
|
setattr(cls, method_name, replacement_method)
|
||||||
|
|
||||||
|
def EnableMemoization():
|
||||||
|
global use_memoizer
|
||||||
|
use_memoizer = 1
|
|
@ -8,7 +8,7 @@ This creates a hash of global Aliases (dummy targets).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,8 +30,9 @@ This creates a hash of global Aliases (dummy targets).
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Node/Alias.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Node/Alias.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import string
|
||||||
import UserDict
|
import UserDict
|
||||||
|
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
|
@ -39,19 +40,33 @@ import SCons.Node
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
class AliasNameSpace(UserDict.UserDict):
|
class AliasNameSpace(UserDict.UserDict):
|
||||||
def Alias(self, name):
|
def Alias(self, name, **kw):
|
||||||
if self.has_key(name):
|
if isinstance(name, SCons.Node.Alias.Alias):
|
||||||
raise SCons.Errors.UserError
|
return name
|
||||||
self[name] = SCons.Node.Alias.Alias(name)
|
try:
|
||||||
return self[name]
|
a = self[name]
|
||||||
|
except KeyError:
|
||||||
|
a = apply(SCons.Node.Alias.Alias, (name,), kw)
|
||||||
|
self[name] = a
|
||||||
|
return a
|
||||||
|
|
||||||
def lookup(self, name):
|
def lookup(self, name, **kw):
|
||||||
try:
|
try:
|
||||||
return self[name]
|
return self[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
class AliasNodeInfo(SCons.Node.NodeInfoBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class AliasBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
|
pass
|
||||||
|
|
||||||
class Alias(SCons.Node.Node):
|
class Alias(SCons.Node.Node):
|
||||||
|
|
||||||
|
NodeInfo = AliasNodeInfo
|
||||||
|
BuildInfo = AliasBuildInfo
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
SCons.Node.Node.__init__(self)
|
SCons.Node.Node.__init__(self)
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -59,16 +74,9 @@ class Alias(SCons.Node.Node):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def build(self):
|
really_build = SCons.Node.Node.build
|
||||||
"""A "builder" for aliases."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
current = SCons.Node.Node.children_are_up_to_date
|
current = SCons.Node.Node.children_are_up_to_date
|
||||||
|
|
||||||
def sconsign(self):
|
|
||||||
"""An Alias is not recorded in .sconsign files"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def is_under(self, dir):
|
def is_under(self, dir):
|
||||||
# Make Alias nodes get built regardless of
|
# Make Alias nodes get built regardless of
|
||||||
# what directory scons was run from. Alias nodes
|
# what directory scons was run from. Alias nodes
|
||||||
|
@ -78,10 +86,26 @@ class Alias(SCons.Node.Node):
|
||||||
def get_contents(self):
|
def get_contents(self):
|
||||||
"""The contents of an alias is the concatenation
|
"""The contents of an alias is the concatenation
|
||||||
of all the contents of its sources"""
|
of all the contents of its sources"""
|
||||||
contents = ""
|
contents = map(lambda n: n.get_contents(), self.children())
|
||||||
for kid in self.children(None):
|
return string.join(contents, '')
|
||||||
contents = contents + kid.get_contents()
|
|
||||||
return contents
|
def sconsign(self):
|
||||||
|
"""An Alias is not recorded in .sconsign files"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
"""A "builder" for aliases."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def convert(self):
|
||||||
|
try: del self.builder
|
||||||
|
except AttributeError: pass
|
||||||
|
self.reset_executor()
|
||||||
|
self.build = self.really_build
|
||||||
|
|
||||||
default_ans = AliasNameSpace()
|
default_ans = AliasNameSpace()
|
||||||
|
|
2418
scons/scons-local-0.97/SCons/Node/FS.py
Normal file
2418
scons/scons-local-0.97/SCons/Node/FS.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,7 @@ Python nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,24 +27,36 @@ Python nodes.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Node/Python.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Node/Python.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Node
|
import SCons.Node
|
||||||
|
|
||||||
|
class ValueNodeInfo(SCons.Node.NodeInfoBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ValueBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
|
pass
|
||||||
|
|
||||||
class Value(SCons.Node.Node):
|
class Value(SCons.Node.Node):
|
||||||
"""A class for Python variables, typically passed on the command line
|
"""A class for Python variables, typically passed on the command line
|
||||||
or generated by a script, but not from a file or some other source.
|
or generated by a script, but not from a file or some other source.
|
||||||
"""
|
"""
|
||||||
def __init__(self, value):
|
|
||||||
|
NodeInfo = ValueNodeInfo
|
||||||
|
BuildInfo = ValueBuildInfo
|
||||||
|
|
||||||
|
def __init__(self, value, built_value=None):
|
||||||
SCons.Node.Node.__init__(self)
|
SCons.Node.Node.__init__(self)
|
||||||
self.value = value
|
self.value = value
|
||||||
|
if not built_value is None:
|
||||||
|
self.built_value = built_value
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
def build(self):
|
def build(self, **kw):
|
||||||
"""A "builder" for Values."""
|
if not hasattr(self, 'built_value'):
|
||||||
pass
|
apply (SCons.Node.Node.build, (self,), kw)
|
||||||
|
|
||||||
current = SCons.Node.Node.children_are_up_to_date
|
current = SCons.Node.Node.children_are_up_to_date
|
||||||
|
|
||||||
|
@ -54,25 +66,39 @@ class Value(SCons.Node.Node):
|
||||||
# are outside the filesystem:
|
# are outside the filesystem:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def write(self, built_value):
|
||||||
|
"""Set the value of the node."""
|
||||||
|
self.built_value = built_value
|
||||||
|
|
||||||
|
def read(self):
|
||||||
|
"""Return the value. If necessary, the value is built."""
|
||||||
|
self.build()
|
||||||
|
if not hasattr(self, 'built_value'):
|
||||||
|
self.built_value = self.value
|
||||||
|
return self.built_value
|
||||||
|
|
||||||
def get_contents(self):
|
def get_contents(self):
|
||||||
"""The contents of a Value are the concatenation
|
"""By the assumption that the node.built_value is a
|
||||||
of all the contents of its sources with the node's value itself."""
|
deterministic product of the sources, the contents of a Value
|
||||||
|
are the concatenation of all the contents of its sources. As
|
||||||
|
the value need not be built when get_contents() is called, we
|
||||||
|
cannot use the actual node.built_value."""
|
||||||
contents = str(self.value)
|
contents = str(self.value)
|
||||||
for kid in self.children(None):
|
for kid in self.children(None):
|
||||||
contents = contents + kid.get_contents()
|
contents = contents + kid.get_contents()
|
||||||
return contents
|
return contents
|
||||||
|
|
||||||
def calc_csig(self, calc=None):
|
def get_csig(self, calc=None):
|
||||||
"""Because we're a Python value node and don't have a real
|
"""Because we're a Python value node and don't have a real
|
||||||
timestamp, we get to ignore the calculator and just use the
|
timestamp, we get to ignore the calculator and just use the
|
||||||
value contents."""
|
value contents."""
|
||||||
try:
|
try:
|
||||||
binfo = self.binfo
|
binfo = self.binfo
|
||||||
except:
|
except AttributeError:
|
||||||
binfo = self.binfo = self.new_binfo()
|
binfo = self.binfo = self.new_binfo()
|
||||||
try:
|
try:
|
||||||
return binfo.csig
|
return binfo.ninfo.csig
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
binfo.csig = self.get_contents()
|
binfo.ninfo.csig = self.get_contents()
|
||||||
self.store_info(binfo)
|
self.store_info(binfo)
|
||||||
return binfo.csig
|
return binfo.ninfo.csig
|
File diff suppressed because it is too large
Load diff
|
@ -10,7 +10,7 @@ See http://optik.sourceforge.net/
|
||||||
# Copyright (c) 2001 Gregory P. Ward. All rights reserved.
|
# Copyright (c) 2001 Gregory P. Ward. All rights reserved.
|
||||||
# See the README.txt distributed with Optik for licensing terms.
|
# See the README.txt distributed with Optik for licensing terms.
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Optik/__init__.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Optik/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
# Original Optik revision this is based on:
|
# Original Optik revision this is based on:
|
||||||
__Optik_revision__ = "__init__.py,v 1.11 2002/04/11 19:17:34 gward Exp"
|
__Optik_revision__ = "__init__.py,v 1.11 2002/04/11 19:17:34 gward Exp"
|
|
@ -3,7 +3,7 @@
|
||||||
Exception classes used by Optik.
|
Exception classes used by Optik.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Optik/errors.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Optik/errors.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
# Original Optik revision this is based on:
|
# Original Optik revision this is based on:
|
||||||
__Optik_revision__ = "errors.py,v 1.5 2002/02/13 23:29:47 gward Exp"
|
__Optik_revision__ = "errors.py,v 1.5 2002/02/13 23:29:47 gward Exp"
|
|
@ -3,7 +3,7 @@
|
||||||
Defines the Option class and some standard value-checking functions.
|
Defines the Option class and some standard value-checking functions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Optik/option.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Optik/option.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
# Original Optik revision this is based on:
|
# Original Optik revision this is based on:
|
||||||
__Optik_revision__ = "option.py,v 1.19.2.1 2002/07/23 01:51:14 gward Exp"
|
__Optik_revision__ = "option.py,v 1.19.2.1 2002/07/23 01:51:14 gward Exp"
|
||||||
|
@ -346,8 +346,8 @@ class Option:
|
||||||
if self.nargs == 1:
|
if self.nargs == 1:
|
||||||
value = self.check_value(opt, value)
|
value = self.check_value(opt, value)
|
||||||
else:
|
else:
|
||||||
def cv(v,check=self.check_value,o=opt):
|
def cv(v,check=self.check_value,o=opt):
|
||||||
return check(o,v)
|
return check(o,v)
|
||||||
|
|
||||||
value = tuple(map(cv,value))
|
value = tuple(map(cv,value))
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Provides the OptionParser and Values classes.
|
Provides the OptionParser and Values classes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Optik/option_parser.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Optik/option_parser.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
# Original Optik revision this is based on:
|
# Original Optik revision this is based on:
|
||||||
__Optik_revision__ = "option_parser.py,v 1.38.2.1 2002/07/23 01:51:14 gward Exp"
|
__Optik_revision__ = "option_parser.py,v 1.38.2.1 2002/07/23 01:51:14 gward Exp"
|
||||||
|
@ -530,8 +530,8 @@ class OptionParser:
|
||||||
(basename of sys.argv[0]). Does nothing if self.usage is empty
|
(basename of sys.argv[0]). Does nothing if self.usage is empty
|
||||||
or not defined.
|
or not defined.
|
||||||
"""
|
"""
|
||||||
if file is None:
|
if file is None:
|
||||||
file = sys.stdout
|
file = sys.stdout
|
||||||
if self.usage:
|
if self.usage:
|
||||||
usage = string.replace(self.usage,"%prog", get_prog_name())
|
usage = string.replace(self.usage,"%prog", get_prog_name())
|
||||||
file.write(usage + "\n")
|
file.write(usage + "\n")
|
||||||
|
@ -544,8 +544,8 @@ class OptionParser:
|
||||||
of "%prog" in self.version is replaced by the current program's
|
of "%prog" in self.version is replaced by the current program's
|
||||||
name. Does nothing if self.version is empty or undefined.
|
name. Does nothing if self.version is empty or undefined.
|
||||||
"""
|
"""
|
||||||
if file is None:
|
if file is None:
|
||||||
file = sys.stdout
|
file = sys.stdout
|
||||||
if self.version:
|
if self.version:
|
||||||
version = string.replace(self.version,"%prog", get_prog_name())
|
version = string.replace(self.version,"%prog", get_prog_name())
|
||||||
file.write(version+"\n")
|
file.write(version+"\n")
|
||||||
|
@ -649,10 +649,10 @@ def _match_abbrev (s, wordmap):
|
||||||
else:
|
else:
|
||||||
# Isolate all words with s as a prefix.
|
# Isolate all words with s as a prefix.
|
||||||
possibilities = []
|
possibilities = []
|
||||||
ls = len(s)
|
ls = len(s)
|
||||||
for word in wordmap.keys():
|
for word in wordmap.keys():
|
||||||
if len(word)>=ls and word[:ls]==s:
|
if len(word)>=ls and word[:ls]==s:
|
||||||
possibilities.append(word)
|
possibilities.append(word)
|
||||||
# No exact match, so there had better be just one possibility.
|
# No exact match, so there had better be just one possibility.
|
||||||
if len(possibilities) == 1:
|
if len(possibilities) == 1:
|
||||||
return possibilities[0]
|
return possibilities[0]
|
|
@ -12,7 +12,7 @@ Usage example:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -34,20 +34,18 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/BoolOption.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/BoolOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
__all__ = ('BoolOption', 'True', 'False')
|
__all__ = ('BoolOption')
|
||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
|
|
||||||
__true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
|
__true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
|
||||||
__false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
|
__false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
|
||||||
|
|
||||||
# we need this since SCons should work version indepentant
|
|
||||||
True, False = 1, 0
|
|
||||||
|
|
||||||
|
|
||||||
def _text2bool(val):
|
def _text2bool(val):
|
||||||
"""
|
"""
|
|
@ -15,7 +15,7 @@ Usage example:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -37,7 +37,7 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/EnumOption.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/EnumOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
__all__ = ('EnumOption',)
|
__all__ = ('EnumOption',)
|
||||||
|
|
|
@ -25,7 +25,7 @@ Usage example:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -47,7 +47,7 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/branch.96/baseline/src/engine/SCons/Options/ListOption.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/ListOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
# Know Bug: This should behave like a Set-Type, but does not really,
|
# Know Bug: This should behave like a Set-Type, but does not really,
|
||||||
# since elements can occur twice.
|
# since elements can occur twice.
|
||||||
|
@ -57,6 +57,8 @@ __all__ = ('ListOption',)
|
||||||
import string
|
import string
|
||||||
import UserList
|
import UserList
|
||||||
|
|
||||||
|
import SCons.Util
|
||||||
|
|
||||||
|
|
||||||
class _ListOption(UserList.UserList):
|
class _ListOption(UserList.UserList):
|
||||||
def __init__(self, initlist=[], allowedElems=[]):
|
def __init__(self, initlist=[], allowedElems=[]):
|
||||||
|
@ -84,10 +86,10 @@ class _ListOption(UserList.UserList):
|
||||||
return 'all'
|
return 'all'
|
||||||
else:
|
else:
|
||||||
return string.join(self, ',')
|
return string.join(self, ',')
|
||||||
#def __repr__(self):
|
def __repr__(self):
|
||||||
# todo: implement this
|
return self.__str__()
|
||||||
|
|
||||||
def _converter(val, allowedElems):
|
def _converter(val, allowedElems, mapdict):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
if val == 'none':
|
if val == 'none':
|
||||||
|
@ -96,10 +98,8 @@ def _converter(val, allowedElems):
|
||||||
val = allowedElems
|
val = allowedElems
|
||||||
else:
|
else:
|
||||||
val = filter(None, string.split(val, ','))
|
val = filter(None, string.split(val, ','))
|
||||||
notAllowed = []
|
val = map(lambda v, m=mapdict: m.get(v, v), val)
|
||||||
for v in val:
|
notAllowed = filter(lambda v, aE=allowedElems: not v in aE, val)
|
||||||
if not v in allowedElems:
|
|
||||||
notAllowed.append(v)
|
|
||||||
if notAllowed:
|
if notAllowed:
|
||||||
raise ValueError("Invalid value(s) for option: %s" %
|
raise ValueError("Invalid value(s) for option: %s" %
|
||||||
string.join(notAllowed, ','))
|
string.join(notAllowed, ','))
|
||||||
|
@ -113,7 +113,7 @@ def _converter(val, allowedElems):
|
||||||
## return 1
|
## return 1
|
||||||
|
|
||||||
|
|
||||||
def ListOption(key, help, default, names):
|
def ListOption(key, help, default, names, map={}):
|
||||||
"""
|
"""
|
||||||
The input parameters describe a 'package list' option, thus they
|
The input parameters describe a 'package list' option, thus they
|
||||||
are returned with the correct converter and validater appended. The
|
are returned with the correct converter and validater appended. The
|
||||||
|
@ -123,9 +123,11 @@ def ListOption(key, help, default, names):
|
||||||
package names (separated by space).
|
package names (separated by space).
|
||||||
"""
|
"""
|
||||||
names_str = 'allowed names: %s' % string.join(names, ' ')
|
names_str = 'allowed names: %s' % string.join(names, ' ')
|
||||||
|
if SCons.Util.is_List(default):
|
||||||
|
default = string.join(default, ',')
|
||||||
help = string.join(
|
help = string.join(
|
||||||
(help, '(all|none|comma-separated list of names)', names_str),
|
(help, '(all|none|comma-separated list of names)', names_str),
|
||||||
'\n ')
|
'\n ')
|
||||||
return (key, help, default,
|
return (key, help, default,
|
||||||
None, #_validator,
|
None, #_validator,
|
||||||
lambda val, elems=names: _converter(val, elems))
|
lambda val, elems=names, m=map: _converter(val, elems, m))
|
|
@ -28,7 +28,7 @@ Usage example:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -50,17 +50,17 @@ Usage example:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/PackageOption.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/PackageOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
__all__ = ('PackageOption', 'True', 'False')
|
__all__ = ('PackageOption')
|
||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
||||||
from BoolOption import True, False
|
import SCons.compat
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
|
|
||||||
__enable_strings = (str(True), 'yes', 'true', 'on', 'enable', 'search')
|
__enable_strings = ('1', 'yes', 'true', 'on', 'enable', 'search')
|
||||||
__disable_strings = (str(False), 'no', 'false', 'off', 'disable')
|
__disable_strings = ('0', 'no', 'false', 'off', 'disable')
|
||||||
|
|
||||||
def _converter(val):
|
def _converter(val):
|
||||||
"""
|
"""
|
||||||
|
@ -78,12 +78,10 @@ def _validator(key, val, env, searchfunc):
|
||||||
"""
|
"""
|
||||||
# todo: write validator, check for path
|
# todo: write validator, check for path
|
||||||
import os
|
import os
|
||||||
if env[key] == False:
|
if env[key] is True:
|
||||||
pass
|
|
||||||
elif env[key] == True:
|
|
||||||
if searchfunc:
|
if searchfunc:
|
||||||
env[key] = searchfunc(key, val)
|
env[key] = searchfunc(key, val)
|
||||||
elif not os.path.exists(val):
|
elif env[key] and not os.path.exists(val):
|
||||||
raise SCons.Errors.UserError(
|
raise SCons.Errors.UserError(
|
||||||
'Path does not exist for option %s: %s' % (key, val))
|
'Path does not exist for option %s: %s' % (key, val))
|
||||||
|
|
134
scons/scons-local-0.97/SCons/Options/PathOption.py
Normal file
134
scons/scons-local-0.97/SCons/Options/PathOption.py
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
"""SCons.Options.PathOption
|
||||||
|
|
||||||
|
This file defines an option type for SCons implementing path settings.
|
||||||
|
|
||||||
|
To be used whenever a a user-specified path override should be allowed.
|
||||||
|
|
||||||
|
Arguments to PathOption are:
|
||||||
|
option-name = name of this option on the command line (e.g. "prefix")
|
||||||
|
option-help = help string for option
|
||||||
|
option-dflt = default value for this option
|
||||||
|
validator = [optional] validator for option value. Predefined
|
||||||
|
validators are:
|
||||||
|
|
||||||
|
PathAccept -- accepts any path setting; no validation
|
||||||
|
PathIsDir -- path must be an existing directory
|
||||||
|
PathIsDirCreate -- path must be a dir; will create
|
||||||
|
PathIsFile -- path must be a file
|
||||||
|
PathExists -- path must exist (any type) [default]
|
||||||
|
|
||||||
|
The validator is a function that is called and which
|
||||||
|
should return True or False to indicate if the path
|
||||||
|
is valid. The arguments to the validator function
|
||||||
|
are: (key, val, env). The key is the name of the
|
||||||
|
option, the val is the path specified for the option,
|
||||||
|
and the env is the env to which the Otions have been
|
||||||
|
added.
|
||||||
|
|
||||||
|
Usage example:
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
prefix=/usr/local
|
||||||
|
|
||||||
|
opts = Options()
|
||||||
|
|
||||||
|
opts = Options()
|
||||||
|
opts.Add(PathOption('qtdir',
|
||||||
|
'where the root of Qt is installed',
|
||||||
|
qtdir, PathIsDir))
|
||||||
|
opts.Add(PathOption('qt_includes',
|
||||||
|
'where the Qt includes are installed',
|
||||||
|
'$qtdir/includes', PathIsDirCreate))
|
||||||
|
opts.Add(PathOption('qt_libraries',
|
||||||
|
'where the Qt library is installed',
|
||||||
|
'$qtdir/lib'))
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Options/PathOption.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import SCons.Errors
|
||||||
|
|
||||||
|
class _PathOptionClass:
|
||||||
|
|
||||||
|
def PathAccept(self, key, val, env):
|
||||||
|
"""Accepts any path, no checking done."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def PathIsDir(self, key, val, env):
|
||||||
|
"""Validator to check if Path is a directory."""
|
||||||
|
if not os.path.isdir(val):
|
||||||
|
if os.path.isfile(val):
|
||||||
|
m = 'Directory path for option %s is a file: %s'
|
||||||
|
else:
|
||||||
|
m = 'Directory path for option %s does not exist: %s'
|
||||||
|
raise SCons.Errors.UserError(m % (key, val))
|
||||||
|
|
||||||
|
def PathIsDirCreate(self, key, val, env):
|
||||||
|
"""Validator to check if Path is a directory,
|
||||||
|
creating it if it does not exist."""
|
||||||
|
if os.path.isfile(val):
|
||||||
|
m = 'Path for option %s is a file, not a directory: %s'
|
||||||
|
raise SCons.Errors.UserError(m % (key, val))
|
||||||
|
if not os.path.isdir(val):
|
||||||
|
os.makedirs(val)
|
||||||
|
|
||||||
|
def PathIsFile(self, key, val, env):
|
||||||
|
"""validator to check if Path is a file"""
|
||||||
|
if not os.path.isfile(val):
|
||||||
|
if os.path.isdir(val):
|
||||||
|
m = 'File path for option %s is a directory: %s'
|
||||||
|
else:
|
||||||
|
m = 'File path for option %s does not exist: %s'
|
||||||
|
raise SCons.Errors.UserError(m % (key, val))
|
||||||
|
|
||||||
|
def PathExists(self, key, val, env):
|
||||||
|
"""validator to check if Path exists"""
|
||||||
|
if not os.path.exists(val):
|
||||||
|
m = 'Path for option %s does not exist: %s'
|
||||||
|
raise SCons.Errors.UserError(m % (key, val))
|
||||||
|
|
||||||
|
def __call__(self, key, help, default, validator=None):
|
||||||
|
# NB: searchfunc is currenty undocumented and unsupported
|
||||||
|
"""
|
||||||
|
The input parameters describe a 'path list' option, thus they
|
||||||
|
are returned with the correct converter and validator appended. The
|
||||||
|
result is usable for input to opts.Add() .
|
||||||
|
|
||||||
|
The 'default' option specifies the default path to use if the
|
||||||
|
user does not specify an override with this option.
|
||||||
|
|
||||||
|
validator is a validator, see this file for examples
|
||||||
|
"""
|
||||||
|
if validator is None:
|
||||||
|
validator = self.PathExists
|
||||||
|
return (key, '%s ( /path/to/%s )' % (help, key), default,
|
||||||
|
validator, None)
|
||||||
|
|
||||||
|
PathOption = _PathOptionClass()
|
|
@ -5,7 +5,7 @@ customizable variables to an SCons build.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,15 +27,16 @@ customizable variables to an SCons build.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/__init__.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Options/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
import string
|
||||||
|
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
|
|
||||||
from BoolOption import BoolOption, True, False # okay
|
from BoolOption import BoolOption # okay
|
||||||
from EnumOption import EnumOption # okay
|
from EnumOption import EnumOption # okay
|
||||||
from ListOption import ListOption # naja
|
from ListOption import ListOption # naja
|
||||||
from PackageOption import PackageOption # naja
|
from PackageOption import PackageOption # naja
|
||||||
|
@ -75,6 +76,11 @@ class Options:
|
||||||
|
|
||||||
self.options.append(option)
|
self.options.append(option)
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
"""
|
||||||
|
Returns the keywords for the options
|
||||||
|
"""
|
||||||
|
return map(lambda o: o.key, self.options)
|
||||||
|
|
||||||
def Add(self, key, help="", default=None, validator=None, converter=None, **kw):
|
def Add(self, key, help="", default=None, validator=None, converter=None, **kw):
|
||||||
"""
|
"""
|
||||||
|
@ -97,16 +103,8 @@ class Options:
|
||||||
not SCons.Util.is_valid_construction_var(key):
|
not SCons.Util.is_valid_construction_var(key):
|
||||||
raise SCons.Errors.UserError, "Illegal Options.Add() key `%s'" % str(key)
|
raise SCons.Errors.UserError, "Illegal Options.Add() key `%s'" % str(key)
|
||||||
|
|
||||||
if kw.has_key('validater'):
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
|
|
||||||
"The 'validater' keyword of the Options.Add() method is deprecated\n" +\
|
|
||||||
"and should be changed to 'validator'.")
|
|
||||||
if validator is None:
|
|
||||||
validator = kw['validater']
|
|
||||||
|
|
||||||
self._do_add(key, help, default, validator, converter)
|
self._do_add(key, help, default, validator, converter)
|
||||||
|
|
||||||
|
|
||||||
def AddOptions(self, *optlist):
|
def AddOptions(self, *optlist):
|
||||||
"""
|
"""
|
||||||
Add a list of options.
|
Add a list of options.
|
||||||
|
@ -165,14 +163,17 @@ class Options:
|
||||||
if option.converter and values.has_key(option.key):
|
if option.converter and values.has_key(option.key):
|
||||||
value = env.subst('${%s}'%option.key)
|
value = env.subst('${%s}'%option.key)
|
||||||
try:
|
try:
|
||||||
env[option.key] = option.converter(value)
|
try:
|
||||||
|
env[option.key] = option.converter(value)
|
||||||
|
except TypeError:
|
||||||
|
env[option.key] = option.converter(value, env)
|
||||||
except ValueError, x:
|
except ValueError, x:
|
||||||
raise SCons.Errors.UserError, 'Error converting option: %s\n%s'%(option.key, x)
|
raise SCons.Errors.UserError, 'Error converting option: %s\n%s'%(option.key, x)
|
||||||
|
|
||||||
|
|
||||||
# Finally validate the values:
|
# Finally validate the values:
|
||||||
for option in self.options:
|
for option in self.options:
|
||||||
if option.validator:
|
if option.validator and values.has_key(option.key):
|
||||||
option.validator(option.key, env.subst('${%s}'%option.key), env)
|
option.validator(option.key, env.subst('${%s}'%option.key), env)
|
||||||
|
|
||||||
def Save(self, filename, env):
|
def Save(self, filename, env):
|
||||||
|
@ -203,8 +204,12 @@ class Options:
|
||||||
# Convert stuff that has a repr() that
|
# Convert stuff that has a repr() that
|
||||||
# cannot be evaluated into a string
|
# cannot be evaluated into a string
|
||||||
value = SCons.Util.to_String(value)
|
value = SCons.Util.to_String(value)
|
||||||
if env.subst('${%s}' % option.key) != \
|
|
||||||
env.subst(SCons.Util.to_String(option.default)):
|
defaultVal = env.subst(SCons.Util.to_String(option.default))
|
||||||
|
if option.converter:
|
||||||
|
defaultVal = option.converter(defaultVal)
|
||||||
|
|
||||||
|
if str(env.subst('${%s}' % option.key)) != str(defaultVal):
|
||||||
fh.write('%s = %s\n' % (option.key, repr(value)))
|
fh.write('%s = %s\n' % (option.key, repr(value)))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
@ -222,19 +227,23 @@ class Options:
|
||||||
of the options.
|
of the options.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
help_text = ""
|
|
||||||
|
|
||||||
if sort:
|
if sort:
|
||||||
options = self.options[:]
|
options = self.options[:]
|
||||||
options.sort(lambda x,y,func=sort: func(x.key,y.key))
|
options.sort(lambda x,y,func=sort: func(x.key,y.key))
|
||||||
else:
|
else:
|
||||||
options = self.options
|
options = self.options
|
||||||
|
|
||||||
for option in options:
|
def format(opt, self=self, env=env):
|
||||||
help_text = help_text + '\n%s: %s\n default: %s\n'%(option.key, option.help, option.default)
|
if env.has_key(opt.key):
|
||||||
if env.has_key(option.key):
|
actual = env.subst('${%s}' % opt.key)
|
||||||
help_text = help_text + ' actual: %s\n'%env.subst('${%s}'%option.key)
|
|
||||||
else:
|
else:
|
||||||
help_text = help_text + ' actual: None\n'
|
actual = None
|
||||||
|
return self.FormatOptionHelpText(env, opt.key, opt.help, opt.default, actual)
|
||||||
|
lines = filter(None, map(format, options))
|
||||||
|
|
||||||
return help_text
|
return string.join(lines, '')
|
||||||
|
|
||||||
|
format = '\n%s: %s\n default: %s\n actual: %s\n'
|
||||||
|
|
||||||
|
def FormatOptionHelpText(self, env, key, help, default, actual):
|
||||||
|
return self.format % (key, help, default, actual)
|
226
scons/scons-local-0.97/SCons/PathList.py
Normal file
226
scons/scons-local-0.97/SCons/PathList.py
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/PathList.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
__doc__ = """SCons.PathList
|
||||||
|
|
||||||
|
A module for handling lists of directory paths (the sort of things
|
||||||
|
that get set as CPPPATH, LIBPATH, etc.) with as much caching of data and
|
||||||
|
efficiency as we can while still keeping the evaluation delayed so that we
|
||||||
|
Do the Right Thing (almost) regardless of how the variable is specified.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
|
||||||
|
import SCons.Memoize
|
||||||
|
import SCons.Node
|
||||||
|
import SCons.Util
|
||||||
|
|
||||||
|
#
|
||||||
|
# Variables to specify the different types of entries in a PathList object:
|
||||||
|
#
|
||||||
|
|
||||||
|
TYPE_STRING_NO_SUBST = 0 # string with no '$'
|
||||||
|
TYPE_STRING_SUBST = 1 # string containing '$'
|
||||||
|
TYPE_OBJECT = 2 # other object
|
||||||
|
|
||||||
|
def node_conv(obj):
|
||||||
|
"""
|
||||||
|
This is the "string conversion" routine that we have our substitutions
|
||||||
|
use to return Nodes, not strings. This relies on the fact that an
|
||||||
|
EntryProxy object has a get() method that returns the underlying
|
||||||
|
Node that it wraps, which is a bit of architectural dependence
|
||||||
|
that we might need to break or modify in the future in response to
|
||||||
|
additional requirements.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
get = obj.get
|
||||||
|
except AttributeError:
|
||||||
|
if isinstance(obj, SCons.Node.Node):
|
||||||
|
result = obj
|
||||||
|
else:
|
||||||
|
result = str(obj)
|
||||||
|
else:
|
||||||
|
result = get()
|
||||||
|
return result
|
||||||
|
|
||||||
|
class _PathList:
|
||||||
|
"""
|
||||||
|
An actual PathList object.
|
||||||
|
"""
|
||||||
|
def __init__(self, pathlist):
|
||||||
|
"""
|
||||||
|
Initializes a PathList object, canonicalizing the input and
|
||||||
|
pre-processing it for quicker substitution later.
|
||||||
|
|
||||||
|
The stored representation of the PathList is a list of tuples
|
||||||
|
containing (type, value), where the "type" is one of the TYPE_*
|
||||||
|
variables defined above. We distinguish between:
|
||||||
|
|
||||||
|
strings that contain no '$' and therefore need no
|
||||||
|
delayed-evaluation string substitution (we expect that there
|
||||||
|
will be many of these and that we therefore get a pretty
|
||||||
|
big win from avoiding string substitution)
|
||||||
|
|
||||||
|
strings that contain '$' and therefore need substitution
|
||||||
|
(the hard case is things like '${TARGET.dir}/include',
|
||||||
|
which require re-evaluation for every target + source)
|
||||||
|
|
||||||
|
other objects (which may be something like an EntryProxy
|
||||||
|
that needs a method called to return a Node)
|
||||||
|
|
||||||
|
Pre-identifying the type of each element in the PathList up-front
|
||||||
|
and storing the type in the list of tuples is intended to reduce
|
||||||
|
the amount of calculation when we actually do the substitution
|
||||||
|
over and over for each target.
|
||||||
|
"""
|
||||||
|
if SCons.Util.is_String(pathlist):
|
||||||
|
pathlist = string.split(pathlist, os.pathsep)
|
||||||
|
elif not SCons.Util.is_Sequence(pathlist):
|
||||||
|
pathlist = [pathlist]
|
||||||
|
|
||||||
|
pl = []
|
||||||
|
for p in pathlist:
|
||||||
|
try:
|
||||||
|
index = string.find(p, '$')
|
||||||
|
except (AttributeError, TypeError):
|
||||||
|
type = TYPE_OBJECT
|
||||||
|
else:
|
||||||
|
if index == -1:
|
||||||
|
type = TYPE_STRING_NO_SUBST
|
||||||
|
else:
|
||||||
|
type = TYPE_STRING_SUBST
|
||||||
|
pl.append((type, p))
|
||||||
|
|
||||||
|
self.pathlist = tuple(pl)
|
||||||
|
|
||||||
|
def __len__(self): return len(self.pathlist)
|
||||||
|
|
||||||
|
def __getitem__(self, i): return self.pathlist[i]
|
||||||
|
|
||||||
|
def subst_path(self, env, target, source):
|
||||||
|
"""
|
||||||
|
Performs construction variable substitution on a pre-digested
|
||||||
|
PathList for a specific target and source.
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
for type, value in self.pathlist:
|
||||||
|
if type == TYPE_STRING_SUBST:
|
||||||
|
value = env.subst(value, target=target, source=source,
|
||||||
|
conv=node_conv)
|
||||||
|
if SCons.Util.is_Sequence(value):
|
||||||
|
# It came back as a string or tuple, which in this
|
||||||
|
# case usually means some variable expanded to an
|
||||||
|
# actually Dir node. Concatenate the values.
|
||||||
|
value = string.join(map(str, value), '')
|
||||||
|
elif type == TYPE_OBJECT:
|
||||||
|
value = node_conv(value)
|
||||||
|
result.append(value)
|
||||||
|
return tuple(result)
|
||||||
|
|
||||||
|
|
||||||
|
class PathListCache:
|
||||||
|
"""
|
||||||
|
A class to handle caching of PathList lookups.
|
||||||
|
|
||||||
|
This class gets instantiated once and then deleted from the namespace,
|
||||||
|
so it's used as a Singleton (although we don't enforce that in the
|
||||||
|
usual Pythonic ways). We could have just made the cache a dictionary
|
||||||
|
in the module namespace, but putting it in this class allows us to
|
||||||
|
use the same Memoizer pattern that we use elsewhere to count cache
|
||||||
|
hits and misses, which is very valuable.
|
||||||
|
|
||||||
|
Lookup keys in the cache are computed by the _PathList_key() method.
|
||||||
|
Cache lookup should be quick, so we don't spend cycles canonicalizing
|
||||||
|
all forms of the same lookup key. For example, 'x:y' and ['x',
|
||||||
|
'y'] logically represent the same list, but we don't bother to
|
||||||
|
split string representations and treat those two equivalently.
|
||||||
|
(Note, however, that we do, treat lists and tuples the same.)
|
||||||
|
|
||||||
|
The main type of duplication we're trying to catch will come from
|
||||||
|
looking up the same path list from two different clones of the
|
||||||
|
same construction environment. That is, given
|
||||||
|
|
||||||
|
env2 = env1.Clone()
|
||||||
|
|
||||||
|
both env1 and env2 will have the same CPPPATH value, and we can
|
||||||
|
cheaply avoid re-parsing both values of CPPPATH by using the
|
||||||
|
common value from this cache.
|
||||||
|
"""
|
||||||
|
if SCons.Memoize.use_memoizer:
|
||||||
|
__metaclass__ = SCons.Memoize.Memoized_Metaclass
|
||||||
|
|
||||||
|
memoizer_counters = []
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._memo = {}
|
||||||
|
|
||||||
|
def _PathList_key(self, pathlist):
|
||||||
|
"""
|
||||||
|
Returns the key for memoization of PathLists.
|
||||||
|
|
||||||
|
Note that we want this to be pretty quick, so we don't completely
|
||||||
|
canonicalize all forms of the same list. For example,
|
||||||
|
'dir1:$ROOT/dir2' and ['$ROOT/dir1', 'dir'] may logically
|
||||||
|
represent the same list if you're executing from $ROOT, but
|
||||||
|
we're not going to bother splitting strings into path elements,
|
||||||
|
or massaging strings into Nodes, to identify that equivalence.
|
||||||
|
We just want to eliminate obvious redundancy from the normal
|
||||||
|
case of re-using exactly the same cloned value for a path.
|
||||||
|
"""
|
||||||
|
if SCons.Util.is_Sequence(pathlist):
|
||||||
|
pathlist = tuple(SCons.Util.flatten(pathlist))
|
||||||
|
return pathlist
|
||||||
|
|
||||||
|
memoizer_counters.append(SCons.Memoize.CountDict('PathList', _PathList_key))
|
||||||
|
|
||||||
|
def PathList(self, pathlist):
|
||||||
|
"""
|
||||||
|
Returns the cached _PathList object for the specified pathlist,
|
||||||
|
creating and caching a new object as necessary.
|
||||||
|
"""
|
||||||
|
pathlist = self._PathList_key(pathlist)
|
||||||
|
try:
|
||||||
|
memo_dict = self._memo['PathList']
|
||||||
|
except KeyError:
|
||||||
|
memo_dict = {}
|
||||||
|
self._memo['PathList'] = memo_dict
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return memo_dict[pathlist]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
result = _PathList(pathlist)
|
||||||
|
|
||||||
|
memo_dict[pathlist] = result
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
PathList = PathListCache().PathList
|
||||||
|
|
||||||
|
|
||||||
|
del PathListCache
|
216
scons/scons-local-0.97/SCons/Platform/__init__.py
Normal file
216
scons/scons-local-0.97/SCons/Platform/__init__.py
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
"""SCons.Platform
|
||||||
|
|
||||||
|
SCons platform selection.
|
||||||
|
|
||||||
|
This looks for modules that define a callable object that can modify a
|
||||||
|
construction environment as appropriate for a given platform.
|
||||||
|
|
||||||
|
Note that we take a more simplistic view of "platform" than Python does.
|
||||||
|
We're looking for a single string that determines a set of
|
||||||
|
tool-independent variables with which to initialize a construction
|
||||||
|
environment. Consequently, we'll examine both sys.platform and os.name
|
||||||
|
(and anything else that might come in to play) in order to return some
|
||||||
|
specification which is unique enough for our purposes.
|
||||||
|
|
||||||
|
Note that because this subsysem just *selects* a callable that can
|
||||||
|
modify a construction environment, it's possible for people to define
|
||||||
|
their own "platform specification" in an arbitrary callable function.
|
||||||
|
No one needs to use or tie in to this subsystem in order to roll
|
||||||
|
their own platform definition.
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Platform/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import imp
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
import SCons.Errors
|
||||||
|
import SCons.Tool
|
||||||
|
|
||||||
|
def platform_default():
|
||||||
|
"""Return the platform string for our execution environment.
|
||||||
|
|
||||||
|
The returned value should map to one of the SCons/Platform/*.py
|
||||||
|
files. Since we're architecture independent, though, we don't
|
||||||
|
care about the machine architecture.
|
||||||
|
"""
|
||||||
|
osname = os.name
|
||||||
|
if osname == 'java':
|
||||||
|
osname = os._osType
|
||||||
|
if osname == 'posix':
|
||||||
|
if sys.platform == 'cygwin':
|
||||||
|
return 'cygwin'
|
||||||
|
elif string.find(sys.platform, 'irix') != -1:
|
||||||
|
return 'irix'
|
||||||
|
elif string.find(sys.platform, 'sunos') != -1:
|
||||||
|
return 'sunos'
|
||||||
|
elif string.find(sys.platform, 'hp-ux') != -1:
|
||||||
|
return 'hpux'
|
||||||
|
elif string.find(sys.platform, 'aix') != -1:
|
||||||
|
return 'aix'
|
||||||
|
elif string.find(sys.platform, 'darwin') != -1:
|
||||||
|
return 'darwin'
|
||||||
|
else:
|
||||||
|
return 'posix'
|
||||||
|
elif os.name == 'os2':
|
||||||
|
return 'os2'
|
||||||
|
else:
|
||||||
|
return sys.platform
|
||||||
|
|
||||||
|
def platform_module(name = platform_default()):
|
||||||
|
"""Return the imported module for the platform.
|
||||||
|
|
||||||
|
This looks for a module name that matches the specified argument.
|
||||||
|
If the name is unspecified, we fetch the appropriate default for
|
||||||
|
our execution environment.
|
||||||
|
"""
|
||||||
|
full_name = 'SCons.Platform.' + name
|
||||||
|
if not sys.modules.has_key(full_name):
|
||||||
|
if os.name == 'java':
|
||||||
|
eval(full_name)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
file, path, desc = imp.find_module(name,
|
||||||
|
sys.modules['SCons.Platform'].__path__)
|
||||||
|
try:
|
||||||
|
mod = imp.load_module(full_name, file, path, desc)
|
||||||
|
finally:
|
||||||
|
if file:
|
||||||
|
file.close()
|
||||||
|
except ImportError:
|
||||||
|
try:
|
||||||
|
import zipimport
|
||||||
|
importer = zipimport.zipimporter( sys.modules['SCons.Platform'].__path__[0] )
|
||||||
|
mod = importer.load_module(full_name)
|
||||||
|
except ImportError:
|
||||||
|
raise SCons.Errors.UserError, "No platform named '%s'" % name
|
||||||
|
setattr(SCons.Platform, name, mod)
|
||||||
|
return sys.modules[full_name]
|
||||||
|
|
||||||
|
def DefaultToolList(platform, env):
|
||||||
|
"""Select a default tool list for the specified platform.
|
||||||
|
"""
|
||||||
|
return SCons.Tool.tool_list(platform, env)
|
||||||
|
|
||||||
|
class PlatformSpec:
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class TempFileMunge:
|
||||||
|
"""A callable class. You can set an Environment variable to this,
|
||||||
|
then call it with a string argument, then it will perform temporary
|
||||||
|
file substitution on it. This is used to circumvent the long command
|
||||||
|
line limitation.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
env["TEMPFILE"] = TempFileMunge
|
||||||
|
env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES')}"
|
||||||
|
|
||||||
|
By default, the name of the temporary file used begins with a
|
||||||
|
prefix of '@'. This may be configred for other tool chains by
|
||||||
|
setting '$TEMPFILEPREFIX'.
|
||||||
|
|
||||||
|
env["TEMPFILEPREFIX"] = '-@' # diab compiler
|
||||||
|
env["TEMPFILEPREFIX"] = '-via' # arm tool chain
|
||||||
|
"""
|
||||||
|
def __init__(self, cmd):
|
||||||
|
self.cmd = cmd
|
||||||
|
|
||||||
|
def __call__(self, target, source, env, for_signature):
|
||||||
|
if for_signature:
|
||||||
|
return self.cmd
|
||||||
|
cmd = env.subst_list(self.cmd, 0, target, source)[0]
|
||||||
|
try:
|
||||||
|
maxline = int(env.subst('$MAXLINELENGTH'))
|
||||||
|
except ValueError:
|
||||||
|
maxline = 2048
|
||||||
|
|
||||||
|
if (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= maxline:
|
||||||
|
return self.cmd
|
||||||
|
|
||||||
|
# We do a normpath because mktemp() has what appears to be
|
||||||
|
# a bug in Windows that will use a forward slash as a path
|
||||||
|
# delimiter. Windows's link mistakes that for a command line
|
||||||
|
# switch and barfs.
|
||||||
|
#
|
||||||
|
# We use the .lnk suffix for the benefit of the Phar Lap
|
||||||
|
# linkloc linker, which likes to append an .lnk suffix if
|
||||||
|
# none is given.
|
||||||
|
tmp = os.path.normpath(tempfile.mktemp('.lnk'))
|
||||||
|
native_tmp = SCons.Util.get_native_path(tmp)
|
||||||
|
|
||||||
|
if env['SHELL'] and env['SHELL'] == 'sh':
|
||||||
|
# The sh shell will try to escape the backslashes in the
|
||||||
|
# path, so unescape them.
|
||||||
|
native_tmp = string.replace(native_tmp, '\\', r'\\\\')
|
||||||
|
# In Cygwin, we want to use rm to delete the temporary
|
||||||
|
# file, because del does not exist in the sh shell.
|
||||||
|
rm = env.Detect('rm') or 'del'
|
||||||
|
else:
|
||||||
|
# Don't use 'rm' if the shell is not sh, because rm won't
|
||||||
|
# work with the Windows shells (cmd.exe or command.com) or
|
||||||
|
# Windows path names.
|
||||||
|
rm = 'del'
|
||||||
|
|
||||||
|
prefix = env.subst('$TEMPFILEPREFIX')
|
||||||
|
if not prefix:
|
||||||
|
prefix = '@'
|
||||||
|
|
||||||
|
args = map(SCons.Subst.quote_spaces, cmd[1:])
|
||||||
|
open(tmp, 'w').write(string.join(args, " ") + "\n")
|
||||||
|
# XXX Using the SCons.Action.print_actions value directly
|
||||||
|
# like this is bogus, but expedient. This class should
|
||||||
|
# really be rewritten as an Action that defines the
|
||||||
|
# __call__() and strfunction() methods and lets the
|
||||||
|
# normal action-execution logic handle whether or not to
|
||||||
|
# print/execute the action. The problem, though, is all
|
||||||
|
# of that is decided before we execute this method as
|
||||||
|
# part of expanding the $TEMPFILE construction variable.
|
||||||
|
# Consequently, refactoring this will have to wait until
|
||||||
|
# we get more flexible with allowing Actions to exist
|
||||||
|
# independently and get strung together arbitrarily like
|
||||||
|
# Ant tasks. In the meantime, it's going to be more
|
||||||
|
# user-friendly to not let obsession with architectural
|
||||||
|
# purity get in the way of just being helpful, so we'll
|
||||||
|
# reach into SCons.Action directly.
|
||||||
|
if SCons.Action.print_actions:
|
||||||
|
print("Using tempfile "+native_tmp+" for command line:\n"+
|
||||||
|
str(cmd[0]) + " " + string.join(args," "))
|
||||||
|
return [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ]
|
||||||
|
|
||||||
|
def Platform(name = platform_default()):
|
||||||
|
"""Select a canned Platform specification.
|
||||||
|
"""
|
||||||
|
module = platform_module(name)
|
||||||
|
spec = PlatformSpec(name)
|
||||||
|
spec.__call__ = module.generate
|
||||||
|
return spec
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,20 +30,23 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/aix.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/aix.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import string
|
import string
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
||||||
def get_xlc(env, xlc, xlc_r, packages):
|
def get_xlc(env, xlc=None, xlc_r=None, packages=[]):
|
||||||
# Use the AIX package installer tool lslpp to figure out where a
|
# Use the AIX package installer tool lslpp to figure out where a
|
||||||
# given xl* compiler is installed and what version it is.
|
# given xl* compiler is installed and what version it is.
|
||||||
xlcPath = None
|
xlcPath = None
|
||||||
xlcVersion = None
|
xlcVersion = None
|
||||||
|
|
||||||
xlc = env.get('CC', 'xlc')
|
if xlc is None:
|
||||||
|
xlc = env.get('CC', 'xlc')
|
||||||
|
if xlc_r is None:
|
||||||
|
xlc_r = xlc + '_r'
|
||||||
for package in packages:
|
for package in packages:
|
||||||
cmd = "lslpp -fc " + package + " 2>/dev/null | egrep '" + xlc + "([^-_a-zA-Z0-9].*)?$'"
|
cmd = "lslpp -fc " + package + " 2>/dev/null | egrep '" + xlc + "([^-_a-zA-Z0-9].*)?$'"
|
||||||
line = os.popen(cmd).readline()
|
line = os.popen(cmd).readline()
|
||||||
|
@ -57,3 +60,6 @@ def get_xlc(env, xlc, xlc_r, packages):
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
posix.generate(env)
|
posix.generate(env)
|
||||||
|
#Based on AIX 5.2: ARG_MAX=24576 - 3000 for environment expansion
|
||||||
|
env['MAXLINELENGTH'] = 21576
|
||||||
|
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,10 +30,10 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/cygwin.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/cygwin.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
import win32
|
from SCons.Platform import TempFileMunge
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
posix.generate(env)
|
posix.generate(env)
|
||||||
|
@ -44,4 +44,6 @@ def generate(env):
|
||||||
env['SHLIBSUFFIX'] = '.dll'
|
env['SHLIBSUFFIX'] = '.dll'
|
||||||
env['LIBPREFIXES'] = [ '$LIBPREFIX', '$SHLIBPREFIX' ]
|
env['LIBPREFIXES'] = [ '$LIBPREFIX', '$SHLIBPREFIX' ]
|
||||||
env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ]
|
env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ]
|
||||||
env['TEMPFILE'] = win32.TempFileMunge
|
env['TEMPFILE'] = TempFileMunge
|
||||||
|
env['TEMPFILEPREFIX'] = '@'
|
||||||
|
env['MAXLINELENGTH'] = 2048
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,11 +30,11 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/darwin.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/darwin.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
import os
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
posix.generate(env)
|
posix.generate(env)
|
||||||
env['SHLIBSUFFIX'] = '.dylib'
|
env['SHLIBSUFFIX'] = '.dylib'
|
||||||
|
env['ENV']['PATH'] = env['ENV']['PATH'] + ':/sw/bin'
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,9 +30,11 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/hpux.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/hpux.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
posix.generate(env)
|
posix.generate(env)
|
||||||
|
#Based on HP-UX11i: ARG_MAX=2048000 - 3000 for environment expansion
|
||||||
|
env['MAXLINELENGTH'] = 2045000
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/irix.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/irix.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/os2.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/os2.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if not env.has_key('ENV'):
|
if not env.has_key('ENV'):
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/posix.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/posix.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -40,6 +40,7 @@ import sys
|
||||||
import select
|
import select
|
||||||
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
from SCons.Platform import TempFileMunge
|
||||||
|
|
||||||
exitvalmap = {
|
exitvalmap = {
|
||||||
2 : 127,
|
2 : 127,
|
||||||
|
@ -57,42 +58,28 @@ def escape(arg):
|
||||||
|
|
||||||
return '"' + arg + '"'
|
return '"' + arg + '"'
|
||||||
|
|
||||||
def _get_env_command(sh, escape, cmd, args, env):
|
def exec_system(l, env):
|
||||||
if env:
|
stat = os.system(string.join(l))
|
||||||
s = 'env - '
|
|
||||||
for key in env.keys():
|
|
||||||
s = s + '%s=%s '%(key, escape(env[key]))
|
|
||||||
s = s + sh + ' -c '
|
|
||||||
s = s + escape(string.join(args))
|
|
||||||
else:
|
|
||||||
s = string.join(args)
|
|
||||||
return s
|
|
||||||
|
|
||||||
def env_spawn(sh, escape, cmd, args, env):
|
|
||||||
s = _get_env_command( sh, escape, cmd, args, env)
|
|
||||||
stat = os.system(s)
|
|
||||||
if stat & 0xff:
|
if stat & 0xff:
|
||||||
return stat | 0x80
|
return stat | 0x80
|
||||||
return stat >> 8
|
return stat >> 8
|
||||||
|
|
||||||
def spawn_spawn(sh, escape, cmd, args, env):
|
def exec_spawnvpe(l, env):
|
||||||
args = [sh, '-c', string.join(args)]
|
stat = os.spawnvpe(os.P_WAIT, l[0], l, env)
|
||||||
stat = os.spawnvpe(os.P_WAIT, sh, args, env)
|
|
||||||
# os.spawnvpe() returns the actual exit code, not the encoding
|
# os.spawnvpe() returns the actual exit code, not the encoding
|
||||||
# returned by os.waitpid() or os.system().
|
# returned by os.waitpid() or os.system().
|
||||||
return stat
|
return stat
|
||||||
|
|
||||||
def fork_spawn(sh, escape, cmd, args, env):
|
def exec_fork(l, env):
|
||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
if not pid:
|
if not pid:
|
||||||
# Child process.
|
# Child process.
|
||||||
exitval = 127
|
exitval = 127
|
||||||
args = [sh, '-c', string.join(args)]
|
|
||||||
try:
|
try:
|
||||||
os.execvpe(sh, args, env)
|
os.execvpe(l[0], l, env)
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
exitval = exitvalmap[e[0]]
|
exitval = exitvalmap.get(e[0], e[0])
|
||||||
sys.stderr.write("scons: %s: %s\n" % (cmd, e[1]))
|
sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
|
||||||
os._exit(exitval)
|
os._exit(exitval)
|
||||||
else:
|
else:
|
||||||
# Parent process.
|
# Parent process.
|
||||||
|
@ -101,6 +88,24 @@ def fork_spawn(sh, escape, cmd, args, env):
|
||||||
return stat | 0x80
|
return stat | 0x80
|
||||||
return stat >> 8
|
return stat >> 8
|
||||||
|
|
||||||
|
def _get_env_command(sh, escape, cmd, args, env):
|
||||||
|
s = string.join(args)
|
||||||
|
if env:
|
||||||
|
l = ['env', '-'] + \
|
||||||
|
map(lambda t, e=escape: t[0]+'='+e(t[1]), env.items()) + \
|
||||||
|
[sh, '-c', escape(s)]
|
||||||
|
s = string.join(l)
|
||||||
|
return s
|
||||||
|
|
||||||
|
def env_spawn(sh, escape, cmd, args, env):
|
||||||
|
return exec_system([_get_env_command( sh, escape, cmd, args, env)], env)
|
||||||
|
|
||||||
|
def spawnvpe_spawn(sh, escape, cmd, args, env):
|
||||||
|
return exec_spawnvpe([sh, '-c', string.join(args)], env)
|
||||||
|
|
||||||
|
def fork_spawn(sh, escape, cmd, args, env):
|
||||||
|
return exec_fork([sh, '-c', string.join(args)], env)
|
||||||
|
|
||||||
def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
|
def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
|
||||||
stdout_eof = stderr_eof = 0
|
stdout_eof = stderr_eof = 0
|
||||||
while not (stdout_eof and stderr_eof):
|
while not (stdout_eof and stderr_eof):
|
||||||
|
@ -120,20 +125,15 @@ def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
|
||||||
#sys.__stderr__.write( "str(stderr) = %s\n" % str )
|
#sys.__stderr__.write( "str(stderr) = %s\n" % str )
|
||||||
stderr.write(str)
|
stderr.write(str)
|
||||||
|
|
||||||
|
def exec_popen3(l, env, stdout, stderr):
|
||||||
def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
proc = popen2.Popen3(string.join(l), 1)
|
||||||
# spawn using Popen3 combined with the env command
|
|
||||||
# the command name and the command's stdout is written to stdout
|
|
||||||
# the command's stderr is written to stderr
|
|
||||||
s = _get_env_command( sh, escape, cmd, args, env)
|
|
||||||
proc = popen2.Popen3(s, 1)
|
|
||||||
process_cmd_output(proc.fromchild, proc.childerr, stdout, stderr)
|
process_cmd_output(proc.fromchild, proc.childerr, stdout, stderr)
|
||||||
stat = proc.wait()
|
stat = proc.wait()
|
||||||
if stat & 0xff:
|
if stat & 0xff:
|
||||||
return stat | 0x80
|
return stat | 0x80
|
||||||
return stat >> 8
|
return stat >> 8
|
||||||
|
|
||||||
def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
def exec_piped_fork(l, env, stdout, stderr):
|
||||||
# spawn using fork / exec and providing a pipe for the command's
|
# spawn using fork / exec and providing a pipe for the command's
|
||||||
# stdout / stderr stream
|
# stdout / stderr stream
|
||||||
if stdout != stderr:
|
if stdout != stderr:
|
||||||
|
@ -156,12 +156,11 @@ def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
if stdout != stderr:
|
if stdout != stderr:
|
||||||
os.close( wFdErr )
|
os.close( wFdErr )
|
||||||
exitval = 127
|
exitval = 127
|
||||||
args = [sh, '-c', string.join(args)]
|
|
||||||
try:
|
try:
|
||||||
os.execvpe(sh, args, env)
|
os.execvpe(l[0], l, env)
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
exitval = exitvalmap[e[0]]
|
exitval = exitvalmap.get(e[0], e[0])
|
||||||
stderr.write("scons: %s: %s\n" % (cmd, e[1]))
|
stderr.write("scons: %s: %s\n" % (l[0], e[1]))
|
||||||
os._exit(exitval)
|
os._exit(exitval)
|
||||||
else:
|
else:
|
||||||
# Parent process
|
# Parent process
|
||||||
|
@ -182,6 +181,19 @@ def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
return stat | 0x80
|
return stat | 0x80
|
||||||
return stat >> 8
|
return stat >> 8
|
||||||
|
|
||||||
|
def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
|
# spawn using Popen3 combined with the env command
|
||||||
|
# the command name and the command's stdout is written to stdout
|
||||||
|
# the command's stderr is written to stderr
|
||||||
|
return exec_popen3([_get_env_command(sh, escape, cmd, args, env)],
|
||||||
|
env, stdout, stderr)
|
||||||
|
|
||||||
|
def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
|
# spawn using fork / exec and providing a pipe for the command's
|
||||||
|
# stdout / stderr stream
|
||||||
|
return exec_piped_fork([sh, '-c', string.join(args)],
|
||||||
|
env, stdout, stderr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
|
@ -199,7 +211,7 @@ def generate(env):
|
||||||
# not be a default that works best for all users.
|
# not be a default that works best for all users.
|
||||||
|
|
||||||
if os.__dict__.has_key('spawnvpe'):
|
if os.__dict__.has_key('spawnvpe'):
|
||||||
spawn = spawn_spawn
|
spawn = spawnvpe_spawn
|
||||||
elif env.Detect('env'):
|
elif env.Detect('env'):
|
||||||
spawn = env_spawn
|
spawn = env_spawn
|
||||||
else:
|
else:
|
||||||
|
@ -212,7 +224,7 @@ def generate(env):
|
||||||
|
|
||||||
if not env.has_key('ENV'):
|
if not env.has_key('ENV'):
|
||||||
env['ENV'] = {}
|
env['ENV'] = {}
|
||||||
env['ENV']['PATH'] = '/usr/local/bin:/bin:/usr/bin'
|
env['ENV']['PATH'] = '/usr/local/bin:/opt/bin:/bin:/usr/bin'
|
||||||
env['OBJPREFIX'] = ''
|
env['OBJPREFIX'] = ''
|
||||||
env['OBJSUFFIX'] = '.o'
|
env['OBJSUFFIX'] = '.o'
|
||||||
env['SHOBJPREFIX'] = '$OBJPREFIX'
|
env['SHOBJPREFIX'] = '$OBJPREFIX'
|
||||||
|
@ -229,6 +241,11 @@ def generate(env):
|
||||||
env['SPAWN'] = spawn
|
env['SPAWN'] = spawn
|
||||||
env['SHELL'] = 'sh'
|
env['SHELL'] = 'sh'
|
||||||
env['ESCAPE'] = escape
|
env['ESCAPE'] = escape
|
||||||
|
env['TEMPFILE'] = TempFileMunge
|
||||||
|
env['TEMPFILEPREFIX'] = '@'
|
||||||
|
#Based on LINUX: ARG_MAX=ARG_MAX=131072 - 3000 for environment expansion
|
||||||
|
#Note: specific platforms might rise or lower this value
|
||||||
|
env['MAXLINELENGTH'] = 128072
|
||||||
|
|
||||||
# This platform supports RPATH specifications.
|
# This platform supports RPATH specifications.
|
||||||
env['__RPATH'] = '$_RPATH'
|
env['__RPATH'] = '$_RPATH'
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,9 +30,15 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/sunos.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/sunos.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import posix
|
import posix
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
posix.generate(env)
|
posix.generate(env)
|
||||||
|
# Based on sunSparc 8:32bit
|
||||||
|
# ARG_MAX=1048320 - 3000 for environment expansion
|
||||||
|
env['MAXLINELENGTH'] = 1045320
|
||||||
|
env['PKGINFO'] = 'pkginfo'
|
||||||
|
env['PKGCHK'] = '/usr/sbin/pkgchk'
|
||||||
|
env['ENV']['PATH'] = env['ENV']['PATH'] + ':/usr/ccs/bin'
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,89 +30,22 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/win32.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Platform/win32.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from SCons.Platform.posix import exitvalmap
|
from SCons.Platform.posix import exitvalmap
|
||||||
|
from SCons.Platform import TempFileMunge
|
||||||
|
|
||||||
# XXX See note below about why importing SCons.Action should be
|
# XXX See note below about why importing SCons.Action should be
|
||||||
# eventually refactored.
|
# eventually refactored.
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
class TempFileMunge:
|
|
||||||
"""A callable class. You can set an Environment variable to this,
|
|
||||||
then call it with a string argument, then it will perform temporary
|
|
||||||
file substitution on it. This is used to circumvent the win32 long command
|
|
||||||
line limitation.
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
env["TEMPFILE"] = TempFileMunge
|
|
||||||
env["LINKCOM"] = "${TEMPFILE('$LINK $TARGET $SOURCES')}"
|
|
||||||
"""
|
|
||||||
def __init__(self, cmd):
|
|
||||||
self.cmd = cmd
|
|
||||||
|
|
||||||
def __call__(self, target, source, env, for_signature):
|
|
||||||
if for_signature:
|
|
||||||
return self.cmd
|
|
||||||
cmd = env.subst_list(self.cmd, 0, target, source)[0]
|
|
||||||
try:
|
|
||||||
maxline = int(env.subst('$MAXLINELENGTH'))
|
|
||||||
except ValueError:
|
|
||||||
maxline = 2048
|
|
||||||
if (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= maxline:
|
|
||||||
return self.cmd
|
|
||||||
else:
|
|
||||||
# We do a normpath because mktemp() has what appears to be
|
|
||||||
# a bug in Win32 that will use a forward slash as a path
|
|
||||||
# delimiter. Win32's link mistakes that for a command line
|
|
||||||
# switch and barfs.
|
|
||||||
#
|
|
||||||
# We use the .lnk suffix for the benefit of the Phar Lap
|
|
||||||
# linkloc linker, which likes to append an .lnk suffix if
|
|
||||||
# none is given.
|
|
||||||
tmp = os.path.normpath(tempfile.mktemp('.lnk'))
|
|
||||||
native_tmp = SCons.Util.get_native_path(tmp)
|
|
||||||
|
|
||||||
if env['SHELL'] and env['SHELL'] == 'sh':
|
|
||||||
# The sh shell will try to escape the backslashes in the
|
|
||||||
# path, so unescape them.
|
|
||||||
native_tmp = string.replace(native_tmp, '\\', r'\\\\')
|
|
||||||
# In Cygwin, we want to use rm to delete the temporary
|
|
||||||
# file, because del does not exist in the sh shell.
|
|
||||||
rm = env.Detect('rm') or 'del'
|
|
||||||
else:
|
|
||||||
# Don't use 'rm' if the shell is not sh, because rm won't
|
|
||||||
# work with the win32 shells (cmd.exe or command.com) or
|
|
||||||
# win32 path names.
|
|
||||||
rm = 'del'
|
|
||||||
|
|
||||||
args = map(SCons.Util.quote_spaces, cmd[1:])
|
|
||||||
open(tmp, 'w').write(string.join(args, " ") + "\n")
|
|
||||||
# XXX Using the SCons.Action.print_actions value directly
|
|
||||||
# like this is bogus, but expedient. This class should
|
|
||||||
# really be rewritten as an Action that defines the
|
|
||||||
# __call__() and strfunction() methods and lets the
|
|
||||||
# normal action-execution logic handle whether or not to
|
|
||||||
# print/execute the action. The problem, though, is all
|
|
||||||
# of that is decided before we execute this method as
|
|
||||||
# part of expanding the $TEMPFILE construction variable.
|
|
||||||
# Consequently, refactoring this will have to wait until
|
|
||||||
# we get more flexible with allowing Actions to exist
|
|
||||||
# independently and get strung together arbitrarily like
|
|
||||||
# Ant tasks. In the meantime, it's going to be more
|
|
||||||
# user-friendly to not let obsession with architectural
|
|
||||||
# purity get in the way of just being helpful, so we'll
|
|
||||||
# reach into SCons.Action directly.
|
|
||||||
if SCons.Action.print_actions:
|
|
||||||
print("Using tempfile "+native_tmp+" for command line:\n"+
|
|
||||||
str(cmd[0]) + " " + string.join(args," "))
|
|
||||||
return [ cmd[0], '@' + native_tmp + '\n' + rm, native_tmp ]
|
|
||||||
|
|
||||||
# The upshot of all this is that, if you are using Python 1.5.2,
|
# The upshot of all this is that, if you are using Python 1.5.2,
|
||||||
# you had better have cmd or command.com in your PATH when you run
|
# you had better have cmd or command.com in your PATH when you run
|
||||||
|
@ -157,7 +90,10 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
ret = os.spawnve(os.P_WAIT, sh, args, env)
|
ret = os.spawnve(os.P_WAIT, sh, args, env)
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
# catch any error
|
# catch any error
|
||||||
ret = exitvalmap[e[0]]
|
try:
|
||||||
|
ret = exitvalmap[e[0]]
|
||||||
|
except KeyError:
|
||||||
|
sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e[0], cmd, e[1]))
|
||||||
if stderr != None:
|
if stderr != None:
|
||||||
stderr.write("scons: %s: %s\n" % (cmd, e[1]))
|
stderr.write("scons: %s: %s\n" % (cmd, e[1]))
|
||||||
# copy child output from tempfiles to our streams
|
# copy child output from tempfiles to our streams
|
||||||
|
@ -177,22 +113,40 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
pass
|
pass
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def exec_spawn(l, env):
|
||||||
|
try:
|
||||||
|
result = os.spawnve(os.P_WAIT, l[0], l, env)
|
||||||
|
except OSError, e:
|
||||||
|
try:
|
||||||
|
result = exitvalmap[e[0]]
|
||||||
|
sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
|
||||||
|
except KeyError:
|
||||||
|
result = 127
|
||||||
|
if len(l) > 2:
|
||||||
|
if len(l[2]) < 1000:
|
||||||
|
command = string.join(l[0:3])
|
||||||
|
else:
|
||||||
|
command = l[0]
|
||||||
|
else:
|
||||||
|
command = l[0]
|
||||||
|
sys.stderr.write("scons: unknown OSError exception code %d - '%s': %s\n" % (e[0], command, e[1]))
|
||||||
|
return result
|
||||||
|
|
||||||
def spawn(sh, escape, cmd, args, env):
|
def spawn(sh, escape, cmd, args, env):
|
||||||
if not sh:
|
if not sh:
|
||||||
sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n")
|
sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n")
|
||||||
return 127
|
return 127
|
||||||
else:
|
return exec_spawn([sh, '/C', escape(string.join(args))], env)
|
||||||
try:
|
|
||||||
args = [sh, '/C', escape(string.join(args)) ]
|
|
||||||
ret = os.spawnve(os.P_WAIT, sh, args, env)
|
|
||||||
except OSError, e:
|
|
||||||
ret = exitvalmap[e[0]]
|
|
||||||
sys.stderr.write("scons: %s: %s\n" % (cmd, e[1]))
|
|
||||||
return ret
|
|
||||||
|
|
||||||
# Windows does not allow special characters in file names anyway, so
|
# Windows does not allow special characters in file names anyway, so no
|
||||||
# no need for a complex escape function, we will just quote the arg.
|
# need for a complex escape function, we will just quote the arg, except
|
||||||
escape = lambda x: '"' + x + '"'
|
# that "cmd /c" requires that if an argument ends with a backslash it
|
||||||
|
# needs to be escaped so as not to interfere with closing double quote
|
||||||
|
# that we add.
|
||||||
|
def escape(x):
|
||||||
|
if x[-1] == '\\':
|
||||||
|
x = x + '\\'
|
||||||
|
return '"' + x + '"'
|
||||||
|
|
||||||
# Get the windows system directory name
|
# Get the windows system directory name
|
||||||
def get_system_root():
|
def get_system_root():
|
||||||
|
@ -298,9 +252,11 @@ def generate(env):
|
||||||
# environment's ENV. This is a potential slippery slope, because we
|
# environment's ENV. This is a potential slippery slope, because we
|
||||||
# *don't* want to make builds dependent on the user's environment by
|
# *don't* want to make builds dependent on the user's environment by
|
||||||
# default. We're doing this for SYSTEMROOT, though, because it's
|
# default. We're doing this for SYSTEMROOT, though, because it's
|
||||||
# needed for anything that uses sockets, and seldom changes. Weigh
|
# needed for anything that uses sockets, and seldom changes, and
|
||||||
# the impact carefully before adding other variables to this list.
|
# for SYSTEMDRIVE because it's related.
|
||||||
import_env = [ 'SYSTEMROOT' ]
|
#
|
||||||
|
# Weigh the impact carefully before adding other variables to this list.
|
||||||
|
import_env = [ 'SYSTEMDRIVE', 'SYSTEMROOT', 'TEMP', 'TMP' ]
|
||||||
for var in import_env:
|
for var in import_env:
|
||||||
v = os.environ.get(var)
|
v = os.environ.get(var)
|
||||||
if v:
|
if v:
|
||||||
|
@ -323,5 +279,6 @@ def generate(env):
|
||||||
env['SPAWN'] = spawn
|
env['SPAWN'] = spawn
|
||||||
env['SHELL'] = cmd_interp
|
env['SHELL'] = cmd_interp
|
||||||
env['TEMPFILE'] = TempFileMunge
|
env['TEMPFILE'] = TempFileMunge
|
||||||
|
env['TEMPFILEPREFIX'] = '@'
|
||||||
env['MAXLINELENGTH'] = 2048
|
env['MAXLINELENGTH'] = 2048
|
||||||
env['ESCAPE'] = escape
|
env['ESCAPE'] = escape
|
|
@ -4,7 +4,7 @@ Autoconf-like configuration support.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -26,11 +26,12 @@ Autoconf-like configuration support.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/SConf.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/SConf.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import cPickle
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import string
|
import string
|
||||||
|
import StringIO
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
import types
|
import types
|
||||||
|
@ -38,41 +39,286 @@ import types
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
|
import SCons.Job
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Taskmaster
|
import SCons.Taskmaster
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
import SCons.Conftest
|
import SCons.Conftest
|
||||||
|
|
||||||
# First i thought of using a different filesystem as the default_fs,
|
# Turn off the Conftest error logging
|
||||||
# but it showed up that there are too many side effects in doing that.
|
SCons.Conftest.LogInputFiles = 0
|
||||||
SConfFS=SCons.Node.FS.default_fs
|
SCons.Conftest.LogErrorMessages = 0
|
||||||
|
|
||||||
# to be set, if we are in dry-run mode
|
# to be set, if we are in dry-run mode
|
||||||
dryrun = 0
|
dryrun = 0
|
||||||
|
|
||||||
_ac_build_counter = 0
|
AUTO=0 # use SCons dependency scanning for up-to-date checks
|
||||||
_ac_config_counter = 0
|
FORCE=1 # force all tests to be rebuilt
|
||||||
_activeSConfObjects = {}
|
CACHE=2 # force all tests to be taken from cache (raise an error, if necessary)
|
||||||
|
cache_mode = AUTO
|
||||||
|
|
||||||
|
def SetCacheMode(mode):
|
||||||
|
"""Set the Configure cache mode. mode must be one of "auto", "force",
|
||||||
|
or "cache"."""
|
||||||
|
global cache_mode
|
||||||
|
if mode == "auto":
|
||||||
|
cache_mode = AUTO
|
||||||
|
elif mode == "force":
|
||||||
|
cache_mode = FORCE
|
||||||
|
elif mode == "cache":
|
||||||
|
cache_mode = CACHE
|
||||||
|
else:
|
||||||
|
raise ValueError, "SCons.SConf.SetCacheMode: Unknown mode " + mode
|
||||||
|
|
||||||
|
progress_display = SCons.Util.display # will be overwritten by SCons.Script
|
||||||
|
def SetProgressDisplay(display):
|
||||||
|
"""Set the progress display to use (called from SCons.Script)"""
|
||||||
|
global progress_display
|
||||||
|
progress_display = display
|
||||||
|
|
||||||
|
SConfFS = None
|
||||||
|
|
||||||
|
_ac_build_counter = 0 # incremented, whenever TryBuild is called
|
||||||
|
_ac_config_logs = {} # all config.log files created in this build
|
||||||
|
_ac_config_hs = {} # all config.h files created in this build
|
||||||
|
sconf_global = None # current sconf object
|
||||||
|
|
||||||
|
def _createConfigH(target, source, env):
|
||||||
|
t = open(str(target[0]), "w")
|
||||||
|
defname = re.sub('[^A-Za-z0-9_]', '_', string.upper(str(target[0])))
|
||||||
|
t.write("""#ifndef %(DEFNAME)s_SEEN
|
||||||
|
#define %(DEFNAME)s_SEEN
|
||||||
|
|
||||||
|
""" % {'DEFNAME' : defname})
|
||||||
|
t.write(source[0].get_contents())
|
||||||
|
t.write("""
|
||||||
|
#endif /* %(DEFNAME)s_SEEN */
|
||||||
|
""" % {'DEFNAME' : defname})
|
||||||
|
t.close()
|
||||||
|
|
||||||
|
def _stringConfigH(target, source, env):
|
||||||
|
return "scons: Configure: creating " + str(target[0])
|
||||||
|
|
||||||
|
def CreateConfigHBuilder(env):
|
||||||
|
"""Called just before the building targets phase begins."""
|
||||||
|
if len(_ac_config_hs) == 0:
|
||||||
|
return
|
||||||
|
action = SCons.Action.Action(_createConfigH,
|
||||||
|
_stringConfigH)
|
||||||
|
sconfigHBld = SCons.Builder.Builder(action=action)
|
||||||
|
env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} )
|
||||||
|
for k in _ac_config_hs.keys():
|
||||||
|
env.SConfigHBuilder(k, env.Value(_ac_config_hs[k]))
|
||||||
|
|
||||||
class SConfWarning(SCons.Warnings.Warning):
|
class SConfWarning(SCons.Warnings.Warning):
|
||||||
pass
|
pass
|
||||||
SCons.Warnings.enableWarningClass( SConfWarning )
|
SCons.Warnings.enableWarningClass(SConfWarning)
|
||||||
|
|
||||||
# action to create the source
|
# some error definitions
|
||||||
|
class SConfError(SCons.Errors.UserError):
|
||||||
|
def __init__(self,msg):
|
||||||
|
SCons.Errors.UserError.__init__(self,msg)
|
||||||
|
|
||||||
|
class ConfigureDryRunError(SConfError):
|
||||||
|
"""Raised when a file or directory needs to be updated during a Configure
|
||||||
|
process, but the user requested a dry-run"""
|
||||||
|
def __init__(self,target):
|
||||||
|
if not isinstance(target, SCons.Node.FS.File):
|
||||||
|
msg = 'Cannot create configure directory "%s" within a dry-run.' % str(target)
|
||||||
|
else:
|
||||||
|
msg = 'Cannot update configure test "%s" within a dry-run.' % str(target)
|
||||||
|
SConfError.__init__(self,msg)
|
||||||
|
|
||||||
|
class ConfigureCacheError(SConfError):
|
||||||
|
"""Raised when a use explicitely requested the cache feature, but the test
|
||||||
|
is run the first time."""
|
||||||
|
def __init__(self,target):
|
||||||
|
SConfError.__init__(self, '"%s" is not yet built and cache is forced.' % str(target))
|
||||||
|
|
||||||
|
# define actions for building text files
|
||||||
def _createSource( target, source, env ):
|
def _createSource( target, source, env ):
|
||||||
fd = open(str(target[0]), "w")
|
fd = open(str(target[0]), "w")
|
||||||
fd.write(env['SCONF_TEXT'])
|
fd.write(source[0].get_contents())
|
||||||
fd.close()
|
fd.close()
|
||||||
|
|
||||||
def _stringSource( target, source, env ):
|
def _stringSource( target, source, env ):
|
||||||
import string
|
return (str(target[0]) + ' <-\n |' +
|
||||||
return (str(target[0]) + ' <- \n |' +
|
string.replace( source[0].get_contents(),
|
||||||
string.replace( env['SCONF_TEXT'], "\n", "\n |" ) )
|
'\n', "\n |" ) )
|
||||||
|
|
||||||
|
# python 2.2 introduces types.BooleanType
|
||||||
BooleanTypes = [types.IntType]
|
BooleanTypes = [types.IntType]
|
||||||
if hasattr(types, 'BooleanType'): BooleanTypes.append(types.BooleanType)
|
if hasattr(types, 'BooleanType'): BooleanTypes.append(types.BooleanType)
|
||||||
|
|
||||||
|
class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
|
||||||
|
"""
|
||||||
|
Special build info for targets of configure tests. Additional members
|
||||||
|
are result (did the builder succeed last time?) and string, which
|
||||||
|
contains messages of the original build phase.
|
||||||
|
"""
|
||||||
|
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)
|
||||||
|
self.result = result
|
||||||
|
self.string = string
|
||||||
|
self.ninfo.bsig = sig
|
||||||
|
|
||||||
|
|
||||||
|
class Streamer:
|
||||||
|
"""
|
||||||
|
'Sniffer' for a file-like writable object. Similar to the unix tool tee.
|
||||||
|
"""
|
||||||
|
def __init__(self, orig):
|
||||||
|
self.orig = orig
|
||||||
|
self.s = StringIO.StringIO()
|
||||||
|
|
||||||
|
def write(self, str):
|
||||||
|
if self.orig:
|
||||||
|
self.orig.write(str)
|
||||||
|
self.s.write(str)
|
||||||
|
|
||||||
|
def writelines(self, lines):
|
||||||
|
for l in lines:
|
||||||
|
self.write(l + '\n')
|
||||||
|
|
||||||
|
def getvalue(self):
|
||||||
|
"""
|
||||||
|
Return everything written to orig since the Streamer was created.
|
||||||
|
"""
|
||||||
|
return self.s.getvalue()
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
if self.orig:
|
||||||
|
self.orig.flush()
|
||||||
|
self.s.flush()
|
||||||
|
|
||||||
|
|
||||||
|
class SConfBuildTask(SCons.Taskmaster.Task):
|
||||||
|
"""
|
||||||
|
This is almost the same as SCons.Script.BuildTask. Handles SConfErrors
|
||||||
|
correctly and knows about the current cache_mode.
|
||||||
|
"""
|
||||||
|
def display(self, message):
|
||||||
|
if sconf_global.logstream:
|
||||||
|
sconf_global.logstream.write("scons: Configure: " + message + "\n")
|
||||||
|
|
||||||
|
def display_cached_string(self, bi):
|
||||||
|
"""
|
||||||
|
Logs the original builder messages, given the SConfBuildInfo instance
|
||||||
|
bi.
|
||||||
|
"""
|
||||||
|
if not isinstance(bi, SConfBuildInfo):
|
||||||
|
SCons.Warnings.warn(SConfWarning,
|
||||||
|
"The stored build information has an unexpected class.")
|
||||||
|
else:
|
||||||
|
self.display("The original builder output was:\n" +
|
||||||
|
string.replace(" |" + str(bi.string),
|
||||||
|
"\n", "\n |"))
|
||||||
|
|
||||||
|
def failed(self):
|
||||||
|
# check, if the reason was a ConfigureDryRunError or a
|
||||||
|
# ConfigureCacheError and if yes, reraise the exception
|
||||||
|
exc_type = self.exc_info()[0]
|
||||||
|
if issubclass(exc_type, SConfError):
|
||||||
|
raise
|
||||||
|
elif issubclass(exc_type, SCons.Errors.BuildError):
|
||||||
|
# we ignore Build Errors (occurs, when a test doesn't pass)
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.display('Caught exception while building "%s":\n' %
|
||||||
|
self.targets[0])
|
||||||
|
try:
|
||||||
|
excepthook = sys.excepthook
|
||||||
|
except AttributeError:
|
||||||
|
# Earlier versions of Python don't have sys.excepthook...
|
||||||
|
def excepthook(type, value, tb):
|
||||||
|
traceback.print_tb(tb)
|
||||||
|
print type, value
|
||||||
|
apply(excepthook, self.exc_info())
|
||||||
|
return SCons.Taskmaster.Task.failed(self)
|
||||||
|
|
||||||
|
def collect_node_states(self):
|
||||||
|
# returns (is_up_to_date, cached_error, cachable)
|
||||||
|
# where is_up_to_date is 1, if the node(s) are up_to_date
|
||||||
|
# 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
|
||||||
|
for t in self.targets:
|
||||||
|
bi = t.get_stored_info()
|
||||||
|
if isinstance(bi, SConfBuildInfo):
|
||||||
|
if cache_mode == CACHE:
|
||||||
|
t.set_state(SCons.Node.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)
|
||||||
|
cached_error = cached_error or bi.result
|
||||||
|
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)
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
sconf = sconf_global
|
||||||
|
|
||||||
|
is_up_to_date, cached_error, cachable = self.collect_node_states()
|
||||||
|
|
||||||
|
if cache_mode == CACHE and not cachable:
|
||||||
|
raise ConfigureCacheError(self.targets[0])
|
||||||
|
elif cache_mode == FORCE:
|
||||||
|
is_up_to_date = 0
|
||||||
|
|
||||||
|
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())
|
||||||
|
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())
|
||||||
|
elif dryrun:
|
||||||
|
raise ConfigureDryRunError(self.targets[0])
|
||||||
|
else:
|
||||||
|
# note stdout and stderr are the same here
|
||||||
|
s = sys.stdout = sys.stderr = Streamer(sys.stdout)
|
||||||
|
try:
|
||||||
|
env = self.targets[0].get_build_env()
|
||||||
|
env['PSTDOUT'] = env['PSTDERR'] = s
|
||||||
|
try:
|
||||||
|
sconf.cached = 0
|
||||||
|
self.targets[0].build()
|
||||||
|
finally:
|
||||||
|
sys.stdout = sys.stderr = env['PSTDOUT'] = \
|
||||||
|
env['PSTDERR'] = sconf.logstream
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except SystemExit:
|
||||||
|
exc_value = sys.exc_info()[1]
|
||||||
|
raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
|
||||||
|
except:
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
|
||||||
class SConf:
|
class SConf:
|
||||||
"""This is simply a class to represent a configure context. After
|
"""This is simply a class to represent a configure context. After
|
||||||
creating a SConf object, you can call any tests. After finished with your
|
creating a SConf object, you can call any tests. After finished with your
|
||||||
|
@ -86,30 +332,29 @@ class SConf:
|
||||||
SConf run, we need to explicitely cache this error.
|
SConf run, we need to explicitely cache this error.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, env, custom_tests = {}, conf_dir='#/.sconf_temp',
|
def __init__(self, env, custom_tests = {}, conf_dir='$CONFIGUREDIR',
|
||||||
log_file='#/config.log'):
|
log_file='$CONFIGURELOG', config_h = None, _depth = 0):
|
||||||
"""Constructor. Pass additional tests in the custom_tests-dictinary,
|
"""Constructor. Pass additional tests in the custom_tests-dictinary,
|
||||||
e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest
|
e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest
|
||||||
defines a custom test.
|
defines a custom test.
|
||||||
Note also the conf_dir and log_file arguments (you may want to
|
Note also the conf_dir and log_file arguments (you may want to
|
||||||
build tests in the BuildDir, not in the SourceDir)
|
build tests in the BuildDir, not in the SourceDir)
|
||||||
"""
|
"""
|
||||||
import SCons.Script.SConscript
|
|
||||||
if not SCons.Script.SConscript.sconscript_reading:
|
|
||||||
raise SCons.Errors.UserError, "Calling Configure from Builders is not supported."
|
|
||||||
global SConfFS
|
global SConfFS
|
||||||
if not SConfFS:
|
if not SConfFS:
|
||||||
SConfFS = SCons.Node.FS.FS(SCons.Node.FS.default_fs.pathTop)
|
SConfFS = SCons.Node.FS.default_fs or \
|
||||||
if len(_activeSConfObjects.keys()) > 0:
|
SCons.Node.FS.FS(env.fs.pathTop)
|
||||||
|
if not sconf_global is None:
|
||||||
raise (SCons.Errors.UserError,
|
raise (SCons.Errors.UserError,
|
||||||
"Only one SConf object may be active at one time")
|
"Only one SConf object may be active at one time")
|
||||||
self.env = env
|
self.env = env
|
||||||
if log_file != None:
|
if log_file != None:
|
||||||
self.logfile = SConfFS.File(log_file)
|
log_file = SConfFS.File(env.subst(log_file))
|
||||||
else:
|
self.logfile = log_file
|
||||||
self.logfile = None
|
|
||||||
self.logstream = None
|
self.logstream = None
|
||||||
self.lastTarget = None
|
self.lastTarget = None
|
||||||
|
self.depth = _depth
|
||||||
|
self.cached = 0 # will be set, if all test results are cached
|
||||||
|
|
||||||
# add default tests
|
# add default tests
|
||||||
default_tests = {
|
default_tests = {
|
||||||
|
@ -123,83 +368,24 @@ class SConf:
|
||||||
}
|
}
|
||||||
self.AddTests(default_tests)
|
self.AddTests(default_tests)
|
||||||
self.AddTests(custom_tests)
|
self.AddTests(custom_tests)
|
||||||
self.confdir = SConfFS.Dir(conf_dir)
|
self.confdir = SConfFS.Dir(env.subst(conf_dir))
|
||||||
self.calc = None
|
self.calc = None
|
||||||
self.cache = {}
|
if not config_h is None:
|
||||||
|
config_h = SConfFS.File(config_h)
|
||||||
|
self.config_h = config_h
|
||||||
self._startup()
|
self._startup()
|
||||||
|
|
||||||
def Finish(self):
|
def Finish(self):
|
||||||
"""Call this method after finished with your tests:
|
"""Call this method after finished with your tests:
|
||||||
env = sconf.Finish()"""
|
env = sconf.Finish()"""
|
||||||
global _lastSConfObj
|
|
||||||
_lastSConfObj = None
|
|
||||||
self._shutdown()
|
self._shutdown()
|
||||||
return self.env
|
return self.env
|
||||||
|
|
||||||
def _setCache(self, nodes, already_done = []):
|
|
||||||
# Set up actions used for caching errors
|
|
||||||
# Caching positive tests should not be necessary, cause
|
|
||||||
# the build system knows, if test objects/programs/outputs
|
|
||||||
# are up to date.
|
|
||||||
for n in nodes:
|
|
||||||
# The 'n in already_done' expression is not really efficient.
|
|
||||||
# We may do something more sophisticated in the future :-),
|
|
||||||
# but there should not be that many dependencies in configure
|
|
||||||
# tests
|
|
||||||
if (n.has_builder() and
|
|
||||||
not n in already_done):
|
|
||||||
n.add_pre_action(SCons.Action.Action(self._preCache,
|
|
||||||
self._stringCache))
|
|
||||||
n.add_post_action(SCons.Action.Action(self._postCache,
|
|
||||||
self._stringCache))
|
|
||||||
already_done.append( n )
|
|
||||||
self._setCache(n.children())
|
|
||||||
|
|
||||||
# Calling children() has set up the implicit cache (and
|
|
||||||
# other state), but we're not really building things yet,
|
|
||||||
# so generated files won't have been generated. Clear the
|
|
||||||
# state so we will, in fact, build everything that's necessary
|
|
||||||
# when we do the build.
|
|
||||||
#
|
|
||||||
# XXX - it would be good to find a better way to do this,
|
|
||||||
# maybe by doing something with the actions in the actual
|
|
||||||
# Taskmaster...?
|
|
||||||
n.clear()
|
|
||||||
|
|
||||||
def BuildNodes(self, nodes):
|
def BuildNodes(self, nodes):
|
||||||
"""
|
"""
|
||||||
Tries to build the given nodes immediately. Returns 1 on success,
|
Tries to build the given nodes immediately. Returns 1 on success,
|
||||||
0 on error.
|
0 on error.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global SCons
|
|
||||||
import SCons.Script # really ugly, but we need BuildTask :-(
|
|
||||||
# Is it better to provide a seperate Task for SConf builds ?
|
|
||||||
class SConfBuildTask(SCons.Script.BuildTask):
|
|
||||||
"""Errors in SConf builds are not fatal, so we override
|
|
||||||
the do_failed method"""
|
|
||||||
def do_failed(self, status=2):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class SConfDryRunTask(SConfBuildTask):
|
|
||||||
"""Raise ConfiugreDryRunErrors whenever a target is to
|
|
||||||
be built. Pass these Errors to the main script."""
|
|
||||||
def execute(self):
|
|
||||||
target = self.targets[0]
|
|
||||||
if (target.get_state() != SCons.Node.up_to_date and
|
|
||||||
target.has_builder() and
|
|
||||||
not hasattr(target.builder, 'status')):
|
|
||||||
|
|
||||||
raise SCons.Errors.ConfigureDryRunError(target)
|
|
||||||
|
|
||||||
def failed(self):
|
|
||||||
exc_type, exc_value = self.exc_info()[:2]
|
|
||||||
if exc_type == SCons.Errors.ConfigureDryRunError:
|
|
||||||
raise exc_type, exc_value
|
|
||||||
# Should be SConfBuildTask.failed(), really,
|
|
||||||
# but that causes name errors in Python 1.5.2.
|
|
||||||
SCons.Script.BuildTask.failed(self)
|
|
||||||
|
|
||||||
if self.logstream != None:
|
if self.logstream != None:
|
||||||
# override stdout / stderr to write in log file
|
# override stdout / stderr to write in log file
|
||||||
oldStdout = sys.stdout
|
oldStdout = sys.stdout
|
||||||
|
@ -212,26 +398,16 @@ class SConf:
|
||||||
old_os_dir = os.getcwd()
|
old_os_dir = os.getcwd()
|
||||||
SConfFS.chdir(SConfFS.Top, change_os_dir=1)
|
SConfFS.chdir(SConfFS.Top, change_os_dir=1)
|
||||||
|
|
||||||
self._setCache( nodes )
|
|
||||||
ret = 1
|
ret = 1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# ToDo: use user options for calc
|
# ToDo: use user options for calc
|
||||||
self.calc = SCons.Sig.Calculator(max_drift=0)
|
save_max_drift = SConfFS.get_max_drift()
|
||||||
if dryrun:
|
SConfFS.set_max_drift(0)
|
||||||
buildTask = SConfDryRunTask
|
tm = SCons.Taskmaster.Taskmaster(nodes, SConfBuildTask)
|
||||||
else:
|
|
||||||
buildTask = SConfBuildTask
|
|
||||||
tm = SCons.Taskmaster.Taskmaster( nodes, buildTask )
|
|
||||||
# we don't want to build tests in parallel
|
# we don't want to build tests in parallel
|
||||||
jobs = SCons.Job.Jobs(1, tm )
|
jobs = SCons.Job.Jobs(1, tm )
|
||||||
try:
|
jobs.run()
|
||||||
jobs.run()
|
|
||||||
except SCons.Errors.BuildError, e:
|
|
||||||
sys.stderr.write("scons: *** [%s] %s\n" % (e.node, e.errstr))
|
|
||||||
if e.errstr == 'Exception':
|
|
||||||
traceback.print_exception(e.args[0], e.args[1], e.args[2])
|
|
||||||
|
|
||||||
for n in nodes:
|
for n in nodes:
|
||||||
state = n.get_state()
|
state = n.get_state()
|
||||||
if (state != SCons.Node.executed and
|
if (state != SCons.Node.executed and
|
||||||
|
@ -239,6 +415,7 @@ class SConf:
|
||||||
# the node could not be built. we return 0 in this case
|
# the node could not be built. we return 0 in this case
|
||||||
ret = 0
|
ret = 0
|
||||||
finally:
|
finally:
|
||||||
|
SConfFS.set_max_drift(save_max_drift)
|
||||||
os.chdir(old_os_dir)
|
os.chdir(old_os_dir)
|
||||||
SConfFS.chdir(old_fs_dir, change_os_dir=0)
|
SConfFS.chdir(old_fs_dir, change_os_dir=0)
|
||||||
if self.logstream != None:
|
if self.logstream != None:
|
||||||
|
@ -247,6 +424,18 @@ class SConf:
|
||||||
sys.stderr = oldStderr
|
sys.stderr = oldStderr
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def pspawn_wrapper(self, sh, escape, cmd, args, env):
|
||||||
|
"""Wrapper function for handling piped spawns.
|
||||||
|
|
||||||
|
This looks to the calling interface (in Action.py) like a "normal"
|
||||||
|
spawn, but associates the call with the PSPAWN variable from
|
||||||
|
the construction environment and with the streams to which we
|
||||||
|
want the output logged. This gets slid into the construction
|
||||||
|
environment as the SPAWN variable so Action.py doesn't have to
|
||||||
|
know or care whether it's spawning a piped command or not.
|
||||||
|
"""
|
||||||
|
return self.pspawn(sh, escape, cmd, args, env, self.logstream, self.logstream)
|
||||||
|
|
||||||
|
|
||||||
def TryBuild(self, builder, text = None, extension = ""):
|
def TryBuild(self, builder, text = None, extension = ""):
|
||||||
"""Low level TryBuild implementation. Normally you don't need to
|
"""Low level TryBuild implementation. Normally you don't need to
|
||||||
|
@ -254,43 +443,55 @@ class SConf:
|
||||||
"""
|
"""
|
||||||
global _ac_build_counter
|
global _ac_build_counter
|
||||||
|
|
||||||
|
# Make sure we have a PSPAWN value, and save the current
|
||||||
|
# SPAWN value.
|
||||||
|
try:
|
||||||
|
self.pspawn = self.env['PSPAWN']
|
||||||
|
except KeyError:
|
||||||
|
raise SCons.Errors.UserError('Missing PSPAWN construction variable.')
|
||||||
|
try:
|
||||||
|
save_spawn = self.env['SPAWN']
|
||||||
|
except KeyError:
|
||||||
|
raise SCons.Errors.UserError('Missing SPAWN construction variable.')
|
||||||
|
|
||||||
nodesToBeBuilt = []
|
nodesToBeBuilt = []
|
||||||
|
|
||||||
f = "conftest_" + str(_ac_build_counter)
|
f = "conftest_" + str(_ac_build_counter)
|
||||||
pref = self.env.subst( builder.builder.prefix )
|
pref = self.env.subst( builder.builder.prefix )
|
||||||
suff = self.env.subst( builder.builder.suffix )
|
suff = self.env.subst( builder.builder.suffix )
|
||||||
target = self.confdir.File(pref + f + suff)
|
target = self.confdir.File(pref + f + suff)
|
||||||
self.env['SCONF_TEXT'] = text
|
|
||||||
self.env['PIPE_BUILD'] = 1
|
|
||||||
self.env['PSTDOUT'] = self.logstream
|
|
||||||
self.env['PSTDERR'] = self.logstream
|
|
||||||
if text != None:
|
|
||||||
source = self.confdir.File(f + extension)
|
|
||||||
sourceNode = self.env.SConfSourceBuilder(target=source,
|
|
||||||
source=None)
|
|
||||||
nodesToBeBuilt.extend(sourceNode)
|
|
||||||
else:
|
|
||||||
source = None
|
|
||||||
|
|
||||||
nodes = builder(target = target, source = source)
|
try:
|
||||||
if not SCons.Util.is_List(nodes):
|
# Slide our wrapper into the construction environment as
|
||||||
nodes = [nodes]
|
# the SPAWN function.
|
||||||
nodesToBeBuilt.extend(nodes)
|
self.env['SPAWN'] = self.pspawn_wrapper
|
||||||
ret = self.BuildNodes(nodesToBeBuilt)
|
sourcetext = self.env.Value(text)
|
||||||
|
|
||||||
# clean up environment
|
if text != None:
|
||||||
del self.env['PIPE_BUILD']
|
textFile = self.confdir.File(f + extension)
|
||||||
del self.env['PSTDOUT']
|
textFileNode = self.env.SConfSourceBuilder(target=textFile,
|
||||||
del self.env['PSTDERR']
|
source=sourcetext)
|
||||||
del self.env['SCONF_TEXT']
|
nodesToBeBuilt.extend(textFileNode)
|
||||||
|
source = textFileNode
|
||||||
|
else:
|
||||||
|
source = None
|
||||||
|
|
||||||
|
nodes = builder(target = target, source = source)
|
||||||
|
if not SCons.Util.is_List(nodes):
|
||||||
|
nodes = [nodes]
|
||||||
|
nodesToBeBuilt.extend(nodes)
|
||||||
|
result = self.BuildNodes(nodesToBeBuilt)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
self.env['SPAWN'] = save_spawn
|
||||||
|
|
||||||
_ac_build_counter = _ac_build_counter + 1
|
_ac_build_counter = _ac_build_counter + 1
|
||||||
if ret:
|
if result:
|
||||||
self.lastTarget = nodes[0]
|
self.lastTarget = nodes[0]
|
||||||
else:
|
else:
|
||||||
self.lastTarget = None
|
self.lastTarget = None
|
||||||
|
|
||||||
return ret
|
return result
|
||||||
|
|
||||||
def TryAction(self, action, text = None, extension = ""):
|
def TryAction(self, action, text = None, extension = ""):
|
||||||
"""Tries to execute the given action with optional source file
|
"""Tries to execute the given action with optional source file
|
||||||
|
@ -352,6 +553,8 @@ class SConf:
|
||||||
"Test called after sconf.Finish()")
|
"Test called after sconf.Finish()")
|
||||||
context = CheckContext(self.sconf)
|
context = CheckContext(self.sconf)
|
||||||
ret = apply(self.test, (context,) + args, kw)
|
ret = apply(self.test, (context,) + args, kw)
|
||||||
|
if not self.sconf.config_h is None:
|
||||||
|
self.sconf.config_h_text = self.sconf.config_h_text + context.config_h
|
||||||
context.Result("error: no result")
|
context.Result("error: no result")
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -367,75 +570,11 @@ class SConf:
|
||||||
for name in tests.keys():
|
for name in tests.keys():
|
||||||
self.AddTest(name, tests[name])
|
self.AddTest(name, tests[name])
|
||||||
|
|
||||||
def _preCache(self, target, source, env):
|
|
||||||
# Action before target is actually built
|
|
||||||
#
|
|
||||||
# We record errors in the cache. Only non-exisiting targets may
|
|
||||||
# have recorded errors
|
|
||||||
needs_rebuild = target[0].exists()
|
|
||||||
buildSig = target[0].calc_signature(self.calc)
|
|
||||||
for node in source:
|
|
||||||
if node.get_state() != SCons.Node.up_to_date:
|
|
||||||
# if any of the sources has changed, we cannot use our cache
|
|
||||||
needs_rebuild = 1
|
|
||||||
tname = str(target[0])
|
|
||||||
if not self.cache.has_key( tname ):
|
|
||||||
# We have no recorded error, so we try to build the target
|
|
||||||
needs_rebuild = 1
|
|
||||||
else:
|
|
||||||
lastBuildSig = self.cache[tname]['builder']
|
|
||||||
if lastBuildSig != buildSig:
|
|
||||||
needs_rebuild = 1
|
|
||||||
if not needs_rebuild:
|
|
||||||
# When we are here, we can savely pass the recorded error
|
|
||||||
print ('(cached): Building "%s" failed in a previous run.' %
|
|
||||||
target[0])
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
# Otherwise, we try to record an error
|
|
||||||
self.cache[tname] = {
|
|
||||||
'builder' : buildSig
|
|
||||||
}
|
|
||||||
|
|
||||||
def _postCache(self, target, source, env):
|
|
||||||
# Action after target is successfully built
|
|
||||||
#
|
|
||||||
# No error during build -> remove the recorded error
|
|
||||||
del self.cache[str(target[0])]
|
|
||||||
|
|
||||||
def _stringCache(self, target, source, env):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _loadCache(self):
|
|
||||||
# try to load build-error cache
|
|
||||||
try:
|
|
||||||
cacheDesc = cPickle.load(open(str(self.confdir.File(".cache"))))
|
|
||||||
if cacheDesc['scons_version'] != SCons.__version__:
|
|
||||||
raise Exception, "version mismatch"
|
|
||||||
self.cache = cacheDesc['data']
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
self.cache = {}
|
|
||||||
|
|
||||||
def _dumpCache(self):
|
|
||||||
if dryrun:
|
|
||||||
return
|
|
||||||
# try to dump build-error cache
|
|
||||||
try:
|
|
||||||
cacheDesc = {'scons_version' : SCons.__version__,
|
|
||||||
'data' : self.cache }
|
|
||||||
cPickle.dump(cacheDesc, open(str(self.confdir.File(".cache")),"w"))
|
|
||||||
except Exception, e:
|
|
||||||
# this is most likely not only an IO error, but an error
|
|
||||||
# inside SConf ...
|
|
||||||
SCons.Warnings.warn( SConfWarning, "Couldn't dump SConf cache" )
|
|
||||||
|
|
||||||
def _createDir( self, node ):
|
def _createDir( self, node ):
|
||||||
dirName = str(node)
|
dirName = str(node)
|
||||||
if dryrun:
|
if dryrun:
|
||||||
if not os.path.isdir( dirName ):
|
if not os.path.isdir( dirName ):
|
||||||
raise SCons.Errors.ConfigureDryRunError(dirName)
|
raise ConfigureDryRunError(dirName)
|
||||||
else:
|
else:
|
||||||
if not os.path.isdir( dirName ):
|
if not os.path.isdir( dirName ):
|
||||||
os.makedirs( dirName )
|
os.makedirs( dirName )
|
||||||
|
@ -445,8 +584,8 @@ class SConf:
|
||||||
"""Private method. Set up logstream, and set the environment
|
"""Private method. Set up logstream, and set the environment
|
||||||
variables necessary for a piped build
|
variables necessary for a piped build
|
||||||
"""
|
"""
|
||||||
global _ac_config_counter
|
global _ac_config_logs
|
||||||
global _activeSConfObjects
|
global sconf_global
|
||||||
global SConfFS
|
global SConfFS
|
||||||
|
|
||||||
self.lastEnvFs = self.env.fs
|
self.lastEnvFs = self.env.fs
|
||||||
|
@ -457,41 +596,44 @@ class SConf:
|
||||||
if self.logfile != None and not dryrun:
|
if self.logfile != None and not dryrun:
|
||||||
# truncate logfile, if SConf.Configure is called for the first time
|
# truncate logfile, if SConf.Configure is called for the first time
|
||||||
# in a build
|
# in a build
|
||||||
if _ac_config_counter == 0:
|
if _ac_config_logs.has_key(self.logfile):
|
||||||
log_mode = "w"
|
|
||||||
else:
|
|
||||||
log_mode = "a"
|
log_mode = "a"
|
||||||
self.logstream = open(str(self.logfile), log_mode)
|
else:
|
||||||
|
_ac_config_logs[self.logfile] = None
|
||||||
|
log_mode = "w"
|
||||||
|
fp = open(str(self.logfile), log_mode)
|
||||||
|
self.logstream = SCons.Util.Unbuffered(fp)
|
||||||
# logfile may stay in a build directory, so we tell
|
# logfile may stay in a build directory, so we tell
|
||||||
# the build system not to override it with a eventually
|
# the build system not to override it with a eventually
|
||||||
# existing file with the same name in the source directory
|
# existing file with the same name in the source directory
|
||||||
self.logfile.dir.add_ignore( [self.logfile] )
|
self.logfile.dir.add_ignore( [self.logfile] )
|
||||||
|
|
||||||
tb = traceback.extract_stack()[-3]
|
tb = traceback.extract_stack()[-3-self.depth]
|
||||||
|
old_fs_dir = SConfFS.getcwd()
|
||||||
self.logstream.write( '\nfile %s,line %d:\n\tConfigure( confdir = %s )\n\n' %
|
SConfFS.chdir(SConfFS.Top, change_os_dir=0)
|
||||||
(tb[0], tb[1], str(self.confdir)) )
|
self.logstream.write('file %s,line %d:\n\tConfigure(confdir = %s)\n' %
|
||||||
|
(tb[0], tb[1], str(self.confdir)) )
|
||||||
|
SConfFS.chdir(old_fs_dir)
|
||||||
else:
|
else:
|
||||||
self.logstream = None
|
self.logstream = None
|
||||||
# we use a special builder to create source files from TEXT
|
# we use a special builder to create source files from TEXT
|
||||||
action = SCons.Action.Action(_createSource,
|
action = SCons.Action.Action(_createSource,
|
||||||
_stringSource,
|
_stringSource)
|
||||||
varlist=['SCONF_TEXT'])
|
|
||||||
sconfSrcBld = SCons.Builder.Builder(action=action)
|
sconfSrcBld = SCons.Builder.Builder(action=action)
|
||||||
self.env.Append( BUILDERS={'SConfSourceBuilder':sconfSrcBld} )
|
self.env.Append( BUILDERS={'SConfSourceBuilder':sconfSrcBld} )
|
||||||
|
self.config_h_text = _ac_config_hs.get(self.config_h, "")
|
||||||
self.active = 1
|
self.active = 1
|
||||||
# only one SConf instance should be active at a time ...
|
# only one SConf instance should be active at a time ...
|
||||||
_activeSConfObjects[self] = None
|
sconf_global = self
|
||||||
_ac_config_counter = _ac_config_counter + 1
|
|
||||||
self._loadCache()
|
|
||||||
|
|
||||||
def _shutdown(self):
|
def _shutdown(self):
|
||||||
"""Private method. Reset to non-piped spawn"""
|
"""Private method. Reset to non-piped spawn"""
|
||||||
global _activeSConfObjets
|
global sconf_global, _ac_config_hs
|
||||||
|
|
||||||
if not self.active:
|
if not self.active:
|
||||||
raise SCons.Errors.UserError, "Finish may be called only once!"
|
raise SCons.Errors.UserError, "Finish may be called only once!"
|
||||||
if self.logstream != None:
|
if self.logstream != None and not dryrun:
|
||||||
|
self.logstream.write("\n")
|
||||||
self.logstream.close()
|
self.logstream.close()
|
||||||
self.logstream = None
|
self.logstream = None
|
||||||
# remove the SConfSourceBuilder from the environment
|
# remove the SConfSourceBuilder from the environment
|
||||||
|
@ -499,8 +641,9 @@ class SConf:
|
||||||
del blds['SConfSourceBuilder']
|
del blds['SConfSourceBuilder']
|
||||||
self.env.Replace( BUILDERS=blds )
|
self.env.Replace( BUILDERS=blds )
|
||||||
self.active = 0
|
self.active = 0
|
||||||
del _activeSConfObjects[self]
|
sconf_global = None
|
||||||
self._dumpCache()
|
if not self.config_h is None:
|
||||||
|
_ac_config_hs[self.config_h] = self.config_h_text
|
||||||
self.env.fs = self.lastEnvFs
|
self.env.fs = self.lastEnvFs
|
||||||
|
|
||||||
class CheckContext:
|
class CheckContext:
|
||||||
|
@ -524,22 +667,27 @@ class CheckContext:
|
||||||
def __init__(self, sconf):
|
def __init__(self, sconf):
|
||||||
"""Constructor. Pass the corresponding SConf instance."""
|
"""Constructor. Pass the corresponding SConf instance."""
|
||||||
self.sconf = sconf
|
self.sconf = sconf
|
||||||
self.cached = 0
|
|
||||||
self.did_show_result = 0
|
self.did_show_result = 0
|
||||||
|
|
||||||
# for Conftest.py:
|
# for Conftest.py:
|
||||||
self.vardict = {}
|
self.vardict = {}
|
||||||
self.havedict = {}
|
self.havedict = {}
|
||||||
self.headerfilename = None # XXX may cause trouble!
|
self.headerfilename = None
|
||||||
|
self.config_h = "" # config_h text will be stored here
|
||||||
|
# we don't regenerate the config.h file after each test. That means,
|
||||||
|
# that tests won't be able to include the config.h file, and so
|
||||||
|
# they can't do an #ifdef HAVE_XXX_H. This shouldn't be a major
|
||||||
|
# issue, though. If it turns out, that we need to include config.h
|
||||||
|
# in tests, we must ensure, that the dependencies are worked out
|
||||||
|
# correctly. Note that we can't use Conftest.py's support for config.h,
|
||||||
|
# cause we will need to specify a builder for the config.h file ...
|
||||||
|
|
||||||
def Message(self, text):
|
def Message(self, text):
|
||||||
"""Inform about what we are doing right now, e.g.
|
"""Inform about what we are doing right now, e.g.
|
||||||
'Checking for SOMETHING ... '
|
'Checking for SOMETHING ... '
|
||||||
"""
|
"""
|
||||||
# write to config.log
|
self.Display(text)
|
||||||
if self.sconf.logstream != None:
|
self.sconf.cached = 1
|
||||||
self.sconf.logstream.write(text + '\n')
|
|
||||||
sys.stdout.write(text)
|
|
||||||
self.did_show_result = 0
|
self.did_show_result = 0
|
||||||
|
|
||||||
def Result(self, res):
|
def Result(self, res):
|
||||||
|
@ -550,25 +698,19 @@ class CheckContext:
|
||||||
"""
|
"""
|
||||||
if type(res) in BooleanTypes:
|
if type(res) in BooleanTypes:
|
||||||
if res:
|
if res:
|
||||||
text = "ok"
|
text = "yes"
|
||||||
else:
|
else:
|
||||||
text = "failed"
|
text = "no"
|
||||||
elif type(res) == types.StringType:
|
elif type(res) == types.StringType:
|
||||||
text = res
|
text = res
|
||||||
else:
|
else:
|
||||||
raise TypeError, "Expected string, int or bool, got " + str(type(res))
|
raise TypeError, "Expected string, int or bool, got " + str(type(res))
|
||||||
|
|
||||||
if self.did_show_result == 0:
|
if self.did_show_result == 0:
|
||||||
if self.cached:
|
|
||||||
text = text + " (cached)"
|
|
||||||
|
|
||||||
# Didn't show result yet, do it now.
|
# Didn't show result yet, do it now.
|
||||||
if self.sconf.logstream != None:
|
self.Display(text + "\n")
|
||||||
self.sconf.logstream.write("Result: " + text + "\n\n")
|
|
||||||
sys.stdout.write(text + "\n")
|
|
||||||
self.did_show_result = 1
|
self.did_show_result = 1
|
||||||
|
|
||||||
|
|
||||||
def TryBuild(self, *args, **kw):
|
def TryBuild(self, *args, **kw):
|
||||||
return apply(self.sconf.TryBuild, args, kw)
|
return apply(self.sconf.TryBuild, args, kw)
|
||||||
|
|
||||||
|
@ -595,32 +737,14 @@ class CheckContext:
|
||||||
#### Stuff used by Conftest.py (look there for explanations).
|
#### Stuff used by Conftest.py (look there for explanations).
|
||||||
|
|
||||||
def BuildProg(self, text, ext):
|
def BuildProg(self, text, ext):
|
||||||
|
self.sconf.cached = 1
|
||||||
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
|
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
|
||||||
res = self.TryBuild(self.env.Program, text, ext)
|
return not self.TryBuild(self.env.Program, text, ext)
|
||||||
if type(res) in BooleanTypes:
|
|
||||||
if res:
|
|
||||||
ret = ""
|
|
||||||
else:
|
|
||||||
ret = "failed to build test program"
|
|
||||||
elif type(res) == types.StringType:
|
|
||||||
ret = res
|
|
||||||
else:
|
|
||||||
raise TypeError, "Expected string or int"
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def CompileProg(self, text, ext):
|
def CompileProg(self, text, ext):
|
||||||
|
self.sconf.cached = 1
|
||||||
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
|
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
|
||||||
res = self.TryBuild(self.env.Object, text, ext)
|
return not self.TryBuild(self.env.Object, text, ext)
|
||||||
if type(res) in BooleanTypes:
|
|
||||||
if res:
|
|
||||||
ret = ""
|
|
||||||
else:
|
|
||||||
ret = "failed to compile test program"
|
|
||||||
elif type(res) == types.StringType:
|
|
||||||
ret = res
|
|
||||||
else:
|
|
||||||
raise TypeError, "Expected string or int"
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def AppendLIBS(self, lib_name_list):
|
def AppendLIBS(self, lib_name_list):
|
||||||
oldLIBS = self.env.get( 'LIBS', [] )
|
oldLIBS = self.env.get( 'LIBS', [] )
|
||||||
|
@ -633,8 +757,14 @@ class CheckContext:
|
||||||
return oldLIBS
|
return oldLIBS
|
||||||
|
|
||||||
def Display(self, msg):
|
def Display(self, msg):
|
||||||
sys.stdout.write(msg)
|
if self.sconf.cached:
|
||||||
self.Log(msg)
|
# We assume that Display is called twice for each test here
|
||||||
|
# once for the Checking for ... message and once for the result.
|
||||||
|
# The self.sconf.cached flag can only be set between those calls
|
||||||
|
msg = "(cached) " + msg
|
||||||
|
self.sconf.cached = 0
|
||||||
|
progress_display(msg, append_newline=0)
|
||||||
|
self.Log("scons: Configure: " + msg + "\n")
|
||||||
|
|
||||||
def Log(self, msg):
|
def Log(self, msg):
|
||||||
if self.sconf.logstream != None:
|
if self.sconf.logstream != None:
|
||||||
|
@ -643,40 +773,44 @@ class CheckContext:
|
||||||
#### End of stuff used by Conftest.py.
|
#### End of stuff used by Conftest.py.
|
||||||
|
|
||||||
|
|
||||||
def CheckFunc(context, function_name, language = None):
|
def CheckFunc(context, function_name, header = None, language = None):
|
||||||
res = SCons.Conftest.CheckFunc(context, function_name, language = language)
|
res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language)
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
if not res:
|
return not res
|
||||||
return 1 # Ok
|
|
||||||
return 0 # Failed
|
|
||||||
|
|
||||||
|
|
||||||
def CheckType(context, type_name, includes = "", language = None):
|
def CheckType(context, type_name, includes = "", language = None):
|
||||||
res = SCons.Conftest.CheckType(context, type_name,
|
res = SCons.Conftest.CheckType(context, type_name,
|
||||||
header = includes, language = language)
|
header = includes, language = language)
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
if not res:
|
return not res
|
||||||
return 1 # Ok
|
|
||||||
return 0 # Failed
|
|
||||||
|
|
||||||
|
def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'):
|
||||||
|
# used by CheckHeader and CheckLibWithHeader to produce C - #include
|
||||||
|
# statements from the specified header (list)
|
||||||
|
if not SCons.Util.is_List(headers):
|
||||||
|
headers = [headers]
|
||||||
|
l = []
|
||||||
|
if leaveLast:
|
||||||
|
lastHeader = headers[-1]
|
||||||
|
headers = headers[:-1]
|
||||||
|
else:
|
||||||
|
lastHeader = None
|
||||||
|
for s in headers:
|
||||||
|
l.append("#include %s%s%s\n"
|
||||||
|
% (include_quotes[0], s, include_quotes[1]))
|
||||||
|
return string.join(l, ''), lastHeader
|
||||||
|
|
||||||
def CheckHeader(context, header, include_quotes = '<>', language = None):
|
def CheckHeader(context, header, include_quotes = '<>', language = None):
|
||||||
"""
|
"""
|
||||||
A test for a C or C++ header file.
|
A test for a C or C++ header file.
|
||||||
"""
|
"""
|
||||||
if not SCons.Util.is_List(header):
|
prog_prefix, hdr_to_check = \
|
||||||
header = [header]
|
createIncludesFromHeaders(header, 1, include_quotes)
|
||||||
l = []
|
res = SCons.Conftest.CheckHeader(context, hdr_to_check, prog_prefix,
|
||||||
for s in header[:-1]:
|
|
||||||
l.append("#include %s%s%s\n" % (include_quotes[0], s, include_quotes[1]))
|
|
||||||
res = SCons.Conftest.CheckHeader(context, header[-1], string.join(l, ''),
|
|
||||||
language = language,
|
language = language,
|
||||||
include_quotes = include_quotes)
|
include_quotes = include_quotes)
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
if not res:
|
return not res
|
||||||
return 1 # Ok
|
|
||||||
return 0 # Failed
|
|
||||||
|
|
||||||
|
|
||||||
# Bram: Make this function obsolete? CheckHeader() is more generic.
|
# Bram: Make this function obsolete? CheckHeader() is more generic.
|
||||||
|
|
||||||
|
@ -696,8 +830,8 @@ def CheckCXXHeader(context, header, include_quotes = '""'):
|
||||||
return CheckHeader(context, header, include_quotes, language = "C++")
|
return CheckHeader(context, header, include_quotes, language = "C++")
|
||||||
|
|
||||||
|
|
||||||
def CheckLib(context, library = None, symbol = "main", autoadd = 1,
|
def CheckLib(context, library = None, symbol = "main",
|
||||||
header = None, language = None):
|
header = None, language = None, autoadd = 1):
|
||||||
"""
|
"""
|
||||||
A test for a library. See also CheckLibWithHeader.
|
A test for a library. See also CheckLibWithHeader.
|
||||||
Note that library may also be None to test whether the given symbol
|
Note that library may also be None to test whether the given symbol
|
||||||
|
@ -714,43 +848,30 @@ def CheckLib(context, library = None, symbol = "main", autoadd = 1,
|
||||||
res = SCons.Conftest.CheckLib(context, library, symbol, header = header,
|
res = SCons.Conftest.CheckLib(context, library, symbol, header = header,
|
||||||
language = language, autoadd = autoadd)
|
language = language, autoadd = autoadd)
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
if not res:
|
return not res
|
||||||
return 1 # Ok
|
|
||||||
return 0 # Failed
|
|
||||||
|
|
||||||
|
|
||||||
# XXX
|
# XXX
|
||||||
# Bram: Can only include one header and can't use #ifdef HAVE_HEADER_H.
|
# Bram: Can only include one header and can't use #ifdef HAVE_HEADER_H.
|
||||||
|
|
||||||
def CheckLibWithHeader(context, libs, header, language,
|
def CheckLibWithHeader(context, libs, header, language,
|
||||||
call = "main();", autoadd = 1):
|
call = None, autoadd = 1):
|
||||||
# ToDo: accept path for library. Support system header files.
|
# ToDo: accept path for library. Support system header files.
|
||||||
"""
|
"""
|
||||||
Another (more sophisticated) test for a library.
|
Another (more sophisticated) test for a library.
|
||||||
Checks, if library and header is available for language (maybe 'C'
|
Checks, if library and header is available for language (may be 'C'
|
||||||
or 'CXX'). Call maybe be a valid expression _with_ a trailing ';'.
|
or 'CXX'). Call maybe be a valid expression _with_ a trailing ';'.
|
||||||
As in CheckLib, we support library=None, to test if the call compiles
|
As in CheckLib, we support library=None, to test if the call compiles
|
||||||
without extra link flags.
|
without extra link flags.
|
||||||
"""
|
"""
|
||||||
|
prog_prefix, dummy = \
|
||||||
if not SCons.Util.is_List(header):
|
createIncludesFromHeaders(header, 0)
|
||||||
header = [header]
|
|
||||||
l = []
|
|
||||||
for s in header:
|
|
||||||
l.append('#include "%s"\n' % (s))
|
|
||||||
|
|
||||||
|
|
||||||
if libs == []:
|
if libs == []:
|
||||||
libs = [None]
|
libs = [None]
|
||||||
|
|
||||||
if not SCons.Util.is_List(libs):
|
if not SCons.Util.is_List(libs):
|
||||||
libs = [libs]
|
libs = [libs]
|
||||||
|
|
||||||
res = SCons.Conftest.CheckLib(context, libs, "main", string.join(l, ''),
|
res = SCons.Conftest.CheckLib(context, libs, None, prog_prefix,
|
||||||
call = call, language = language, autoadd = autoadd)
|
call = call, language = language, autoadd = autoadd)
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
if not res:
|
return not res
|
||||||
return 1 # Ok
|
|
||||||
return 0 # Failed
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ Writing and reading information to the .sconsign file or files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,26 +27,85 @@ Writing and reading information to the .sconsign file or files.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/SConsign.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/SConsign.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import cPickle
|
import cPickle
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import time
|
|
||||||
|
|
||||||
import SCons.Node
|
import SCons.dblite
|
||||||
import SCons.Sig
|
import SCons.Sig
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
|
|
||||||
|
def corrupt_dblite_warning(filename):
|
||||||
|
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
||||||
|
"Ignoring corrupt .sconsign file: %s"%filename)
|
||||||
|
|
||||||
|
SCons.dblite.ignore_corrupt_dbfiles = 1
|
||||||
|
SCons.dblite.corruption_warning = corrupt_dblite_warning
|
||||||
|
|
||||||
#XXX Get rid of the global array so this becomes re-entrant.
|
#XXX Get rid of the global array so this becomes re-entrant.
|
||||||
sig_files = []
|
sig_files = []
|
||||||
|
|
||||||
database = None
|
# Info for the database SConsign implementation (now the default):
|
||||||
|
# "DataBase" is a dictionary that maps top-level SConstruct directories
|
||||||
|
# to open database handles.
|
||||||
|
# "DB_Module" is the Python database module to create the handles.
|
||||||
|
# "DB_Name" is the base name of the database file (minus any
|
||||||
|
# extension the underlying DB module will add).
|
||||||
|
DataBase = {}
|
||||||
|
DB_Module = SCons.dblite
|
||||||
|
DB_Name = ".sconsign"
|
||||||
|
DB_sync_list = []
|
||||||
|
|
||||||
|
def Get_DataBase(dir):
|
||||||
|
global DataBase, DB_Module, DB_Name
|
||||||
|
top = dir.fs.Top
|
||||||
|
if not os.path.isabs(DB_Name) and top.repositories:
|
||||||
|
mode = "c"
|
||||||
|
for d in [top] + top.repositories:
|
||||||
|
if dir.is_under(d):
|
||||||
|
try:
|
||||||
|
return DataBase[d], mode
|
||||||
|
except KeyError:
|
||||||
|
path = d.entry_abspath(DB_Name)
|
||||||
|
try: db = DataBase[d] = DB_Module.open(path, mode)
|
||||||
|
except (IOError, OSError): pass
|
||||||
|
else:
|
||||||
|
if mode != "r":
|
||||||
|
DB_sync_list.append(db)
|
||||||
|
return db, mode
|
||||||
|
mode = "r"
|
||||||
|
try:
|
||||||
|
return DataBase[top], "c"
|
||||||
|
except KeyError:
|
||||||
|
db = DataBase[top] = DB_Module.open(DB_Name, "c")
|
||||||
|
DB_sync_list.append(db)
|
||||||
|
return db, "c"
|
||||||
|
except TypeError:
|
||||||
|
print "DataBase =", DataBase
|
||||||
|
raise
|
||||||
|
|
||||||
|
def Reset():
|
||||||
|
"""Reset global state. Used by unit tests that end up using
|
||||||
|
SConsign multiple times to get a clean slate for each test."""
|
||||||
|
global sig_files, DB_sync_list
|
||||||
|
sig_files = []
|
||||||
|
DB_sync_list = []
|
||||||
|
|
||||||
|
normcase = os.path.normcase
|
||||||
|
|
||||||
def write():
|
def write():
|
||||||
global sig_files
|
global sig_files
|
||||||
for sig_file in sig_files:
|
for sig_file in sig_files:
|
||||||
sig_file.write()
|
sig_file.write(sync=0)
|
||||||
|
for db in DB_sync_list:
|
||||||
|
try:
|
||||||
|
syncmethod = db.sync
|
||||||
|
except AttributeError:
|
||||||
|
pass # Not all anydbm modules have sync() methods.
|
||||||
|
else:
|
||||||
|
syncmethod()
|
||||||
|
|
||||||
class Base:
|
class Base:
|
||||||
"""
|
"""
|
||||||
|
@ -79,19 +138,28 @@ class Base:
|
||||||
self.entries[filename] = obj
|
self.entries[filename] = obj
|
||||||
self.dirty = 1
|
self.dirty = 1
|
||||||
|
|
||||||
|
def do_not_set_entry(self, filename, obj):
|
||||||
|
pass
|
||||||
|
|
||||||
class DB(Base):
|
class DB(Base):
|
||||||
"""
|
"""
|
||||||
A Base subclass that reads and writes signature information
|
A Base subclass that reads and writes signature information
|
||||||
from a global .sconsign.dbm file.
|
from a global .sconsign.db* file--the actual file suffix is
|
||||||
|
determined by the specified database module.
|
||||||
"""
|
"""
|
||||||
def __init__(self, dir, module=None):
|
def __init__(self, dir, module=None):
|
||||||
Base.__init__(self, module)
|
Base.__init__(self, module)
|
||||||
|
|
||||||
self.dir = dir
|
self.dir = dir
|
||||||
|
|
||||||
|
db, mode = Get_DataBase(dir)
|
||||||
|
|
||||||
|
# Read using the path relative to the top of the Repository
|
||||||
|
# (self.dir.tpath) from which we're fetching the signature
|
||||||
|
# information.
|
||||||
|
path = normcase(dir.tpath)
|
||||||
try:
|
try:
|
||||||
global database
|
rawentries = db[path]
|
||||||
rawentries = database[self.dir.path]
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -102,22 +170,45 @@ class DB(Base):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except:
|
except Exception, e:
|
||||||
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
||||||
"Ignoring corrupt sconsign entry : %s"%self.dir.path)
|
"Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.tpath, e))
|
||||||
|
for key, entry in self.entries.items():
|
||||||
|
entry.convert_from_sconsign(dir, key)
|
||||||
|
|
||||||
|
if mode == "r":
|
||||||
|
# This directory is actually under a repository, which means
|
||||||
|
# likely they're reaching in directly for a dependency on
|
||||||
|
# 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
|
||||||
|
|
||||||
global sig_files
|
global sig_files
|
||||||
sig_files.append(self)
|
sig_files.append(self)
|
||||||
|
|
||||||
def write(self):
|
def write(self, sync=1):
|
||||||
if self.dirty:
|
if not self.dirty:
|
||||||
global database
|
return
|
||||||
database[self.dir.path] = cPickle.dumps(self.entries, 1)
|
|
||||||
|
db, mode = Get_DataBase(self.dir)
|
||||||
|
|
||||||
|
# Write using the path relative to the top of the SConstruct
|
||||||
|
# directory (self.dir.path), not relative to the top of
|
||||||
|
# the Repository; we only write to our own .sconsign file,
|
||||||
|
# not to .sconsign files in Repositories.
|
||||||
|
path = normcase(self.dir.path)
|
||||||
|
for key, entry in self.entries.items():
|
||||||
|
entry.convert_to_sconsign()
|
||||||
|
db[path] = cPickle.dumps(self.entries, 1)
|
||||||
|
|
||||||
|
if sync:
|
||||||
try:
|
try:
|
||||||
database.sync()
|
syncmethod = db.sync
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Not all anydbm modules have sync() methods.
|
# Not all anydbm modules have sync() methods.
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
syncmethod()
|
||||||
|
|
||||||
class Dir(Base):
|
class Dir(Base):
|
||||||
def __init__(self, fp=None, module=None):
|
def __init__(self, fp=None, module=None):
|
||||||
|
@ -162,7 +253,16 @@ class DirFile(Dir):
|
||||||
global sig_files
|
global sig_files
|
||||||
sig_files.append(self)
|
sig_files.append(self)
|
||||||
|
|
||||||
def write(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.
|
Write the .sconsign file to disk.
|
||||||
|
|
||||||
|
@ -186,6 +286,8 @@ class DirFile(Dir):
|
||||||
fname = self.sconsign
|
fname = self.sconsign
|
||||||
except IOError:
|
except IOError:
|
||||||
return
|
return
|
||||||
|
for key, entry in self.entries.items():
|
||||||
|
entry.convert_to_sconsign()
|
||||||
cPickle.dump(self.entries, file, 1)
|
cPickle.dump(self.entries, file, 1)
|
||||||
file.close()
|
file.close()
|
||||||
if fname != self.sconsign:
|
if fname != self.sconsign:
|
||||||
|
@ -193,31 +295,42 @@ class DirFile(Dir):
|
||||||
mode = os.stat(self.sconsign)[0]
|
mode = os.stat(self.sconsign)[0]
|
||||||
os.chmod(self.sconsign, 0666)
|
os.chmod(self.sconsign, 0666)
|
||||||
os.unlink(self.sconsign)
|
os.unlink(self.sconsign)
|
||||||
except OSError:
|
except (IOError, OSError):
|
||||||
|
# Try to carry on in the face of either OSError
|
||||||
|
# (things like permission issues) or IOError (disk
|
||||||
|
# or network issues). If there's a really dangerous
|
||||||
|
# issue, it should get re-raised by the calls below.
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
os.rename(fname, self.sconsign)
|
os.rename(fname, self.sconsign)
|
||||||
except OSError:
|
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())
|
open(self.sconsign, 'wb').write(open(fname, 'rb').read())
|
||||||
os.chmod(self.sconsign, mode)
|
os.chmod(self.sconsign, mode)
|
||||||
try:
|
try:
|
||||||
os.unlink(temp)
|
os.unlink(temp)
|
||||||
except OSError:
|
except (IOError, OSError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
ForDirectory = DirFile
|
ForDirectory = DB
|
||||||
|
|
||||||
def File(name, dbm_module=None):
|
def File(name, dbm_module=None):
|
||||||
"""
|
"""
|
||||||
Arrange for all signatures to be stored in a global .sconsign.dbm
|
Arrange for all signatures to be stored in a global .sconsign.db*
|
||||||
file.
|
file.
|
||||||
"""
|
"""
|
||||||
global database
|
global ForDirectory, DB_Name, DB_Module
|
||||||
if database is None:
|
if name is None:
|
||||||
if dbm_module is None:
|
ForDirectory = DirFile
|
||||||
import SCons.dblite
|
DB_Module = None
|
||||||
dbm_module = SCons.dblite
|
else:
|
||||||
database = dbm_module.open(name, "c")
|
ForDirectory = DB
|
||||||
|
DB_Name = name
|
||||||
global ForDirectory
|
if not dbm_module is None:
|
||||||
ForDirectory = DB
|
DB_Module = dbm_module
|
|
@ -5,7 +5,7 @@ This module implements the depenency scanner for C/C++ code.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,17 +27,16 @@ This module implements the depenency scanner for C/C++ code.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/C.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/C.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
|
|
||||||
def CScan(fs = SCons.Node.FS.default_fs):
|
def CScanner():
|
||||||
"""Return a prototype Scanner instance for scanning source files
|
"""Return a prototype Scanner instance for scanning source files
|
||||||
that use the C pre-processor"""
|
that use the C pre-processor"""
|
||||||
cs = SCons.Scanner.ClassicCPP("CScan",
|
cs = SCons.Scanner.ClassicCPP("CScanner",
|
||||||
"$CPPSUFFIXES",
|
"$CPPSUFFIXES",
|
||||||
"CPPPATH",
|
"CPPPATH",
|
||||||
'^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")',
|
'^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")')
|
||||||
fs = fs)
|
|
||||||
return cs
|
return cs
|
|
@ -8,7 +8,7 @@ Coded by Andy Friesen
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,27 +30,24 @@ Coded by Andy Friesen
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/D.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/D.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
|
|
||||||
def DScan(fs = SCons.Node.FS.default_fs):
|
def DScanner():
|
||||||
"""Return a prototype Scanner instance for scanning D source files"""
|
"""Return a prototype Scanner instance for scanning D source files"""
|
||||||
ds = DScanner(name = "DScan",
|
ds = D(name = "DScanner",
|
||||||
suffixes = '$DSUFFIXES',
|
suffixes = '$DSUFFIXES',
|
||||||
path_variable = 'DPATH',
|
path_variable = 'DPATH',
|
||||||
regex = 'import\s+([^\;]*)\;',
|
regex = 'import\s+([^\;]*)\;')
|
||||||
fs = fs)
|
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
class DScanner(SCons.Scanner.Classic):
|
class D(SCons.Scanner.Classic):
|
||||||
def find_include(self, include, source_dir, path):
|
def find_include(self, include, source_dir, path):
|
||||||
# translate dots (package separators) to slashes
|
# translate dots (package separators) to slashes
|
||||||
inc = string.replace(include, '.', '/')
|
inc = string.replace(include, '.', '/')
|
||||||
|
|
||||||
i = SCons.Node.FS.find_file(inc + '.d',
|
i = SCons.Node.FS.find_file(inc + '.d', (source_dir,) + path)
|
||||||
(source_dir,) + path,
|
|
||||||
self.fs.File)
|
|
||||||
return i, include
|
return i, include
|
105
scons/scons-local-0.97/SCons/Scanner/Dir.py
Normal file
105
scons/scons-local-0.97/SCons/Scanner/Dir.py
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Scanner/Dir.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.Node.FS
|
||||||
|
import SCons.Scanner
|
||||||
|
|
||||||
|
def only_dirs(nodes):
|
||||||
|
is_Dir = lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir)
|
||||||
|
return filter(is_Dir, nodes)
|
||||||
|
|
||||||
|
def DirScanner(**kw):
|
||||||
|
"""Return a prototype Scanner instance for scanning
|
||||||
|
directories for on-disk files"""
|
||||||
|
kw['node_factory'] = SCons.Node.FS.Entry
|
||||||
|
kw['recursive'] = only_dirs
|
||||||
|
return apply(SCons.Scanner.Base, (scan_on_disk, "DirScanner"), kw)
|
||||||
|
|
||||||
|
def DirEntryScanner(**kw):
|
||||||
|
"""Return a prototype Scanner instance for "scanning"
|
||||||
|
directory Nodes for their in-memory entries"""
|
||||||
|
kw['node_factory'] = SCons.Node.FS.Entry
|
||||||
|
kw['recursive'] = None
|
||||||
|
return apply(SCons.Scanner.Base, (scan_in_memory, "DirEntryScanner"), kw)
|
||||||
|
|
||||||
|
skip_entry = {}
|
||||||
|
|
||||||
|
skip_entry_list = [
|
||||||
|
'.',
|
||||||
|
'..',
|
||||||
|
'.sconsign',
|
||||||
|
# Used by the native dblite.py module.
|
||||||
|
'.sconsign.dblite',
|
||||||
|
# Used by dbm and dumbdbm.
|
||||||
|
'.sconsign.dir',
|
||||||
|
# Used by dbm.
|
||||||
|
'.sconsign.pag',
|
||||||
|
# Used by dumbdbm.
|
||||||
|
'.sconsign.dat',
|
||||||
|
'.sconsign.bak',
|
||||||
|
# Used by some dbm emulations using Berkeley DB.
|
||||||
|
'.sconsign.db',
|
||||||
|
]
|
||||||
|
|
||||||
|
for skip in skip_entry_list:
|
||||||
|
skip_entry[skip] = 1
|
||||||
|
skip_entry[SCons.Node.FS._my_normcase(skip)] = 1
|
||||||
|
|
||||||
|
do_not_scan = lambda k: not skip_entry.has_key(k)
|
||||||
|
|
||||||
|
def scan_on_disk(node, env, path=()):
|
||||||
|
"""
|
||||||
|
Scans a directory for on-disk files and directories therein.
|
||||||
|
|
||||||
|
Looking up the entries will add these to the in-memory Node tree
|
||||||
|
representation of the file system, so all we have to do is just
|
||||||
|
that and then call the in-memory scanning function.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
flist = node.fs.listdir(node.abspath)
|
||||||
|
except (IOError, OSError):
|
||||||
|
return []
|
||||||
|
e = node.Entry
|
||||||
|
for f in filter(do_not_scan, flist):
|
||||||
|
# Add ./ to the beginning of the file name so if it begins with a
|
||||||
|
# '#' we don't look it up relative to the top-level directory.
|
||||||
|
e('./' + f)
|
||||||
|
return scan_in_memory(node, env, path)
|
||||||
|
|
||||||
|
def scan_in_memory(node, env, path=()):
|
||||||
|
"""
|
||||||
|
"Scans" a Node.FS.Dir for its in-memory entries.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
entries = node.entries
|
||||||
|
except AttributeError:
|
||||||
|
# It's not a Node.FS.Dir (or doesn't look enough like one for
|
||||||
|
# our purposes), which can happen if a target list containing
|
||||||
|
# mixed Node types (Dirs and Files, for example) has a Dir as
|
||||||
|
# the first entry.
|
||||||
|
return []
|
||||||
|
entry_list = filter(do_not_scan, entries.keys())
|
||||||
|
entry_list.sort()
|
||||||
|
return map(lambda n, e=entries: e[n], entry_list)
|
|
@ -5,7 +5,7 @@ This module implements the dependency scanner for Fortran code.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for Fortran code.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/Fortran.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/Fortran.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
|
@ -54,18 +54,23 @@ class F90Scanner(SCons.Scanner.Classic):
|
||||||
smart thing to do.
|
smart thing to do.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, suffixes, path_variable, use_regex,
|
def __init__(self, name, suffixes, path_variable,
|
||||||
incl_regex, fs=SCons.Node.FS.default_fs, *args, **kw):
|
use_regex, incl_regex, def_regex, *args, **kw):
|
||||||
|
|
||||||
self.cre_use = re.compile(use_regex, re.M)
|
self.cre_use = re.compile(use_regex, re.M)
|
||||||
self.cre_incl = re.compile(incl_regex, re.M)
|
self.cre_incl = re.compile(incl_regex, re.M)
|
||||||
self.fs = fs
|
self.cre_def = re.compile(def_regex, re.M)
|
||||||
|
|
||||||
|
def _scan(node, env, path, self=self):
|
||||||
|
node = node.rfile()
|
||||||
|
|
||||||
|
if not node.exists():
|
||||||
|
return []
|
||||||
|
|
||||||
def _scan(node, env, path, self=self, fs=fs):
|
|
||||||
return self.scan(node, env, path)
|
return self.scan(node, env, path)
|
||||||
|
|
||||||
kw['function'] = _scan
|
kw['function'] = _scan
|
||||||
kw['path_function'] = SCons.Scanner.FindPathDirs(path_variable, fs)
|
kw['path_function'] = SCons.Scanner.FindPathDirs(path_variable)
|
||||||
kw['recursive'] = 1
|
kw['recursive'] = 1
|
||||||
kw['skeys'] = suffixes
|
kw['skeys'] = suffixes
|
||||||
kw['name'] = name
|
kw['name'] = name
|
||||||
|
@ -73,10 +78,6 @@ class F90Scanner(SCons.Scanner.Classic):
|
||||||
apply(SCons.Scanner.Current.__init__, (self,) + args, kw)
|
apply(SCons.Scanner.Current.__init__, (self,) + args, kw)
|
||||||
|
|
||||||
def scan(self, node, env, path=()):
|
def scan(self, node, env, path=()):
|
||||||
node = node.rfile()
|
|
||||||
|
|
||||||
if not node.exists():
|
|
||||||
return []
|
|
||||||
|
|
||||||
# cache the includes list in node so we only scan it once:
|
# cache the includes list in node so we only scan it once:
|
||||||
if node.includes != None:
|
if node.includes != None:
|
||||||
|
@ -86,6 +87,15 @@ class F90Scanner(SCons.Scanner.Classic):
|
||||||
includes = self.cre_incl.findall(node.get_contents())
|
includes = self.cre_incl.findall(node.get_contents())
|
||||||
# retrieve all USE'd module names
|
# retrieve all USE'd module names
|
||||||
modules = self.cre_use.findall(node.get_contents())
|
modules = self.cre_use.findall(node.get_contents())
|
||||||
|
# retrieve all defined module names
|
||||||
|
defmodules = self.cre_def.findall(node.get_contents())
|
||||||
|
|
||||||
|
# Remove all USE'd module names that are defined in the same file
|
||||||
|
d = {}
|
||||||
|
for m in defmodules:
|
||||||
|
d[m] = 1
|
||||||
|
modules = filter(lambda m, d=d: not d.has_key(m), modules)
|
||||||
|
#modules = self.undefinedModules(modules, defmodules)
|
||||||
|
|
||||||
# Convert module name to a .mod filename
|
# Convert module name to a .mod filename
|
||||||
suffix = env.subst('$FORTRANMODSUFFIX')
|
suffix = env.subst('$FORTRANMODSUFFIX')
|
||||||
|
@ -94,44 +104,30 @@ class F90Scanner(SCons.Scanner.Classic):
|
||||||
mods_and_includes = SCons.Util.unique(includes+modules)
|
mods_and_includes = SCons.Util.unique(includes+modules)
|
||||||
node.includes = mods_and_includes
|
node.includes = mods_and_includes
|
||||||
|
|
||||||
|
# This is a hand-coded DSU (decorate-sort-undecorate, or
|
||||||
|
# Schwartzian transform) pattern. The sort key is the raw name
|
||||||
|
# of the file as specifed on the USE or INCLUDE line, which lets
|
||||||
|
# us keep the sort order constant regardless of whether the file
|
||||||
|
# is actually found in a Repository or locally.
|
||||||
nodes = []
|
nodes = []
|
||||||
source_dir = node.get_dir()
|
source_dir = node.get_dir()
|
||||||
|
if callable(path):
|
||||||
|
path = path()
|
||||||
for dep in mods_and_includes:
|
for dep in mods_and_includes:
|
||||||
n, i = self.find_include(dep, source_dir, path)
|
n, i = self.find_include(dep, source_dir, path)
|
||||||
|
|
||||||
if not n is None:
|
if n is None:
|
||||||
nodes.append(n)
|
|
||||||
else:
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
||||||
"No dependency generated for file: %s (referenced by: %s) -- file not found" % (i, node))
|
"No dependency generated for file: %s (referenced by: %s) -- file not found" % (i, node))
|
||||||
|
else:
|
||||||
|
sortkey = self.sort_key(dep)
|
||||||
|
nodes.append((sortkey, n))
|
||||||
|
|
||||||
# Sort the list of dependencies
|
nodes.sort()
|
||||||
|
nodes = map(lambda pair: pair[1], nodes)
|
||||||
|
return nodes
|
||||||
|
|
||||||
# Schwartzian transform from the Python FAQ Wizard
|
def FortranScan(path_variable="FORTRANPATH"):
|
||||||
def st(List, Metric):
|
|
||||||
def pairing(element, M = Metric):
|
|
||||||
return (M(element), element)
|
|
||||||
def stripit(pair):
|
|
||||||
return pair[1]
|
|
||||||
paired = map(pairing, List)
|
|
||||||
paired.sort()
|
|
||||||
return map(stripit, paired)
|
|
||||||
|
|
||||||
def normalize(node):
|
|
||||||
# We don't want the order of includes to be
|
|
||||||
# modified by case changes on case insensitive OSes, so
|
|
||||||
# normalize the case of the filename here:
|
|
||||||
# (see test/win32pathmadness.py for a test of this)
|
|
||||||
return SCons.Node.FS._my_normcase(str(node))
|
|
||||||
|
|
||||||
# Apply a Schwartzian transform to return the list of
|
|
||||||
# dependencies, sorted according to their normalized names
|
|
||||||
transformed = st(nodes, normalize)
|
|
||||||
# print "ClassicF90: " + str(node) + " => " + str(map(lambda x: str(x),list(transformed)))
|
|
||||||
return transformed
|
|
||||||
|
|
||||||
|
|
||||||
def FortranScan(path_variable="FORTRANPATH", fs=SCons.Node.FS.default_fs):
|
|
||||||
"""Return a prototype Scanner instance for scanning source files
|
"""Return a prototype Scanner instance for scanning source files
|
||||||
for Fortran USE & INCLUDE statements"""
|
for Fortran USE & INCLUDE statements"""
|
||||||
|
|
||||||
|
@ -285,10 +281,34 @@ def FortranScan(path_variable="FORTRANPATH", fs=SCons.Node.FS.default_fs):
|
||||||
|
|
||||||
include_regex = """(?i)(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
|
include_regex = """(?i)(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
|
||||||
|
|
||||||
|
# The MODULE statement regex finds module definitions by matching
|
||||||
|
# the following:
|
||||||
|
#
|
||||||
|
# MODULE module_name
|
||||||
|
#
|
||||||
|
# but *not* the following:
|
||||||
|
#
|
||||||
|
# MODULE PROCEDURE procedure_name
|
||||||
|
#
|
||||||
|
# Here is a breakdown of the regex:
|
||||||
|
#
|
||||||
|
# (?i) : regex is case insensitive
|
||||||
|
# ^\s* : any amount of white space
|
||||||
|
# MODULE : match the string MODULE, case insensitive
|
||||||
|
# \s+ : match one or more white space characters
|
||||||
|
# (?!PROCEDURE) : but *don't* match if the next word matches
|
||||||
|
# PROCEDURE (negative lookahead assertion),
|
||||||
|
# case insensitive
|
||||||
|
# (\w+) : match one or more alphanumeric characters
|
||||||
|
# that make up the defined module name and
|
||||||
|
# save it in a group
|
||||||
|
|
||||||
|
def_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)"""
|
||||||
|
|
||||||
scanner = F90Scanner("FortranScan",
|
scanner = F90Scanner("FortranScan",
|
||||||
"$FORTRANSUFFIXES",
|
"$FORTRANSUFFIXES",
|
||||||
path_variable,
|
path_variable,
|
||||||
use_regex,
|
use_regex,
|
||||||
include_regex,
|
include_regex,
|
||||||
fs = fs)
|
def_regex)
|
||||||
return scanner
|
return scanner
|
|
@ -6,7 +6,7 @@ Definition Language) files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,16 +28,15 @@ Definition Language) files.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/IDL.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/IDL.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
|
|
||||||
def IDLScan(fs = SCons.Node.FS.default_fs):
|
def IDLScan():
|
||||||
"""Return a prototype Scanner instance for scanning IDL source files"""
|
"""Return a prototype Scanner instance for scanning IDL source files"""
|
||||||
cs = SCons.Scanner.ClassicCPP("IDLScan",
|
cs = SCons.Scanner.ClassicCPP("IDLScan",
|
||||||
"$IDLSUFFIXES",
|
"$IDLSUFFIXES",
|
||||||
"CPPPATH",
|
"CPPPATH",
|
||||||
'^[ \t]*(?:#[ \t]*include|[ \t]*import)[ \t]+(<|")([^>"]+)(>|")',
|
'^[ \t]*(?:#[ \t]*include|[ \t]*import)[ \t]+(<|")([^>"]+)(>|")')
|
||||||
fs = fs)
|
|
||||||
return cs
|
return cs
|
122
scons/scons-local-0.97/SCons/Scanner/LaTeX.py
Normal file
122
scons/scons-local-0.97/SCons/Scanner/LaTeX.py
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
"""SCons.Scanner.LaTeX
|
||||||
|
|
||||||
|
This module implements the dependency scanner for LaTeX code.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Scanner/LaTeX.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
|
||||||
|
import SCons.Scanner
|
||||||
|
import string
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
def LaTeXScanner(fs = SCons.Node.FS.default_fs):
|
||||||
|
"""Return a prototype Scanner instance for scanning LaTeX source files"""
|
||||||
|
ds = LaTeX(name = "LaTeXScanner",
|
||||||
|
suffixes = '$LATEXSUFFIXES',
|
||||||
|
path_variable = 'TEXINPUTS',
|
||||||
|
regex = '\\\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography){([^}]*)}',
|
||||||
|
recursive = 0)
|
||||||
|
return ds
|
||||||
|
|
||||||
|
class LaTeX(SCons.Scanner.Classic):
|
||||||
|
"""Class for scanning LaTeX files for included files.
|
||||||
|
|
||||||
|
Unlike most scanners, which use regular expressions that just
|
||||||
|
return the included file name, this returns a tuple consisting
|
||||||
|
of the keyword for the inclusion ("include", "includegraphics",
|
||||||
|
"input", or "bibliography"), and then the file name itself.
|
||||||
|
Based on a quick look at LaTeX documentation, it seems that we
|
||||||
|
need a should append .tex suffix for the "include" keywords,
|
||||||
|
append .tex if there is no extension for the "input" keyword,
|
||||||
|
but leave the file name untouched for "includegraphics." For
|
||||||
|
the "bibliography" keyword we need to add .bib if there is
|
||||||
|
no extension. (This need to be revisited since if there
|
||||||
|
is no extension for an :includegraphics" keyword latex will
|
||||||
|
append .ps or .eps to find the file; while pdftex will use
|
||||||
|
other extensions.)
|
||||||
|
"""
|
||||||
|
def latex_name(self, include):
|
||||||
|
filename = include[1]
|
||||||
|
if include[0] == 'input':
|
||||||
|
base, ext = os.path.splitext( filename )
|
||||||
|
if ext == "":
|
||||||
|
filename = filename + '.tex'
|
||||||
|
if (include[0] == 'include'):
|
||||||
|
filename = filename + '.tex'
|
||||||
|
if include[0] == 'bibliography':
|
||||||
|
base, ext = os.path.splitext( filename )
|
||||||
|
if ext == "":
|
||||||
|
filename = filename + '.bib'
|
||||||
|
return filename
|
||||||
|
def sort_key(self, include):
|
||||||
|
return SCons.Node.FS._my_normcase(self.latex_name(include))
|
||||||
|
def find_include(self, include, source_dir, path):
|
||||||
|
i = SCons.Node.FS.find_file(self.latex_name(include),
|
||||||
|
(source_dir,) + path)
|
||||||
|
return i, include
|
||||||
|
|
||||||
|
def scan(self, node, path=()):
|
||||||
|
#
|
||||||
|
# Modify the default scan function to allow for the regular
|
||||||
|
# expression to return a comma separated list of file names
|
||||||
|
# as can be the case with the bibliography keyword.
|
||||||
|
#
|
||||||
|
# cache the includes list in node so we only scan it once:
|
||||||
|
if node.includes != None:
|
||||||
|
includes = node.includes
|
||||||
|
else:
|
||||||
|
includes = self.cre.findall(node.get_contents())
|
||||||
|
node.includes = includes
|
||||||
|
|
||||||
|
# This is a hand-coded DSU (decorate-sort-undecorate, or
|
||||||
|
# Schwartzian transform) pattern. The sort key is the raw name
|
||||||
|
# of the file as specifed on the #include line (including the
|
||||||
|
# " or <, since that may affect what file is found), which lets
|
||||||
|
# us keep the sort order constant regardless of whether the file
|
||||||
|
# is actually found in a Repository or locally.
|
||||||
|
nodes = []
|
||||||
|
source_dir = node.get_dir()
|
||||||
|
for include in includes:
|
||||||
|
#
|
||||||
|
# Handle multiple filenames in include[1]
|
||||||
|
#
|
||||||
|
inc_list = string.split(include[1],',')
|
||||||
|
for j in range(len(inc_list)):
|
||||||
|
include_local = [include[0],inc_list[j]]
|
||||||
|
n, i = self.find_include(include_local, source_dir, path)
|
||||||
|
|
||||||
|
if n is None:
|
||||||
|
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
||||||
|
"No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
|
||||||
|
else:
|
||||||
|
sortkey = self.sort_key(include)
|
||||||
|
nodes.append((sortkey, n))
|
||||||
|
|
||||||
|
nodes.sort()
|
||||||
|
nodes = map(lambda pair: pair[1], nodes)
|
||||||
|
return nodes
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/Prog.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/Prog.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
||||||
|
@ -30,57 +30,70 @@ import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
def ProgScan(fs = SCons.Node.FS.default_fs):
|
# global, set by --debug=findlibs
|
||||||
|
print_find_libs = None
|
||||||
|
|
||||||
|
def ProgramScanner(**kw):
|
||||||
"""Return a prototype Scanner instance for scanning executable
|
"""Return a prototype Scanner instance for scanning executable
|
||||||
files for static-lib dependencies"""
|
files for static-lib dependencies"""
|
||||||
pf = SCons.Scanner.FindPathDirs('LIBPATH', fs)
|
kw['path_function'] = SCons.Scanner.FindPathDirs('LIBPATH')
|
||||||
ps = SCons.Scanner.Base(scan, "ProgScan", path_function = pf)
|
ps = apply(SCons.Scanner.Base, [scan, "ProgramScanner"], kw)
|
||||||
return ps
|
return ps
|
||||||
|
|
||||||
def scan(node, env, libpath = (), fs = SCons.Node.FS.default_fs):
|
def scan(node, env, libpath = ()):
|
||||||
"""
|
"""
|
||||||
This scanner scans program files for static-library
|
This scanner scans program files for static-library
|
||||||
dependencies. It will search the LIBPATH environment variable
|
dependencies. It will search the LIBPATH environment variable
|
||||||
for libraries specified in the LIBS variable, returning any
|
for libraries specified in the LIBS variable, returning any
|
||||||
files it finds as dependencies.
|
files it finds as dependencies.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
libs = env.Dictionary('LIBS')
|
libs = env['LIBS']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# There are no LIBS in this environment, so just return a null list:
|
# There are no LIBS in this environment, so just return a null list:
|
||||||
return []
|
return []
|
||||||
if SCons.Util.is_String(libs):
|
if SCons.Util.is_String(libs):
|
||||||
libs = string.split(libs)
|
libs = string.split(libs)
|
||||||
elif not SCons.Util.is_List(libs):
|
elif SCons.Util.is_List(libs):
|
||||||
|
libs = SCons.Util.flatten(libs)
|
||||||
|
else:
|
||||||
libs = [libs]
|
libs = [libs]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
prefix = env.Dictionary('LIBPREFIXES')
|
prefix = env['LIBPREFIXES']
|
||||||
if not SCons.Util.is_List(prefix):
|
if not SCons.Util.is_List(prefix):
|
||||||
prefix = [ prefix ]
|
prefix = [ prefix ]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
prefix = [ '' ]
|
prefix = [ '' ]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
suffix = env.Dictionary('LIBSUFFIXES')
|
suffix = env['LIBSUFFIXES']
|
||||||
if not SCons.Util.is_List(suffix):
|
if not SCons.Util.is_List(suffix):
|
||||||
suffix = [ suffix ]
|
suffix = [ suffix ]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
suffix = [ '' ]
|
suffix = [ '' ]
|
||||||
|
|
||||||
find_file = SCons.Node.FS.find_file
|
pairs = []
|
||||||
adjustixes = SCons.Util.adjustixes
|
|
||||||
result = []
|
|
||||||
for suf in map(env.subst, suffix):
|
for suf in map(env.subst, suffix):
|
||||||
for pref in map(env.subst, prefix):
|
for pref in map(env.subst, prefix):
|
||||||
for lib in libs:
|
pairs.append((pref, suf))
|
||||||
if SCons.Util.is_String(lib):
|
|
||||||
lib = env.subst(lib)
|
result = []
|
||||||
lib = adjustixes(lib, pref, suf)
|
|
||||||
lib = find_file(lib, libpath, fs.File)
|
if callable(libpath):
|
||||||
if lib:
|
libpath = libpath()
|
||||||
result.append(lib)
|
|
||||||
else:
|
find_file = SCons.Node.FS.find_file
|
||||||
result.append(lib)
|
adjustixes = SCons.Util.adjustixes
|
||||||
|
for lib in libs:
|
||||||
|
if SCons.Util.is_String(lib):
|
||||||
|
lib = env.subst(lib)
|
||||||
|
for pref, suf in pairs:
|
||||||
|
l = adjustixes(lib, pref, suf)
|
||||||
|
l = find_file(l, libpath, verbose=print_find_libs)
|
||||||
|
if l:
|
||||||
|
result.append(l)
|
||||||
|
else:
|
||||||
|
result.append(lib)
|
||||||
|
|
||||||
return result
|
return result
|
|
@ -5,7 +5,7 @@ The Scanner package for the SCons software construction utility.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,9 +27,10 @@ The Scanner package for the SCons software construction utility.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/__init__.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Scanner/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import string
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Sig
|
import SCons.Sig
|
||||||
|
@ -44,30 +45,41 @@ class _Null:
|
||||||
_null = _Null
|
_null = _Null
|
||||||
|
|
||||||
def Scanner(function, *args, **kw):
|
def Scanner(function, *args, **kw):
|
||||||
"""Public interface factory function for creating different types
|
"""
|
||||||
|
Public interface factory function for creating different types
|
||||||
of Scanners based on the different types of "functions" that may
|
of Scanners based on the different types of "functions" that may
|
||||||
be supplied."""
|
be supplied.
|
||||||
|
|
||||||
|
TODO: Deprecate this some day. We've moved the functionality
|
||||||
|
inside the Base class and really don't need this factory function
|
||||||
|
any more. It was, however, used by some of our Tool modules, so
|
||||||
|
the call probably ended up in various people's custom modules
|
||||||
|
patterned on SCons code.
|
||||||
|
"""
|
||||||
if SCons.Util.is_Dict(function):
|
if SCons.Util.is_Dict(function):
|
||||||
return apply(Selector, (function,) + args, kw)
|
return apply(Selector, (function,) + args, kw)
|
||||||
else:
|
else:
|
||||||
return apply(Base, (function,) + args, kw)
|
return apply(Base, (function,) + args, kw)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FindPathDirs:
|
class FindPathDirs:
|
||||||
"""A class to bind a specific *PATH variable name and the fs object
|
"""A class to bind a specific *PATH variable name to a function that
|
||||||
to a function that will return all of the *path directories."""
|
will return all of the *path directories."""
|
||||||
def __init__(self, variable, fs):
|
def __init__(self, variable):
|
||||||
self.variable = variable
|
self.variable = variable
|
||||||
self.fs = fs
|
def __call__(self, env, dir, target=None, source=None, argument=None):
|
||||||
def __call__(self, env, dir, argument=None):
|
import SCons.PathList
|
||||||
try:
|
try:
|
||||||
path = env[self.variable]
|
path = env[self.variable]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
return tuple(self.fs.Rsearchall(env.subst_path(path),
|
dir = dir or env.fs._cwd
|
||||||
must_exist = 0,
|
path = SCons.PathList.PathList(path).subst_path(env, target, source)
|
||||||
clazz = SCons.Node.FS.Dir,
|
return tuple(dir.Rfindalldirs(path))
|
||||||
cwd = dir))
|
|
||||||
|
|
||||||
|
|
||||||
class Base:
|
class Base:
|
||||||
"""
|
"""
|
||||||
|
@ -79,10 +91,10 @@ class Base:
|
||||||
function,
|
function,
|
||||||
name = "NONE",
|
name = "NONE",
|
||||||
argument = _null,
|
argument = _null,
|
||||||
skeys = [],
|
skeys = _null,
|
||||||
path_function = None,
|
path_function = None,
|
||||||
node_class = SCons.Node.FS.Entry,
|
node_class = SCons.Node.FS.Entry,
|
||||||
node_factory = SCons.Node.FS.default_fs.File,
|
node_factory = None,
|
||||||
scan_check = None,
|
scan_check = None,
|
||||||
recursive = None):
|
recursive = None):
|
||||||
"""
|
"""
|
||||||
|
@ -100,10 +112,14 @@ class Base:
|
||||||
which scanner should be used for a given Node. In the case of File
|
which scanner should be used for a given Node. In the case of File
|
||||||
nodes, for example, the 'skeys' would be file suffixes.
|
nodes, for example, the 'skeys' would be file suffixes.
|
||||||
|
|
||||||
'path_function' - a function that takes one to three arguments
|
'path_function' - a function that takes four or five arguments
|
||||||
(a construction environment, optional directory, and optional
|
(a construction environment, Node for the directory containing
|
||||||
argument for this instance) and returns a tuple of the
|
the SConscript file that defined the primary target, list of
|
||||||
directories that can be searched for implicit dependency files.
|
target nodes, list of source nodes, and optional argument for
|
||||||
|
this instance) and returns a tuple of the directories that can
|
||||||
|
be searched for implicit dependency files. May also return a
|
||||||
|
callable() which is called with no args and returns the tuple
|
||||||
|
(supporting Bindable class).
|
||||||
|
|
||||||
'node_class' - the class of Nodes which this scan will return.
|
'node_class' - the class of Nodes which this scan will return.
|
||||||
If node_class is None, then this scanner will not enforce any
|
If node_class is None, then this scanner will not enforce any
|
||||||
|
@ -118,14 +134,19 @@ class Base:
|
||||||
this node really needs to be scanned.
|
this node really needs to be scanned.
|
||||||
|
|
||||||
'recursive' - specifies that this scanner should be invoked
|
'recursive' - specifies that this scanner should be invoked
|
||||||
recursively on the implicit dependencies it returns (the
|
recursively on all of the implicit dependencies it returns
|
||||||
canonical example being #include lines in C source files).
|
(the canonical example being #include lines in C source files).
|
||||||
|
May be a callable, which will be called to filter the list
|
||||||
|
of nodes found to select a subset for recursive scanning
|
||||||
|
(the canonical example being only recursively scanning
|
||||||
|
subdirectories within a directory).
|
||||||
|
|
||||||
The scanner function's first argument will be the name of a file
|
The scanner function's first argument will be a Node that should
|
||||||
that should be scanned for dependencies, the second argument will
|
be scanned for dependencies, the second argument will be an
|
||||||
be an Environment object, the third argument will be the value
|
Environment object, the third argument will be the tuple of paths
|
||||||
passed into 'argument', and the returned list should contain the
|
returned by the path_function, and the fourth argument will be
|
||||||
Nodes for all the direct dependencies of the file.
|
the value passed into 'argument', and the returned list should
|
||||||
|
contain the Nodes for all the direct dependencies of the file.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
@ -146,19 +167,31 @@ class Base:
|
||||||
self.path_function = path_function
|
self.path_function = path_function
|
||||||
self.name = name
|
self.name = name
|
||||||
self.argument = argument
|
self.argument = argument
|
||||||
|
|
||||||
|
if skeys is _null:
|
||||||
|
if SCons.Util.is_Dict(function):
|
||||||
|
skeys = function.keys()
|
||||||
|
else:
|
||||||
|
skeys = []
|
||||||
self.skeys = skeys
|
self.skeys = skeys
|
||||||
|
|
||||||
self.node_class = node_class
|
self.node_class = node_class
|
||||||
self.node_factory = node_factory
|
self.node_factory = node_factory
|
||||||
self.scan_check = scan_check
|
self.scan_check = scan_check
|
||||||
self.recursive = recursive
|
if callable(recursive):
|
||||||
|
self.recurse_nodes = recursive
|
||||||
|
elif recursive:
|
||||||
|
self.recurse_nodes = self._recurse_all_nodes
|
||||||
|
else:
|
||||||
|
self.recurse_nodes = self._recurse_no_nodes
|
||||||
|
|
||||||
def path(self, env, dir = None):
|
def path(self, env, dir=None, target=None, source=None):
|
||||||
if not self.path_function:
|
if not self.path_function:
|
||||||
return ()
|
return ()
|
||||||
if not self.argument is _null:
|
if not self.argument is _null:
|
||||||
return self.path_function(env, dir, self.argument)
|
return self.path_function(env, dir, target, source, self.argument)
|
||||||
else:
|
else:
|
||||||
return self.path_function(env, dir)
|
return self.path_function(env, dir, target, source)
|
||||||
|
|
||||||
def __call__(self, node, env, path = ()):
|
def __call__(self, node, env, path = ()):
|
||||||
"""
|
"""
|
||||||
|
@ -170,47 +203,85 @@ class Base:
|
||||||
if self.scan_check and not self.scan_check(node, env):
|
if self.scan_check and not self.scan_check(node, env):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
self = self.select(node)
|
||||||
|
|
||||||
if not self.argument is _null:
|
if not self.argument is _null:
|
||||||
list = self.function(node, env, path, self.argument)
|
list = self.function(node, env, path, self.argument)
|
||||||
else:
|
else:
|
||||||
list = self.function(node, env, path)
|
list = self.function(node, env, path)
|
||||||
|
|
||||||
kw = {}
|
kw = {}
|
||||||
if hasattr(node, 'dir'):
|
if hasattr(node, 'dir'):
|
||||||
kw['directory'] = node.dir
|
kw['directory'] = node.dir
|
||||||
|
node_factory = env.get_factory(self.node_factory)
|
||||||
nodes = []
|
nodes = []
|
||||||
for l in list:
|
for l in list:
|
||||||
if self.node_class and not isinstance(l, self.node_class):
|
if self.node_class and not isinstance(l, self.node_class):
|
||||||
l = apply(self.node_factory, (l,), kw)
|
l = apply(node_factory, (l,), kw)
|
||||||
nodes.append(l)
|
nodes.append(l)
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
return cmp(self.__dict__, other.__dict__)
|
try:
|
||||||
|
return cmp(self.__dict__, other.__dict__)
|
||||||
|
except AttributeError:
|
||||||
|
# other probably doesn't have a __dict__
|
||||||
|
return cmp(self.__dict__, other)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(repr(self))
|
return id(self)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def add_skey(self, skey):
|
def add_skey(self, skey):
|
||||||
"""Add a skey to the list of skeys"""
|
"""Add a skey to the list of skeys"""
|
||||||
self.skeys.append(skey)
|
self.skeys.append(skey)
|
||||||
|
|
||||||
def get_skeys(self, env=None):
|
def get_skeys(self, env=None):
|
||||||
if SCons.Util.is_String(self.skeys):
|
if env and SCons.Util.is_String(self.skeys):
|
||||||
return env.subst_list(self.skeys)[0]
|
return env.subst_list(self.skeys)[0]
|
||||||
return self.skeys
|
return self.skeys
|
||||||
|
|
||||||
def select(self, node):
|
def select(self, node):
|
||||||
return self
|
if SCons.Util.is_Dict(self.function):
|
||||||
|
key = node.scanner_key()
|
||||||
|
try:
|
||||||
|
return self.function[key]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return self
|
||||||
|
|
||||||
|
def _recurse_all_nodes(self, nodes):
|
||||||
|
return nodes
|
||||||
|
|
||||||
|
def _recurse_no_nodes(self, nodes):
|
||||||
|
return []
|
||||||
|
|
||||||
|
recurse_nodes = _recurse_no_nodes
|
||||||
|
|
||||||
|
def add_scanner(self, skey, scanner):
|
||||||
|
self.function[skey] = scanner
|
||||||
|
self.add_skey(skey)
|
||||||
|
|
||||||
|
|
||||||
class Selector(Base):
|
class Selector(Base):
|
||||||
"""
|
"""
|
||||||
A class for selecting a more specific scanner based on the
|
A class for selecting a more specific scanner based on the
|
||||||
scanner_key() (suffix) for a specific Node.
|
scanner_key() (suffix) for a specific Node.
|
||||||
|
|
||||||
|
TODO: This functionality has been moved into the inner workings of
|
||||||
|
the Base class, and this class will be deprecated at some point.
|
||||||
|
(It was never exposed directly as part of the public interface,
|
||||||
|
although it is used by the Scanner() factory function that was
|
||||||
|
used by various Tool modules and therefore was likely a template
|
||||||
|
for custom modules that may be out there.)
|
||||||
"""
|
"""
|
||||||
def __init__(self, dict, *args, **kw):
|
def __init__(self, dict, *args, **kw):
|
||||||
Base.__init__(self, (None,)+args, kw)
|
apply(Base.__init__, (self, None,)+args, kw)
|
||||||
self.dict = dict
|
self.dict = dict
|
||||||
|
self.skeys = dict.keys()
|
||||||
|
|
||||||
def __call__(self, node, env, path = ()):
|
def __call__(self, node, env, path = ()):
|
||||||
return self.select(node)(node, env, path)
|
return self.select(node)(node, env, path)
|
||||||
|
@ -223,6 +294,7 @@ class Selector(Base):
|
||||||
|
|
||||||
def add_scanner(self, skey, scanner):
|
def add_scanner(self, skey, scanner):
|
||||||
self.dict[skey] = scanner
|
self.dict[skey] = scanner
|
||||||
|
self.add_skey(skey)
|
||||||
|
|
||||||
|
|
||||||
class Current(Base):
|
class Current(Base):
|
||||||
|
@ -246,22 +318,23 @@ class Classic(Current):
|
||||||
regular expressions to find the includes.
|
regular expressions to find the includes.
|
||||||
|
|
||||||
Note that in order for this to work "out of the box" (without
|
Note that in order for this to work "out of the box" (without
|
||||||
overriding the find_include() method), the regular expression passed
|
overriding the find_include() and sort_key() methods), the regular
|
||||||
to the constructor must return the name of the include file in group
|
expression passed to the constructor must return the name of the
|
||||||
0.
|
include file in group 0.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, suffixes, path_variable, regex,
|
def __init__(self, name, suffixes, path_variable, regex, *args, **kw):
|
||||||
fs=SCons.Node.FS.default_fs, *args, **kw):
|
|
||||||
|
|
||||||
self.cre = re.compile(regex, re.M)
|
self.cre = re.compile(regex, re.M)
|
||||||
self.fs = fs
|
|
||||||
|
|
||||||
def _scan(node, env, path, self=self, fs=fs):
|
def _scan(node, env, path=(), self=self):
|
||||||
return self.scan(node, env, path)
|
node = node.rfile()
|
||||||
|
if not node.exists():
|
||||||
|
return []
|
||||||
|
return self.scan(node, path)
|
||||||
|
|
||||||
kw['function'] = _scan
|
kw['function'] = _scan
|
||||||
kw['path_function'] = FindPathDirs(path_variable, fs)
|
kw['path_function'] = FindPathDirs(path_variable)
|
||||||
kw['recursive'] = 1
|
kw['recursive'] = 1
|
||||||
kw['skeys'] = suffixes
|
kw['skeys'] = suffixes
|
||||||
kw['name'] = name
|
kw['name'] = name
|
||||||
|
@ -269,14 +342,13 @@ class Classic(Current):
|
||||||
apply(Current.__init__, (self,) + args, kw)
|
apply(Current.__init__, (self,) + args, kw)
|
||||||
|
|
||||||
def find_include(self, include, source_dir, path):
|
def find_include(self, include, source_dir, path):
|
||||||
n = SCons.Node.FS.find_file(include, (source_dir,) + path, self.fs.File)
|
n = SCons.Node.FS.find_file(include, (source_dir,) + tuple(path))
|
||||||
return n, include
|
return n, include
|
||||||
|
|
||||||
def scan(self, node, env, path=()):
|
def sort_key(self, include):
|
||||||
node = node.rfile()
|
return SCons.Node.FS._my_normcase(include)
|
||||||
|
|
||||||
if not node.exists():
|
def scan(self, node, path=()):
|
||||||
return []
|
|
||||||
|
|
||||||
# cache the includes list in node so we only scan it once:
|
# cache the includes list in node so we only scan it once:
|
||||||
if node.includes != None:
|
if node.includes != None:
|
||||||
|
@ -285,37 +357,29 @@ class Classic(Current):
|
||||||
includes = self.cre.findall(node.get_contents())
|
includes = self.cre.findall(node.get_contents())
|
||||||
node.includes = includes
|
node.includes = includes
|
||||||
|
|
||||||
|
# This is a hand-coded DSU (decorate-sort-undecorate, or
|
||||||
|
# Schwartzian transform) pattern. The sort key is the raw name
|
||||||
|
# of the file as specifed on the #include line (including the
|
||||||
|
# " or <, since that may affect what file is found), which lets
|
||||||
|
# us keep the sort order constant regardless of whether the file
|
||||||
|
# is actually found in a Repository or locally.
|
||||||
nodes = []
|
nodes = []
|
||||||
source_dir = node.get_dir()
|
source_dir = node.get_dir()
|
||||||
|
if callable(path):
|
||||||
|
path = path()
|
||||||
for include in includes:
|
for include in includes:
|
||||||
n, i = self.find_include(include, source_dir, path)
|
n, i = self.find_include(include, source_dir, path)
|
||||||
|
|
||||||
if not n is None:
|
if n is None:
|
||||||
nodes.append(n)
|
|
||||||
else:
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
||||||
"No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
|
"No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
|
||||||
|
else:
|
||||||
|
sortkey = self.sort_key(include)
|
||||||
|
nodes.append((sortkey, n))
|
||||||
|
|
||||||
# Schwartzian transform from the Python FAQ Wizard
|
nodes.sort()
|
||||||
def st(List, Metric):
|
nodes = map(lambda pair: pair[1], nodes)
|
||||||
def pairing(element, M = Metric):
|
return nodes
|
||||||
return (M(element), element)
|
|
||||||
def stripit(pair):
|
|
||||||
return pair[1]
|
|
||||||
paired = map(pairing, List)
|
|
||||||
paired.sort()
|
|
||||||
return map(stripit, paired)
|
|
||||||
|
|
||||||
def normalize(node):
|
|
||||||
# We don't want the order of includes to be
|
|
||||||
# modified by case changes on case insensitive OSes, so
|
|
||||||
# normalize the case of the filename here:
|
|
||||||
# (see test/win32pathmadness.py for a test of this)
|
|
||||||
return SCons.Node.FS._my_normcase(str(node))
|
|
||||||
|
|
||||||
transformed = st(nodes, normalize)
|
|
||||||
# print "Classic: " + str(node) + " => " + str(map(lambda x: str(x),list(transformed)))
|
|
||||||
return transformed
|
|
||||||
|
|
||||||
class ClassicCPP(Classic):
|
class ClassicCPP(Classic):
|
||||||
"""
|
"""
|
||||||
|
@ -329,11 +393,13 @@ class ClassicCPP(Classic):
|
||||||
"""
|
"""
|
||||||
def find_include(self, include, source_dir, path):
|
def find_include(self, include, source_dir, path):
|
||||||
if include[0] == '"':
|
if include[0] == '"':
|
||||||
n = SCons.Node.FS.find_file(include[1],
|
paths = (source_dir,) + tuple(path)
|
||||||
(source_dir,) + path,
|
|
||||||
self.fs.File)
|
|
||||||
else:
|
else:
|
||||||
n = SCons.Node.FS.find_file(include[1],
|
paths = tuple(path) + (source_dir,)
|
||||||
path + (source_dir,),
|
|
||||||
self.fs.File)
|
n = SCons.Node.FS.find_file(include[1], paths)
|
||||||
|
|
||||||
return n, include[1]
|
return n, include[1]
|
||||||
|
|
||||||
|
def sort_key(self, include):
|
||||||
|
return SCons.Node.FS._my_normcase(string.join(include))
|
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,7 @@ files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,7 +28,7 @@ files.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Script/SConscript.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Script/SConscript.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons
|
import SCons
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
|
@ -42,7 +42,7 @@ import SCons.Node.FS
|
||||||
import SCons.Options
|
import SCons.Options
|
||||||
import SCons.Platform
|
import SCons.Platform
|
||||||
import SCons.SConf
|
import SCons.SConf
|
||||||
import SCons.Script
|
import SCons.Script.Main
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
@ -55,26 +55,19 @@ import traceback
|
||||||
import types
|
import types
|
||||||
import UserList
|
import UserList
|
||||||
|
|
||||||
|
# The following variables used to live in this module. Some
|
||||||
|
# SConscript files out there may have referred to them directly as
|
||||||
|
# SCons.Script.SConscript.*. This is now supported by some special
|
||||||
|
# handling towards the bottom of the SConscript.__init__.py module.
|
||||||
|
#Arguments = {}
|
||||||
|
#ArgList = []
|
||||||
|
#BuildTargets = TargetList()
|
||||||
|
#CommandLineTargets = []
|
||||||
|
#DefaultTargets = []
|
||||||
|
|
||||||
launch_dir = os.path.abspath(os.curdir)
|
launch_dir = os.path.abspath(os.curdir)
|
||||||
|
|
||||||
def do_nothing(text): pass
|
GlobalDict = None
|
||||||
HelpFunction = do_nothing
|
|
||||||
|
|
||||||
Arguments = {}
|
|
||||||
ArgList = []
|
|
||||||
CommandLineTargets = []
|
|
||||||
DefaultCalled = None
|
|
||||||
DefaultTargets = []
|
|
||||||
GlobalDict = {}
|
|
||||||
|
|
||||||
class TargetList(UserList.UserList):
|
|
||||||
def _do_nothing(self, *args, **kw):
|
|
||||||
pass
|
|
||||||
def _add_Default(self, list):
|
|
||||||
self.extend(list)
|
|
||||||
def _clear(self):
|
|
||||||
del self[:]
|
|
||||||
BuildTargets = TargetList()
|
|
||||||
|
|
||||||
# global exports set by Export():
|
# global exports set by Export():
|
||||||
global_exports = {}
|
global_exports = {}
|
||||||
|
@ -82,29 +75,21 @@ global_exports = {}
|
||||||
# chdir flag
|
# chdir flag
|
||||||
sconscript_chdir = 1
|
sconscript_chdir = 1
|
||||||
|
|
||||||
# will be set to 1, if we are reading a SConscript
|
|
||||||
sconscript_reading = 0
|
|
||||||
|
|
||||||
def _scons_add_args(alist):
|
|
||||||
for arg in alist:
|
|
||||||
a, b = string.split(arg, '=', 1)
|
|
||||||
Arguments[a] = b
|
|
||||||
ArgList.append((a, b))
|
|
||||||
|
|
||||||
def _scons_add_targets(tlist):
|
|
||||||
if tlist:
|
|
||||||
CommandLineTargets.extend(tlist)
|
|
||||||
BuildTargets.extend(tlist)
|
|
||||||
BuildTargets._add_Default = BuildTargets._do_nothing
|
|
||||||
BuildTargets._clear = BuildTargets._do_nothing
|
|
||||||
|
|
||||||
def get_calling_namespaces():
|
def get_calling_namespaces():
|
||||||
"""Return the locals and globals for the function that called
|
"""Return the locals and globals for the function that called
|
||||||
into this module in the current callstack."""
|
into this module in the current call stack."""
|
||||||
try: 1/0
|
try: 1/0
|
||||||
except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame
|
except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame
|
||||||
|
|
||||||
while frame.f_globals.get("__name__") == __name__: frame = frame.f_back
|
# Find the first frame that *isn't* from this file. This means
|
||||||
|
# that we expect all of the SCons frames that implement an Export()
|
||||||
|
# or SConscript() call to be in this file, so that we can identify
|
||||||
|
# the first non-Script.SConscript frame as the user's local calling
|
||||||
|
# environment, and the locals and globals dictionaries from that
|
||||||
|
# frame as the calling namespaces. See the comment below preceding
|
||||||
|
# the DefaultEnvironmentCall block for even more explanation.
|
||||||
|
while frame.f_globals.get("__name__") == __name__:
|
||||||
|
frame = frame.f_back
|
||||||
|
|
||||||
return frame.f_locals, frame.f_globals
|
return frame.f_locals, frame.f_globals
|
||||||
|
|
||||||
|
@ -130,22 +115,21 @@ def compute_exports(exports):
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
|
|
||||||
class Frame:
|
class Frame:
|
||||||
"""A frame on the SConstruct/SConscript call stack"""
|
"""A frame on the SConstruct/SConscript call stack"""
|
||||||
def __init__(self, exports, sconscript):
|
def __init__(self, fs, exports, sconscript):
|
||||||
self.globals = BuildDefaultGlobals()
|
self.globals = BuildDefaultGlobals()
|
||||||
self.retval = None
|
self.retval = None
|
||||||
self.prev_dir = SCons.Node.FS.default_fs.getcwd()
|
self.prev_dir = fs.getcwd()
|
||||||
self.exports = compute_exports(exports) # exports from the calling SConscript
|
self.exports = compute_exports(exports) # exports from the calling SConscript
|
||||||
# make sure the sconscript attr is a Node.
|
# make sure the sconscript attr is a Node.
|
||||||
if isinstance(sconscript, SCons.Node.Node):
|
if isinstance(sconscript, SCons.Node.Node):
|
||||||
self.sconscript = sconscript
|
self.sconscript = sconscript
|
||||||
else:
|
else:
|
||||||
self.sconscript = SCons.Node.FS.default_fs.File(str(sconscript))
|
self.sconscript = fs.File(str(sconscript))
|
||||||
|
|
||||||
# the SConstruct/SConscript call stack:
|
# the SConstruct/SConscript call stack:
|
||||||
stack = []
|
call_stack = []
|
||||||
|
|
||||||
# For documentation on the methods in this file, see the scons man-page
|
# For documentation on the methods in this file, see the scons man-page
|
||||||
|
|
||||||
|
@ -154,14 +138,17 @@ def Return(*vars):
|
||||||
try:
|
try:
|
||||||
for var in vars:
|
for var in vars:
|
||||||
for v in string.split(var):
|
for v in string.split(var):
|
||||||
retval.append(stack[-1].globals[v])
|
retval.append(call_stack[-1].globals[v])
|
||||||
except KeyError, x:
|
except KeyError, x:
|
||||||
raise SCons.Errors.UserError, "Return of non-existent variable '%s'"%x
|
raise SCons.Errors.UserError, "Return of non-existent variable '%s'"%x
|
||||||
|
|
||||||
if len(retval) == 1:
|
if len(retval) == 1:
|
||||||
stack[-1].retval = retval[0]
|
call_stack[-1].retval = retval[0]
|
||||||
else:
|
else:
|
||||||
stack[-1].retval = tuple(retval)
|
call_stack[-1].retval = tuple(retval)
|
||||||
|
|
||||||
|
|
||||||
|
stack_bottom = '% Stack boTTom %' # hard to define a variable w/this name :)
|
||||||
|
|
||||||
def _SConscript(fs, *files, **kw):
|
def _SConscript(fs, *files, **kw):
|
||||||
top = fs.Top
|
top = fs.Top
|
||||||
|
@ -171,13 +158,12 @@ def _SConscript(fs, *files, **kw):
|
||||||
# evaluate each SConscript file
|
# evaluate each SConscript file
|
||||||
results = []
|
results = []
|
||||||
for fn in files:
|
for fn in files:
|
||||||
stack.append(Frame(exports,fn))
|
call_stack.append(Frame(fs, exports, fn))
|
||||||
old_sys_path = sys.path
|
old_sys_path = sys.path
|
||||||
try:
|
try:
|
||||||
global sconscript_reading
|
SCons.Script.sconscript_reading = SCons.Script.sconscript_reading + 1
|
||||||
sconscript_reading = 1
|
|
||||||
if fn == "-":
|
if fn == "-":
|
||||||
exec sys.stdin in stack[-1].globals
|
exec sys.stdin in call_stack[-1].globals
|
||||||
else:
|
else:
|
||||||
if isinstance(fn, SCons.Node.Node):
|
if isinstance(fn, SCons.Node.Node):
|
||||||
f = fn
|
f = fn
|
||||||
|
@ -190,17 +176,17 @@ def _SConscript(fs, *files, **kw):
|
||||||
# fs match so we can open the SConscript.
|
# fs match so we can open the SConscript.
|
||||||
fs.chdir(top, change_os_dir=1)
|
fs.chdir(top, change_os_dir=1)
|
||||||
if f.rexists():
|
if f.rexists():
|
||||||
_file_ = open(f.rstr(), "r")
|
_file_ = open(f.rfile().get_abspath(), "r")
|
||||||
elif f.has_src_builder():
|
elif f.has_src_builder():
|
||||||
# The SConscript file apparently exists in a source
|
# The SConscript file apparently exists in a source
|
||||||
# code management system. Build it, but then clear
|
# code management system. Build it, but then clear
|
||||||
# the builder so that it doesn't get built *again*
|
# the builder so that it doesn't get built *again*
|
||||||
# during the actual build phase.
|
# during the actual build phase.
|
||||||
f.build()
|
f.build()
|
||||||
|
f.built()
|
||||||
f.builder_set(None)
|
f.builder_set(None)
|
||||||
s = str(f)
|
if f.exists():
|
||||||
if os.path.exists(s):
|
_file_ = open(f.get_abspath(), "r")
|
||||||
_file_ = open(s, "r")
|
|
||||||
if _file_:
|
if _file_:
|
||||||
# Chdir to the SConscript directory. Use a path
|
# Chdir to the SConscript directory. Use a path
|
||||||
# name relative to the SConstruct file so that if
|
# name relative to the SConstruct file so that if
|
||||||
|
@ -212,7 +198,18 @@ def _SConscript(fs, *files, **kw):
|
||||||
# where the SConstruct and SConscript files might be
|
# where the SConstruct and SConscript files might be
|
||||||
# in different Repositories. For now, cross that
|
# in different Repositories. For now, cross that
|
||||||
# bridge when someone comes to it.
|
# bridge when someone comes to it.
|
||||||
ldir = fs.Dir(f.dir.get_path(sd))
|
try:
|
||||||
|
src_dir = kw['src_dir']
|
||||||
|
except KeyError:
|
||||||
|
ldir = fs.Dir(f.dir.get_path(sd))
|
||||||
|
else:
|
||||||
|
ldir = fs.Dir(src_dir)
|
||||||
|
if not ldir.is_under(f.dir):
|
||||||
|
# They specified a source directory, but
|
||||||
|
# it's above the SConscript directory.
|
||||||
|
# Do the sensible thing and just use the
|
||||||
|
# SConcript directory.
|
||||||
|
ldir = fs.Dir(f.dir.get_path(sd))
|
||||||
try:
|
try:
|
||||||
fs.chdir(ldir, change_os_dir=sconscript_chdir)
|
fs.chdir(ldir, change_os_dir=sconscript_chdir)
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -223,6 +220,7 @@ def _SConscript(fs, *files, **kw):
|
||||||
# interpret the stuff within the SConscript file
|
# interpret the stuff within the SConscript file
|
||||||
# relative to where we are logically.
|
# relative to where we are logically.
|
||||||
fs.chdir(ldir, change_os_dir=0)
|
fs.chdir(ldir, change_os_dir=0)
|
||||||
|
# TODO Not sure how to handle src_dir here
|
||||||
os.chdir(f.rfile().dir.get_abspath())
|
os.chdir(f.rfile().dir.get_abspath())
|
||||||
|
|
||||||
# Append the SConscript directory to the beginning
|
# Append the SConscript directory to the beginning
|
||||||
|
@ -230,21 +228,32 @@ def _SConscript(fs, *files, **kw):
|
||||||
# directory can be easily imported.
|
# directory can be easily imported.
|
||||||
sys.path = [ f.dir.get_abspath() ] + sys.path
|
sys.path = [ f.dir.get_abspath() ] + sys.path
|
||||||
|
|
||||||
# This is the magic line that actually reads up and
|
# This is the magic line that actually reads up
|
||||||
# executes the stuff in the SConscript file. We
|
# and executes the stuff in the SConscript file.
|
||||||
# look for the "exec _file_ " from the beginning
|
# The locals for this frame contain the special
|
||||||
# of this line to find the right stack frame (the
|
# bottom-of-the-stack marker so that any
|
||||||
# next one) describing the SConscript file and line
|
# exceptions that occur when processing this
|
||||||
# number that creates a node.
|
# SConscript can base the printed frames at this
|
||||||
exec _file_ in stack[-1].globals
|
# level and not show SCons internals as well.
|
||||||
|
call_stack[-1].globals.update({stack_bottom:1})
|
||||||
|
old_file = call_stack[-1].globals.get('__file__')
|
||||||
|
try:
|
||||||
|
del call_stack[-1].globals['__file__']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
exec _file_ in call_stack[-1].globals
|
||||||
|
finally:
|
||||||
|
if old_file is not None:
|
||||||
|
call_stack[-1].globals.update({__file__:old_file})
|
||||||
else:
|
else:
|
||||||
SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning,
|
SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning,
|
||||||
"Ignoring missing SConscript '%s'" % f.path)
|
"Ignoring missing SConscript '%s'" % f.path)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
sconscript_reading = 0
|
SCons.Script.sconscript_reading = SCons.Script.sconscript_reading - 1
|
||||||
sys.path = old_sys_path
|
sys.path = old_sys_path
|
||||||
frame = stack.pop()
|
frame = call_stack.pop()
|
||||||
try:
|
try:
|
||||||
fs.chdir(frame.prev_dir, change_os_dir=sconscript_chdir)
|
fs.chdir(frame.prev_dir, change_os_dir=sconscript_chdir)
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -252,7 +261,9 @@ def _SConscript(fs, *files, **kw):
|
||||||
# Repository directory. Like above, we do this
|
# Repository directory. Like above, we do this
|
||||||
# directly.
|
# directly.
|
||||||
fs.chdir(frame.prev_dir, change_os_dir=0)
|
fs.chdir(frame.prev_dir, change_os_dir=0)
|
||||||
os.chdir(frame.prev_dir.rdir().get_abspath())
|
rdir = frame.prev_dir.rdir()
|
||||||
|
rdir._create() # Make sure there's a directory there.
|
||||||
|
os.chdir(rdir.get_abspath())
|
||||||
|
|
||||||
results.append(frame.retval)
|
results.append(frame.retval)
|
||||||
|
|
||||||
|
@ -262,51 +273,41 @@ def _SConscript(fs, *files, **kw):
|
||||||
else:
|
else:
|
||||||
return tuple(results)
|
return tuple(results)
|
||||||
|
|
||||||
def is_our_exec_statement(line):
|
|
||||||
return not line is None and line[:12] == "exec _file_ "
|
|
||||||
|
|
||||||
def SConscript_exception(file=sys.stderr):
|
def SConscript_exception(file=sys.stderr):
|
||||||
"""Print an exception stack trace just for the SConscript file(s).
|
"""Print an exception stack trace just for the SConscript file(s).
|
||||||
This will show users who have Python errors where the problem is,
|
This will show users who have Python errors where the problem is,
|
||||||
without cluttering the output with all of the internal calls leading
|
without cluttering the output with all of the internal calls leading
|
||||||
up to where we exec the SConscript."""
|
up to where we exec the SConscript."""
|
||||||
exc_type, exc_value, exc_tb = sys.exc_info()
|
exc_type, exc_value, exc_tb = sys.exc_info()
|
||||||
stack = traceback.extract_tb(exc_tb)
|
tb = exc_tb
|
||||||
last_text = ""
|
while tb and not tb.tb_frame.f_locals.has_key(stack_bottom):
|
||||||
found = 0
|
tb = tb.tb_next
|
||||||
i = 0
|
if not tb:
|
||||||
for frame in stack:
|
|
||||||
if is_our_exec_statement(last_text):
|
|
||||||
found = 1
|
|
||||||
break
|
|
||||||
i = i + 1
|
|
||||||
last_text = frame[3]
|
|
||||||
if not found:
|
|
||||||
# We did not find our exec statement, so this was actually a bug
|
# We did not find our exec statement, so this was actually a bug
|
||||||
# in SCons itself. Show the whole stack.
|
# in SCons itself. Show the whole stack.
|
||||||
i = 0
|
tb = exc_tb
|
||||||
type = str(exc_type)
|
stack = traceback.extract_tb(tb)
|
||||||
if type[:11] == "exceptions.":
|
try:
|
||||||
type = type[11:]
|
type = exc_type.__name__
|
||||||
|
except AttributeError:
|
||||||
|
type = str(exc_type)
|
||||||
|
if type[:11] == "exceptions.":
|
||||||
|
type = type[11:]
|
||||||
file.write('%s: %s:\n' % (type, exc_value))
|
file.write('%s: %s:\n' % (type, exc_value))
|
||||||
for fname, line, func, text in stack[i:]:
|
for fname, line, func, text in stack:
|
||||||
file.write(' File "%s", line %d:\n' % (fname, line))
|
file.write(' File "%s", line %d:\n' % (fname, line))
|
||||||
file.write(' %s\n' % text)
|
file.write(' %s\n' % text)
|
||||||
|
|
||||||
def annotate(node):
|
def annotate(node):
|
||||||
"""Annotate a node with the stack frame describing the
|
"""Annotate a node with the stack frame describing the
|
||||||
SConscript file and line number that created it."""
|
SConscript file and line number that created it."""
|
||||||
stack = traceback.extract_stack()
|
tb = sys.exc_info()[2]
|
||||||
last_text = ""
|
while tb and not tb.tb_frame.f_locals.has_key(stack_bottom):
|
||||||
for frame in stack:
|
tb = tb.tb_next
|
||||||
# If the script text of the previous frame begins with the
|
if not tb:
|
||||||
# magic "exec _file_ " string, then this frame describes the
|
# We did not find any exec of an SConscript file: what?!
|
||||||
# SConscript file and line number that caused this node to be
|
raise SCons.Errors.InternalError, "could not find SConscript stack frame"
|
||||||
# created. Record the tuple and carry on.
|
node.creator = traceback.extract_stack(tb)[0]
|
||||||
if is_our_exec_statement(last_text):
|
|
||||||
node.creator = frame
|
|
||||||
return
|
|
||||||
last_text = frame[3]
|
|
||||||
|
|
||||||
# The following line would cause each Node to be annotated using the
|
# The following line would cause each Node to be annotated using the
|
||||||
# above function. Unfortunately, this is a *huge* performance hit, so
|
# above function. Unfortunately, this is a *huge* performance hit, so
|
||||||
|
@ -330,14 +331,20 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
in 'v_major' and 'v_minor', and 0 otherwise."""
|
in 'v_major' and 'v_minor', and 0 otherwise."""
|
||||||
return (major > v_major or (major == v_major and minor > v_minor))
|
return (major > v_major or (major == v_major and minor > v_minor))
|
||||||
|
|
||||||
def _get_major_minor(self, version_string):
|
def _get_major_minor_revision(self, version_string):
|
||||||
"""Split a version string into major and minor parts. This
|
"""Split a version string into major, minor and (optionally)
|
||||||
is complicated by the fact that a version string can be something
|
revision parts.
|
||||||
like 3.2b1."""
|
|
||||||
|
This is complicated by the fact that a version string can be
|
||||||
|
something like 3.2b1."""
|
||||||
version = string.split(string.split(version_string, ' ')[0], '.')
|
version = string.split(string.split(version_string, ' ')[0], '.')
|
||||||
v_major = int(version[0])
|
v_major = int(version[0])
|
||||||
v_minor = int(re.match('\d+', version[1]).group())
|
v_minor = int(re.match('\d+', version[1]).group())
|
||||||
return v_major, v_minor
|
if len(version) >= 3:
|
||||||
|
v_revision = int(re.match('\d+', version[2]).group())
|
||||||
|
else:
|
||||||
|
v_revision = 0
|
||||||
|
return v_major, v_minor, v_revision
|
||||||
|
|
||||||
def _get_SConscript_filenames(self, ls, kw):
|
def _get_SConscript_filenames(self, ls, kw):
|
||||||
"""
|
"""
|
||||||
|
@ -392,6 +399,7 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
src_dir = kw.get('src_dir')
|
src_dir = kw.get('src_dir')
|
||||||
if not src_dir:
|
if not src_dir:
|
||||||
src_dir, fname = os.path.split(str(files[0]))
|
src_dir, fname = os.path.split(str(files[0]))
|
||||||
|
files = [os.path.join(str(build_dir), fname)]
|
||||||
else:
|
else:
|
||||||
if not isinstance(src_dir, SCons.Node.Node):
|
if not isinstance(src_dir, SCons.Node.Node):
|
||||||
src_dir = self.fs.Dir(src_dir)
|
src_dir = self.fs.Dir(src_dir)
|
||||||
|
@ -401,11 +409,11 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
if fn.is_under(src_dir):
|
if fn.is_under(src_dir):
|
||||||
# Get path relative to the source directory.
|
# Get path relative to the source directory.
|
||||||
fname = fn.get_path(src_dir)
|
fname = fn.get_path(src_dir)
|
||||||
|
files = [os.path.join(str(build_dir), fname)]
|
||||||
else:
|
else:
|
||||||
# Fast way to only get the terminal path component of a Node.
|
files = [fn.abspath]
|
||||||
fname = fn.get_path(fn.dir)
|
kw['src_dir'] = build_dir
|
||||||
self.fs.BuildDir(build_dir, src_dir, duplicate)
|
self.fs.BuildDir(build_dir, src_dir, duplicate)
|
||||||
files = [os.path.join(str(build_dir), fname)]
|
|
||||||
|
|
||||||
return (files, exports)
|
return (files, exports)
|
||||||
|
|
||||||
|
@ -415,40 +423,35 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
# as global functions.
|
# as global functions.
|
||||||
#
|
#
|
||||||
|
|
||||||
def Default(self, *targets):
|
def Configure(self, *args, **kw):
|
||||||
global DefaultCalled
|
if not SCons.Script.sconscript_reading:
|
||||||
global DefaultTargets
|
raise SCons.Errors.UserError, "Calling Configure from Builders is not supported."
|
||||||
DefaultCalled = 1
|
kw['_depth'] = kw.get('_depth', 0) + 1
|
||||||
for t in targets:
|
return apply(SCons.Environment.Base.Configure, (self,)+args, kw)
|
||||||
if t is None:
|
|
||||||
# Delete the elements from the list in-place, don't
|
|
||||||
# reassign an empty list to DefaultTargets, so that the
|
|
||||||
# DEFAULT_TARGETS variable will still point to the
|
|
||||||
# same object we point to.
|
|
||||||
del DefaultTargets[:]
|
|
||||||
BuildTargets._clear()
|
|
||||||
elif isinstance(t, SCons.Node.Node):
|
|
||||||
DefaultTargets.append(t)
|
|
||||||
BuildTargets._add_Default([t])
|
|
||||||
else:
|
|
||||||
nodes = self.arg2nodes(t, self.fs.Entry)
|
|
||||||
DefaultTargets.extend(nodes)
|
|
||||||
BuildTargets._add_Default(nodes)
|
|
||||||
|
|
||||||
def EnsureSConsVersion(self, major, minor):
|
def Default(self, *targets):
|
||||||
|
SCons.Script._Set_Default_Targets(self, targets)
|
||||||
|
|
||||||
|
def EnsureSConsVersion(self, major, minor, revision=0):
|
||||||
"""Exit abnormally if the SCons version is not late enough."""
|
"""Exit abnormally if the SCons version is not late enough."""
|
||||||
v_major, v_minor = self._get_major_minor(SCons.__version__)
|
scons_ver = self._get_major_minor_revision(SCons.__version__)
|
||||||
if self._exceeds_version(major, minor, v_major, v_minor):
|
if scons_ver < (major, minor, revision):
|
||||||
print "SCons %d.%d or greater required, but you have SCons %s" %(major,minor,SCons.__version__)
|
if revision:
|
||||||
|
scons_ver_string = '%d.%d.%d' % (major, minor, revision)
|
||||||
|
else:
|
||||||
|
scons_ver_string = '%d.%d' % (major, minor)
|
||||||
|
print "SCons %s or greater required, but you have SCons %s" % \
|
||||||
|
(scons_ver_string, SCons.__version__)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
def EnsurePythonVersion(self, major, minor):
|
def EnsurePythonVersion(self, major, minor):
|
||||||
"""Exit abnormally if the Python version is not late enough."""
|
"""Exit abnormally if the Python version is not late enough."""
|
||||||
try:
|
try:
|
||||||
v_major, v_minor, v_micro, release, serial = sys.version_info
|
v_major, v_minor, v_micro, release, serial = sys.version_info
|
||||||
|
python_ver = (v_major, v_minor)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
v_major, v_minor = self._get_major_minor(sys.version)
|
python_ver = self._get_major_minor_revision(sys.version)[:2]
|
||||||
if self._exceeds_version(major, minor, v_major, v_minor):
|
if python_ver < (major, minor):
|
||||||
v = string.split(sys.version, " ", 1)[0]
|
v = string.split(sys.version, " ", 1)[0]
|
||||||
print "Python %d.%d or greater required, but you have Python %s" %(major,minor,v)
|
print "Python %d.%d or greater required, but you have Python %s" %(major,minor,v)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
@ -466,30 +469,39 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
|
|
||||||
def GetOption(self, name):
|
def GetOption(self, name):
|
||||||
name = self.subst(name)
|
name = self.subst(name)
|
||||||
return SCons.Script.ssoptions.get(name)
|
return SCons.Script.Main.ssoptions.get(name)
|
||||||
|
|
||||||
def Help(self, text):
|
def Help(self, text):
|
||||||
text = self.subst(text, raw=1)
|
text = self.subst(text, raw=1)
|
||||||
HelpFunction(text)
|
SCons.Script.HelpFunction(text)
|
||||||
|
|
||||||
def Import(self, *vars):
|
def Import(self, *vars):
|
||||||
try:
|
try:
|
||||||
|
frame = call_stack[-1]
|
||||||
|
globals = frame.globals
|
||||||
|
exports = frame.exports
|
||||||
for var in vars:
|
for var in vars:
|
||||||
var = self.Split(var)
|
var = self.Split(var)
|
||||||
for v in var:
|
for v in var:
|
||||||
if v == '*':
|
if v == '*':
|
||||||
stack[-1].globals.update(global_exports)
|
globals.update(global_exports)
|
||||||
stack[-1].globals.update(stack[-1].exports)
|
globals.update(exports)
|
||||||
else:
|
else:
|
||||||
if stack[-1].exports.has_key(v):
|
if exports.has_key(v):
|
||||||
stack[-1].globals[v] = stack[-1].exports[v]
|
globals[v] = exports[v]
|
||||||
else:
|
else:
|
||||||
stack[-1].globals[v] = global_exports[v]
|
globals[v] = global_exports[v]
|
||||||
except KeyError,x:
|
except KeyError,x:
|
||||||
raise SCons.Errors.UserError, "Import of non-existent variable '%s'"%x
|
raise SCons.Errors.UserError, "Import of non-existent variable '%s'"%x
|
||||||
|
|
||||||
def SConscript(self, *ls, **kw):
|
def SConscript(self, *ls, **kw):
|
||||||
ls = map(lambda l, self=self: self.subst(l), ls)
|
def subst_element(x, subst=self.subst):
|
||||||
|
if SCons.Util.is_List(x):
|
||||||
|
x = map(subst, x)
|
||||||
|
else:
|
||||||
|
x = subst(x)
|
||||||
|
return x
|
||||||
|
ls = map(subst_element, ls)
|
||||||
subst_kw = {}
|
subst_kw = {}
|
||||||
for key, val in kw.items():
|
for key, val in kw.items():
|
||||||
if SCons.Util.is_String(val):
|
if SCons.Util.is_String(val):
|
||||||
|
@ -504,8 +516,8 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
subst_kw[key] = val
|
subst_kw[key] = val
|
||||||
|
|
||||||
files, exports = self._get_SConscript_filenames(ls, subst_kw)
|
files, exports = self._get_SConscript_filenames(ls, subst_kw)
|
||||||
|
subst_kw['exports'] = exports
|
||||||
return apply(_SConscript, [self.fs,] + files, {'exports' : exports})
|
return apply(_SConscript, [self.fs,] + files, subst_kw)
|
||||||
|
|
||||||
def SConscriptChdir(self, flag):
|
def SConscriptChdir(self, flag):
|
||||||
global sconscript_chdir
|
global sconscript_chdir
|
||||||
|
@ -513,48 +525,34 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
|
|
||||||
def SetOption(self, name, value):
|
def SetOption(self, name, value):
|
||||||
name = self.subst(name)
|
name = self.subst(name)
|
||||||
SCons.Script.ssoptions.set(name, value)
|
SCons.Script.Main.ssoptions.set(name, value)
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
SCons.Environment.Environment = SConsEnvironment
|
SCons.Environment.Environment = SConsEnvironment
|
||||||
|
|
||||||
def Options(files=None, args=Arguments):
|
def Configure(*args, **kw):
|
||||||
return SCons.Options.Options(files, args)
|
if not SCons.Script.sconscript_reading:
|
||||||
|
raise SCons.Errors.UserError, "Calling Configure from Builders is not supported."
|
||||||
def SetBuildSignatureType(type):
|
kw['_depth'] = 1
|
||||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
|
return apply(SCons.SConf.SConf, args, kw)
|
||||||
"The SetBuildSignatureType() function has been deprecated;\n" +\
|
|
||||||
"\tuse the TargetSignatures() function instead.")
|
|
||||||
SCons.Defaults.DefaultEnvironment().TargetSignatures(type)
|
|
||||||
|
|
||||||
def SetContentSignatureType(type):
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
|
|
||||||
"The SetContentSignatureType() function has been deprecated;\n" +\
|
|
||||||
"\tuse the SourceSignatures() function instead.")
|
|
||||||
SCons.Defaults.DefaultEnvironment().SourceSignatures(type)
|
|
||||||
|
|
||||||
def GetJobs():
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
|
|
||||||
"The GetJobs() function has been deprecated;\n" +\
|
|
||||||
"\tuse GetOption('num_jobs') instead.")
|
|
||||||
|
|
||||||
return GetOption('num_jobs')
|
|
||||||
|
|
||||||
def SetJobs(num):
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
|
|
||||||
"The SetJobs() function has been deprecated;\n" +\
|
|
||||||
"\tuse SetOption('num_jobs', num) instead.")
|
|
||||||
SetOption('num_jobs', num)
|
|
||||||
|
|
||||||
def ParseConfig(env, command, function=None):
|
|
||||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
|
|
||||||
"The ParseConfig() function has been deprecated;\n" +\
|
|
||||||
"\tuse the env.ParseConfig() method instead.")
|
|
||||||
return env.ParseConfig(command, function)
|
|
||||||
|
|
||||||
|
# It's very important that the DefaultEnvironmentCall() class stay in this
|
||||||
|
# file, with the get_calling_namespaces() function, the compute_exports()
|
||||||
|
# function, the Frame class and the SConsEnvironment.Export() method.
|
||||||
|
# These things make up the calling stack leading up to the actual global
|
||||||
|
# Export() or SConscript() call that the user issued. We want to allow
|
||||||
|
# users to export local variables that they define, like so:
|
||||||
#
|
#
|
||||||
|
# def func():
|
||||||
|
# x = 1
|
||||||
|
# Export('x')
|
||||||
|
#
|
||||||
|
# To support this, the get_calling_namespaces() function assumes that
|
||||||
|
# the *first* stack frame that's not from this file is the local frame
|
||||||
|
# for the Export() or SConscript() call.
|
||||||
|
|
||||||
_DefaultEnvironmentProxy = None
|
_DefaultEnvironmentProxy = None
|
||||||
|
|
||||||
def get_DefaultEnvironmentProxy():
|
def get_DefaultEnvironmentProxy():
|
||||||
|
@ -573,92 +571,17 @@ class DefaultEnvironmentCall:
|
||||||
thereby prevent expansion of construction variables (since from
|
thereby prevent expansion of construction variables (since from
|
||||||
the user's point of view this was called as a global function,
|
the user's point of view this was called as a global function,
|
||||||
with no associated construction environment)."""
|
with no associated construction environment)."""
|
||||||
def __init__(self, method_name):
|
def __init__(self, method_name, subst=0):
|
||||||
self.method_name = method_name
|
self.method_name = method_name
|
||||||
|
if subst:
|
||||||
|
self.factory = SCons.Defaults.DefaultEnvironment
|
||||||
|
else:
|
||||||
|
self.factory = get_DefaultEnvironmentProxy
|
||||||
def __call__(self, *args, **kw):
|
def __call__(self, *args, **kw):
|
||||||
proxy = get_DefaultEnvironmentProxy()
|
env = self.factory()
|
||||||
method = getattr(proxy, self.method_name)
|
method = getattr(env, self.method_name)
|
||||||
return apply(method, args, kw)
|
return apply(method, args, kw)
|
||||||
|
|
||||||
# The list of global functions to add to the SConscript name space
|
|
||||||
# that end up calling corresponding methods or Builders in the
|
|
||||||
# DefaultEnvironment().
|
|
||||||
GlobalDefaultEnvironmentFunctions = [
|
|
||||||
# Methods from the SConsEnvironment class, above.
|
|
||||||
'Default',
|
|
||||||
'EnsurePythonVersion',
|
|
||||||
'EnsureSConsVersion',
|
|
||||||
'Exit',
|
|
||||||
'Export',
|
|
||||||
'GetLaunchDir',
|
|
||||||
'GetOption',
|
|
||||||
'Help',
|
|
||||||
'Import',
|
|
||||||
'SConscript',
|
|
||||||
'SConscriptChdir',
|
|
||||||
'SetOption',
|
|
||||||
|
|
||||||
# Methods from the Environment.Base class.
|
|
||||||
'AddPostAction',
|
|
||||||
'AddPreAction',
|
|
||||||
'Alias',
|
|
||||||
'AlwaysBuild',
|
|
||||||
'BuildDir',
|
|
||||||
'CacheDir',
|
|
||||||
'Clean',
|
|
||||||
'Command',
|
|
||||||
'Depends',
|
|
||||||
'Dir',
|
|
||||||
'Execute',
|
|
||||||
'File',
|
|
||||||
'FindFile',
|
|
||||||
'Flatten',
|
|
||||||
'GetBuildPath',
|
|
||||||
'Ignore',
|
|
||||||
'Install',
|
|
||||||
'InstallAs',
|
|
||||||
'Literal',
|
|
||||||
'Local',
|
|
||||||
'Precious',
|
|
||||||
'Repository',
|
|
||||||
'SConsignFile',
|
|
||||||
'SideEffect',
|
|
||||||
'SourceCode',
|
|
||||||
'SourceSignatures',
|
|
||||||
'Split',
|
|
||||||
'TargetSignatures',
|
|
||||||
'Value',
|
|
||||||
]
|
|
||||||
|
|
||||||
GlobalDefaultBuilders = [
|
|
||||||
# Supported builders.
|
|
||||||
'CFile',
|
|
||||||
'CXXFile',
|
|
||||||
'DVI',
|
|
||||||
'Jar',
|
|
||||||
'Java',
|
|
||||||
'JavaH',
|
|
||||||
'Library',
|
|
||||||
'M4',
|
|
||||||
'MSVSProject',
|
|
||||||
'Object',
|
|
||||||
'PCH',
|
|
||||||
'PDF',
|
|
||||||
'PostScript',
|
|
||||||
'Program',
|
|
||||||
'RES',
|
|
||||||
'RMIC',
|
|
||||||
'SharedLibrary',
|
|
||||||
'SharedObject',
|
|
||||||
'StaticLibrary',
|
|
||||||
'StaticObject',
|
|
||||||
'Tar',
|
|
||||||
'TypeLibrary',
|
|
||||||
'Zip',
|
|
||||||
]
|
|
||||||
|
|
||||||
for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
|
|
||||||
GlobalDict[name] = DefaultEnvironmentCall(name)
|
|
||||||
|
|
||||||
def BuildDefaultGlobals():
|
def BuildDefaultGlobals():
|
||||||
"""
|
"""
|
||||||
|
@ -666,52 +589,15 @@ def BuildDefaultGlobals():
|
||||||
SConstruct and SConscript files.
|
SConstruct and SConscript files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
globals = {
|
global GlobalDict
|
||||||
# Global functions that don't get executed through the
|
if GlobalDict is None:
|
||||||
# default Environment.
|
GlobalDict = {}
|
||||||
'Action' : SCons.Action.Action,
|
|
||||||
'BoolOption' : SCons.Options.BoolOption,
|
|
||||||
'Builder' : SCons.Builder.Builder,
|
|
||||||
'Configure' : SCons.SConf.SConf,
|
|
||||||
'EnumOption' : SCons.Options.EnumOption,
|
|
||||||
'Environment' : SCons.Environment.Environment,
|
|
||||||
'ListOption' : SCons.Options.ListOption,
|
|
||||||
'Options' : Options,
|
|
||||||
'PackageOption' : SCons.Options.PackageOption,
|
|
||||||
'PathOption' : SCons.Options.PathOption,
|
|
||||||
'Platform' : SCons.Platform.Platform,
|
|
||||||
'Return' : Return,
|
|
||||||
'Scanner' : SCons.Scanner.Base,
|
|
||||||
'Tool' : SCons.Tool.Tool,
|
|
||||||
'WhereIs' : SCons.Util.WhereIs,
|
|
||||||
|
|
||||||
# Action factories.
|
import SCons.Script
|
||||||
'Chmod' : SCons.Defaults.Chmod,
|
d = SCons.Script.__dict__
|
||||||
'Copy' : SCons.Defaults.Copy,
|
def not_a_module(m, d=d, mtype=type(SCons.Script)):
|
||||||
'Delete' : SCons.Defaults.Delete,
|
return type(d[m]) != mtype
|
||||||
'Mkdir' : SCons.Defaults.Mkdir,
|
for m in filter(not_a_module, dir(SCons.Script)):
|
||||||
'Move' : SCons.Defaults.Move,
|
GlobalDict[m] = d[m]
|
||||||
'Touch' : SCons.Defaults.Touch,
|
|
||||||
|
|
||||||
# Other variables we provide.
|
return GlobalDict.copy()
|
||||||
'ARGUMENTS' : Arguments,
|
|
||||||
'ARGLIST' : ArgList,
|
|
||||||
'BUILD_TARGETS' : BuildTargets,
|
|
||||||
'COMMAND_LINE_TARGETS' : CommandLineTargets,
|
|
||||||
'DEFAULT_TARGETS' : DefaultTargets,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Functions we might still convert to Environment methods.
|
|
||||||
globals['CScan'] = SCons.Defaults.CScan
|
|
||||||
globals['DefaultEnvironment'] = SCons.Defaults.DefaultEnvironment
|
|
||||||
|
|
||||||
# Deprecated functions, leave these here for now.
|
|
||||||
globals['GetJobs'] = GetJobs
|
|
||||||
globals['ParseConfig'] = ParseConfig
|
|
||||||
globals['SetBuildSignatureType'] = SetBuildSignatureType
|
|
||||||
globals['SetContentSignatureType'] = SetContentSignatureType
|
|
||||||
globals['SetJobs'] = SetJobs
|
|
||||||
|
|
||||||
globals.update(GlobalDict)
|
|
||||||
|
|
||||||
return globals
|
|
382
scons/scons-local-0.97/SCons/Script/__init__.py
Normal file
382
scons/scons-local-0.97/SCons/Script/__init__.py
Normal file
|
@ -0,0 +1,382 @@
|
||||||
|
"""SCons.Script
|
||||||
|
|
||||||
|
This file implements the main() function used by the scons script.
|
||||||
|
|
||||||
|
Architecturally, this *is* the scons script, and will likely only be
|
||||||
|
called from the external "scons" wrapper. Consequently, anything here
|
||||||
|
should not be, or be considered, part of the build engine. If it's
|
||||||
|
something that we expect other software to want to use, it should go in
|
||||||
|
some other module. If it's specific to the "scons" script invocation,
|
||||||
|
it goes here.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Script/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import time
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
import UserList
|
||||||
|
|
||||||
|
# Special chicken-and-egg handling of the "--debug=memoizer" flag:
|
||||||
|
#
|
||||||
|
# SCons.Memoize contains a metaclass implementation that affects how
|
||||||
|
# the other classes are instantiated. The Memoizer may add shim methods
|
||||||
|
# to classes that have methods that cache computed values in order to
|
||||||
|
# count and report the hits and misses.
|
||||||
|
#
|
||||||
|
# If we wait to enable the Memoization until after we've parsed the
|
||||||
|
# command line options normally, it will be too late, because the Memoizer
|
||||||
|
# will have already analyzed the classes that it's Memoizing and decided
|
||||||
|
# to not add the shims. So we use a special-case, up-front check for
|
||||||
|
# the "--debug=memoizer" flag and enable Memoizer before we import any
|
||||||
|
# of the other modules that use it.
|
||||||
|
|
||||||
|
_args = sys.argv + string.split(os.environ.get('SCONSFLAGS', ''))
|
||||||
|
if "--debug=memoizer" in _args:
|
||||||
|
import SCons.Memoize
|
||||||
|
import SCons.Warnings
|
||||||
|
try:
|
||||||
|
SCons.Memoize.EnableMemoization()
|
||||||
|
except SCons.Warnings.Warning:
|
||||||
|
# Some warning was thrown (inability to --debug=memoizer on
|
||||||
|
# Python 1.5.2 because it doesn't have metaclasses). Arrange
|
||||||
|
# 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)
|
||||||
|
del _args
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
|
import SCons.Builder
|
||||||
|
import SCons.Environment
|
||||||
|
import SCons.Node.FS
|
||||||
|
import SCons.Options
|
||||||
|
import SCons.Platform
|
||||||
|
import SCons.Scanner
|
||||||
|
import SCons.SConf
|
||||||
|
import SCons.Subst
|
||||||
|
import SCons.Tool
|
||||||
|
import SCons.Util
|
||||||
|
import SCons.Defaults
|
||||||
|
|
||||||
|
import Main
|
||||||
|
|
||||||
|
main = Main.main
|
||||||
|
|
||||||
|
# The following are global class definitions and variables that used to
|
||||||
|
# live directly in this module back before 0.96.90, when it contained
|
||||||
|
# a lot of code. Some SConscript files in widely-distributed packages
|
||||||
|
# (Blender is the specific example) actually reached into SCons.Script
|
||||||
|
# directly to use some of these. Rather than break those SConscript
|
||||||
|
# files, we're going to propagate these names into the SCons.Script
|
||||||
|
# namespace here.
|
||||||
|
#
|
||||||
|
# Some of these are commented out because it's *really* unlikely anyone
|
||||||
|
# used them, but we're going to leave the comment here to try to make
|
||||||
|
# it obvious what to do if the situation arises.
|
||||||
|
BuildTask = Main.BuildTask
|
||||||
|
CleanTask = Main.CleanTask
|
||||||
|
QuestionTask = Main.QuestionTask
|
||||||
|
#PrintHelp = Main.PrintHelp
|
||||||
|
OptParser = Main.OptParser
|
||||||
|
SConscriptSettableOptions = Main.SConscriptSettableOptions
|
||||||
|
|
||||||
|
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_tree = Main.print_tree
|
||||||
|
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
|
||||||
|
|
||||||
|
#
|
||||||
|
import SConscript
|
||||||
|
_SConscript = SConscript
|
||||||
|
|
||||||
|
call_stack = _SConscript.call_stack
|
||||||
|
|
||||||
|
#
|
||||||
|
Action = SCons.Action.Action
|
||||||
|
AllowSubstExceptions = SCons.Subst.SetAllowableExceptions
|
||||||
|
BoolOption = SCons.Options.BoolOption
|
||||||
|
Builder = SCons.Builder.Builder
|
||||||
|
Configure = _SConscript.Configure
|
||||||
|
EnumOption = SCons.Options.EnumOption
|
||||||
|
Environment = SCons.Environment.Environment
|
||||||
|
FindPathDirs = SCons.Scanner.FindPathDirs
|
||||||
|
ListOption = SCons.Options.ListOption
|
||||||
|
PackageOption = SCons.Options.PackageOption
|
||||||
|
PathOption = SCons.Options.PathOption
|
||||||
|
Platform = SCons.Platform.Platform
|
||||||
|
Return = _SConscript.Return
|
||||||
|
Scanner = SCons.Scanner.Base
|
||||||
|
Tool = SCons.Tool.Tool
|
||||||
|
WhereIs = SCons.Util.WhereIs
|
||||||
|
|
||||||
|
# Action factories.
|
||||||
|
Chmod = SCons.Defaults.Chmod
|
||||||
|
Copy = SCons.Defaults.Copy
|
||||||
|
Delete = SCons.Defaults.Delete
|
||||||
|
Mkdir = SCons.Defaults.Mkdir
|
||||||
|
Move = SCons.Defaults.Move
|
||||||
|
Touch = SCons.Defaults.Touch
|
||||||
|
|
||||||
|
# Pre-made, public scanners.
|
||||||
|
CScanner = SCons.Tool.CScanner
|
||||||
|
DScanner = SCons.Tool.DScanner
|
||||||
|
DirScanner = SCons.Defaults.DirScanner
|
||||||
|
ProgramScanner = SCons.Tool.ProgramScanner
|
||||||
|
SourceFileScanner = SCons.Tool.SourceFileScanner
|
||||||
|
|
||||||
|
# Functions we might still convert to Environment methods.
|
||||||
|
CScan = SCons.Defaults.CScan
|
||||||
|
DefaultEnvironment = SCons.Defaults.DefaultEnvironment
|
||||||
|
|
||||||
|
# Other variables we provide.
|
||||||
|
class TargetList(UserList.UserList):
|
||||||
|
def _do_nothing(self, *args, **kw):
|
||||||
|
pass
|
||||||
|
def _add_Default(self, list):
|
||||||
|
self.extend(list)
|
||||||
|
def _clear(self):
|
||||||
|
del self[:]
|
||||||
|
|
||||||
|
ARGUMENTS = {}
|
||||||
|
ARGLIST = []
|
||||||
|
BUILD_TARGETS = TargetList()
|
||||||
|
COMMAND_LINE_TARGETS = []
|
||||||
|
DEFAULT_TARGETS = []
|
||||||
|
|
||||||
|
# BUILD_TARGETS can be modified in the SConscript files. If so, we
|
||||||
|
# want to treat the modified BUILD_TARGETS list as if they specified
|
||||||
|
# targets on the command line. To do that, though, we need to know if
|
||||||
|
# BUILD_TARGETS was modified through "official" APIs or by hand. We do
|
||||||
|
# this by updating two lists in parallel, the documented BUILD_TARGETS
|
||||||
|
# list, above, and this internal _build_plus_default targets list which
|
||||||
|
# should only have "official" API changes. Then Script/Main.py can
|
||||||
|
# compare these two afterwards to figure out if the user added their
|
||||||
|
# own targets to BUILD_TARGETS.
|
||||||
|
_build_plus_default = TargetList()
|
||||||
|
|
||||||
|
def _Add_Arguments(alist):
|
||||||
|
for arg in alist:
|
||||||
|
a, b = string.split(arg, '=', 1)
|
||||||
|
ARGUMENTS[a] = b
|
||||||
|
ARGLIST.append((a, b))
|
||||||
|
|
||||||
|
def _Add_Targets(tlist):
|
||||||
|
if tlist:
|
||||||
|
COMMAND_LINE_TARGETS.extend(tlist)
|
||||||
|
BUILD_TARGETS.extend(tlist)
|
||||||
|
BUILD_TARGETS._add_Default = BUILD_TARGETS._do_nothing
|
||||||
|
BUILD_TARGETS._clear = BUILD_TARGETS._do_nothing
|
||||||
|
_build_plus_default.extend(tlist)
|
||||||
|
_build_plus_default._add_Default = _build_plus_default._do_nothing
|
||||||
|
_build_plus_default._clear = _build_plus_default._do_nothing
|
||||||
|
|
||||||
|
def _Set_Default_Targets_Has_Been_Called(d, fs):
|
||||||
|
return DEFAULT_TARGETS
|
||||||
|
|
||||||
|
def _Set_Default_Targets_Has_Not_Been_Called(d, fs):
|
||||||
|
if d is None:
|
||||||
|
d = [fs.Dir('.')]
|
||||||
|
return d
|
||||||
|
|
||||||
|
_Get_Default_Targets = _Set_Default_Targets_Has_Not_Been_Called
|
||||||
|
|
||||||
|
def _Set_Default_Targets(env, tlist):
|
||||||
|
global DEFAULT_TARGETS
|
||||||
|
global _Get_Default_Targets
|
||||||
|
_Get_Default_Targets = _Set_Default_Targets_Has_Been_Called
|
||||||
|
for t in tlist:
|
||||||
|
if t is None:
|
||||||
|
# Delete the elements from the list in-place, don't
|
||||||
|
# reassign an empty list to DEFAULT_TARGETS, so that the
|
||||||
|
# variables will still point to the same object we point to.
|
||||||
|
del DEFAULT_TARGETS[:]
|
||||||
|
BUILD_TARGETS._clear()
|
||||||
|
_build_plus_default._clear()
|
||||||
|
elif isinstance(t, SCons.Node.Node):
|
||||||
|
DEFAULT_TARGETS.append(t)
|
||||||
|
BUILD_TARGETS._add_Default([t])
|
||||||
|
_build_plus_default._add_Default([t])
|
||||||
|
else:
|
||||||
|
nodes = env.arg2nodes(t, env.fs.Entry)
|
||||||
|
DEFAULT_TARGETS.extend(nodes)
|
||||||
|
BUILD_TARGETS._add_Default(nodes)
|
||||||
|
_build_plus_default._add_Default(nodes)
|
||||||
|
|
||||||
|
#
|
||||||
|
help_text = None
|
||||||
|
|
||||||
|
def HelpFunction(text):
|
||||||
|
global help_text
|
||||||
|
if SCons.Script.help_text is None:
|
||||||
|
SCons.Script.help_text = text
|
||||||
|
else:
|
||||||
|
help_text = help_text + text
|
||||||
|
|
||||||
|
#
|
||||||
|
# Will be non-zero if we are reading an SConscript file.
|
||||||
|
sconscript_reading = 0
|
||||||
|
|
||||||
|
#
|
||||||
|
def Options(files=None, args=ARGUMENTS):
|
||||||
|
return SCons.Options.Options(files, args)
|
||||||
|
|
||||||
|
# The list of global functions to add to the SConscript name space
|
||||||
|
# that end up calling corresponding methods or Builders in the
|
||||||
|
# DefaultEnvironment().
|
||||||
|
GlobalDefaultEnvironmentFunctions = [
|
||||||
|
# Methods from the SConsEnvironment class, above.
|
||||||
|
'Default',
|
||||||
|
'EnsurePythonVersion',
|
||||||
|
'EnsureSConsVersion',
|
||||||
|
'Exit',
|
||||||
|
'Export',
|
||||||
|
'GetLaunchDir',
|
||||||
|
'GetOption',
|
||||||
|
'Help',
|
||||||
|
'Import',
|
||||||
|
#'SConscript', is handled separately, below.
|
||||||
|
'SConscriptChdir',
|
||||||
|
'SetOption',
|
||||||
|
|
||||||
|
# Methods from the Environment.Base class.
|
||||||
|
'AddPostAction',
|
||||||
|
'AddPreAction',
|
||||||
|
'Alias',
|
||||||
|
'AlwaysBuild',
|
||||||
|
'BuildDir',
|
||||||
|
'CacheDir',
|
||||||
|
'Clean',
|
||||||
|
#The Command() method is handled separately, below.
|
||||||
|
'Depends',
|
||||||
|
'Dir',
|
||||||
|
'NoClean',
|
||||||
|
'NoCache',
|
||||||
|
'Entry',
|
||||||
|
'Execute',
|
||||||
|
'File',
|
||||||
|
'FindFile',
|
||||||
|
'Flatten',
|
||||||
|
'GetBuildPath',
|
||||||
|
'Ignore',
|
||||||
|
'Install',
|
||||||
|
'InstallAs',
|
||||||
|
'Literal',
|
||||||
|
'Local',
|
||||||
|
'ParseDepends',
|
||||||
|
'Precious',
|
||||||
|
'Repository',
|
||||||
|
'SConsignFile',
|
||||||
|
'SideEffect',
|
||||||
|
'SourceCode',
|
||||||
|
'SourceSignatures',
|
||||||
|
'Split',
|
||||||
|
'TargetSignatures',
|
||||||
|
'Value',
|
||||||
|
]
|
||||||
|
|
||||||
|
GlobalDefaultBuilders = [
|
||||||
|
# Supported builders.
|
||||||
|
'CFile',
|
||||||
|
'CXXFile',
|
||||||
|
'DVI',
|
||||||
|
'Jar',
|
||||||
|
'Java',
|
||||||
|
'JavaH',
|
||||||
|
'Library',
|
||||||
|
'M4',
|
||||||
|
'MSVSProject',
|
||||||
|
'Object',
|
||||||
|
'PCH',
|
||||||
|
'PDF',
|
||||||
|
'PostScript',
|
||||||
|
'Program',
|
||||||
|
'RES',
|
||||||
|
'RMIC',
|
||||||
|
'SharedLibrary',
|
||||||
|
'SharedObject',
|
||||||
|
'StaticLibrary',
|
||||||
|
'StaticObject',
|
||||||
|
'Tar',
|
||||||
|
'TypeLibrary',
|
||||||
|
'Zip',
|
||||||
|
]
|
||||||
|
|
||||||
|
for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
|
||||||
|
exec "%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))
|
||||||
|
del name
|
||||||
|
|
||||||
|
# There are a handful of variables that used to live in the
|
||||||
|
# Script/SConscript.py module that some SConscript files out there were
|
||||||
|
# accessing directly as SCons.Script.SConscript.*. The problem is that
|
||||||
|
# "SConscript" in this namespace is no longer a module, it's a global
|
||||||
|
# function call--or more precisely, an object that implements a global
|
||||||
|
# function call through the default Environment. Nevertheless, we can
|
||||||
|
# maintain backwards compatibility for SConscripts that were reaching in
|
||||||
|
# this way by hanging some attributes off the "SConscript" object here.
|
||||||
|
SConscript = _SConscript.DefaultEnvironmentCall('SConscript')
|
||||||
|
|
||||||
|
# Make SConscript look enough like the module it used to be so
|
||||||
|
# that pychecker doesn't barf.
|
||||||
|
SConscript.__name__ = 'SConscript'
|
||||||
|
|
||||||
|
SConscript.Arguments = ARGUMENTS
|
||||||
|
SConscript.ArgList = ARGLIST
|
||||||
|
SConscript.BuildTargets = BUILD_TARGETS
|
||||||
|
SConscript.CommandLineTargets = COMMAND_LINE_TARGETS
|
||||||
|
SConscript.DefaultTargets = DEFAULT_TARGETS
|
||||||
|
|
||||||
|
# The global Command() function must be handled differently than the
|
||||||
|
# global functions for other construction environment methods because
|
||||||
|
# we want people to be able to use Actions that must expand $TARGET
|
||||||
|
# and $SOURCE later, when (and if) the Action is invoked to build
|
||||||
|
# the target(s). We do this with the subst=1 argument, which creates
|
||||||
|
# a DefaultEnvironmentCall instance that wraps up a normal default
|
||||||
|
# construction environment that performs variable substitution, not a
|
||||||
|
# proxy that doesn't.
|
||||||
|
#
|
||||||
|
# There's a flaw here, though, because any other $-variables on a command
|
||||||
|
# line will *also* be expanded, each to a null string, but that should
|
||||||
|
# only be a problem in the unusual case where someone was passing a '$'
|
||||||
|
# on a command line and *expected* the $ to get through to the shell
|
||||||
|
# because they were calling Command() and not env.Command()... This is
|
||||||
|
# unlikely enough that we're going to leave this as is and cross that
|
||||||
|
# bridge if someone actually comes to it.
|
||||||
|
Command = _SConscript.DefaultEnvironmentCall('Command', subst=1)
|
|
@ -6,7 +6,7 @@ utility.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,13 +28,13 @@ utility.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Sig/MD5.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Sig/MD5.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import imp
|
import imp
|
||||||
import string
|
import string
|
||||||
|
|
||||||
# Force Python to load the builtin "md5" module. If we do this with a
|
# Force Python to load the builtin "md5" module. If we do this with a
|
||||||
# normal import statement, then case-insensitive systems (Win32) get
|
# normal import statement, then case-insensitive systems (Windows) get
|
||||||
# confused and thinks there's a case mismatch with *this* MD5.py module.
|
# confused and thinks there's a case mismatch with *this* MD5.py module.
|
||||||
file, name, desc = imp.find_module('md5')
|
file, name, desc = imp.find_module('md5')
|
||||||
try:
|
try:
|
||||||
|
@ -49,18 +49,30 @@ def current(new, old):
|
||||||
"""
|
"""
|
||||||
return new == old
|
return new == old
|
||||||
|
|
||||||
def hexdigest(s):
|
try:
|
||||||
"""Return a signature as a string of hex characters.
|
md5.new('').hexdigest
|
||||||
"""
|
except AttributeError:
|
||||||
# NOTE: This routine is a method in the Python 2.0 interface
|
# The md5 objects created by the module have no native hexdigest()
|
||||||
# of the native md5 module, but we want SCons to operate all
|
# method (*cough* 1.5.2 *cough*) so provide an equivalent.
|
||||||
# the way back to at least Python 1.5.2, which doesn't have it.
|
class new_md5:
|
||||||
h = string.hexdigits
|
def __init__(self, s):
|
||||||
r = ''
|
self.m = md5.new(str(s))
|
||||||
for c in s:
|
#def copy(self):
|
||||||
i = ord(c)
|
# return self.m.copy()
|
||||||
r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
|
def digest(self):
|
||||||
return r
|
return self.m.digest()
|
||||||
|
def hexdigest(self):
|
||||||
|
h = string.hexdigits
|
||||||
|
r = ''
|
||||||
|
for c in self.m.digest():
|
||||||
|
i = ord(c)
|
||||||
|
r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
|
||||||
|
return r
|
||||||
|
def update(self, s):
|
||||||
|
return self.m.update(s)
|
||||||
|
|
||||||
|
else:
|
||||||
|
new_md5 = lambda s: md5.new(str(s))
|
||||||
|
|
||||||
def collect(signatures):
|
def collect(signatures):
|
||||||
"""
|
"""
|
||||||
|
@ -70,10 +82,9 @@ def collect(signatures):
|
||||||
returns - the aggregate signature
|
returns - the aggregate signature
|
||||||
"""
|
"""
|
||||||
if len(signatures) == 1:
|
if len(signatures) == 1:
|
||||||
return signatures[0]
|
return signatures[0]
|
||||||
else:
|
else:
|
||||||
contents = string.join(signatures, ', ')
|
return new_md5(string.join(signatures, ', ')).hexdigest()
|
||||||
return hexdigest(md5.new(contents).digest())
|
|
||||||
|
|
||||||
def signature(obj):
|
def signature(obj):
|
||||||
"""Generate a signature for an object
|
"""Generate a signature for an object
|
||||||
|
@ -82,7 +93,7 @@ def signature(obj):
|
||||||
gc = obj.get_contents
|
gc = obj.get_contents
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError, "unable to fetch contents of '%s'" % str(obj)
|
raise AttributeError, "unable to fetch contents of '%s'" % str(obj)
|
||||||
return hexdigest(md5.new(str(gc())).digest())
|
return new_md5(gc()).hexdigest()
|
||||||
|
|
||||||
def to_string(signature):
|
def to_string(signature):
|
||||||
"""Convert a signature to a string"""
|
"""Convert a signature to a string"""
|
|
@ -6,7 +6,7 @@ utility.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,7 +28,7 @@ utility.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Sig/TimeStamp.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Sig/TimeStamp.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
def current(new, old):
|
def current(new, old):
|
||||||
"""Return whether a new timestamp is up-to-date with
|
"""Return whether a new timestamp is up-to-date with
|
|
@ -5,7 +5,7 @@ The Signature package for the scons software construction utility.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ The Signature package for the scons software construction utility.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Sig/__init__.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Sig/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import MD5
|
import MD5
|
||||||
|
@ -36,34 +36,18 @@ except ImportError:
|
||||||
import TimeStamp
|
import TimeStamp
|
||||||
default_module = TimeStamp
|
default_module = TimeStamp
|
||||||
|
|
||||||
# XXX We should move max_drift into Node/FS.py,
|
|
||||||
# since it's really something about files.
|
|
||||||
default_max_drift = 2*24*60*60
|
|
||||||
|
|
||||||
class SConsignEntry:
|
|
||||||
"""The old SConsignEntry format.
|
|
||||||
We keep this around to handle conversions from old .sconsign files."""
|
|
||||||
timestamp = None
|
|
||||||
bsig = None
|
|
||||||
csig = None
|
|
||||||
implicit = None
|
|
||||||
|
|
||||||
class Calculator:
|
class Calculator:
|
||||||
"""
|
"""
|
||||||
Encapsulates signature calculations and .sconsign file generating
|
Encapsulates signature calculations and .sconsign file generating
|
||||||
for the build engine.
|
for the build engine.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, module=default_module, max_drift=default_max_drift):
|
def __init__(self, module=default_module):
|
||||||
"""
|
"""
|
||||||
Initialize the calculator.
|
Initialize the calculator.
|
||||||
|
|
||||||
module - the signature module to use for signature calculations
|
module - the signature module to use for signature calculations
|
||||||
max_drift - the maximum system clock drift used to determine when to
|
|
||||||
cache content signatures. A negative value means to never cache
|
|
||||||
content signatures. (defaults to 2 days)
|
|
||||||
"""
|
"""
|
||||||
self.module = module
|
self.module = module
|
||||||
self.max_drift = max_drift
|
|
||||||
|
|
||||||
default_calc = Calculator()
|
default_calc = Calculator()
|
853
scons/scons-local-0.97/SCons/Subst.py
Normal file
853
scons/scons-local-0.97/SCons/Subst.py
Normal file
|
@ -0,0 +1,853 @@
|
||||||
|
"""SCons.Subst
|
||||||
|
|
||||||
|
SCons string substitution.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Subst.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
|
|
||||||
|
import re
|
||||||
|
import string
|
||||||
|
import types
|
||||||
|
import UserList
|
||||||
|
import UserString
|
||||||
|
|
||||||
|
import SCons.Errors
|
||||||
|
|
||||||
|
from SCons.Util import is_String, is_List, is_Tuple
|
||||||
|
|
||||||
|
# Indexed by the SUBST_* constants below.
|
||||||
|
_strconv = [SCons.Util.to_String,
|
||||||
|
SCons.Util.to_String,
|
||||||
|
SCons.Util.to_String_for_signature]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AllowableExceptions = (IndexError, NameError)
|
||||||
|
|
||||||
|
def SetAllowableExceptions(*excepts):
|
||||||
|
global AllowableExceptions
|
||||||
|
AllowableExceptions = filter(None, excepts)
|
||||||
|
|
||||||
|
def raise_exception(exception, target, s):
|
||||||
|
name = exception.__class__.__name__
|
||||||
|
msg = "%s `%s' trying to evaluate `%s'" % (name, exception, s)
|
||||||
|
if target:
|
||||||
|
raise SCons.Errors.BuildError, (target[0], msg)
|
||||||
|
else:
|
||||||
|
raise SCons.Errors.UserError, msg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Literal:
|
||||||
|
"""A wrapper for a string. If you use this object wrapped
|
||||||
|
around a string, then it will be interpreted as literal.
|
||||||
|
When passed to the command interpreter, all special
|
||||||
|
characters will be escaped."""
|
||||||
|
def __init__(self, lstr):
|
||||||
|
self.lstr = lstr
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.lstr
|
||||||
|
|
||||||
|
def escape(self, escape_func):
|
||||||
|
return escape_func(self.lstr)
|
||||||
|
|
||||||
|
def for_signature(self):
|
||||||
|
return self.lstr
|
||||||
|
|
||||||
|
def is_literal(self):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
class SpecialAttrWrapper:
|
||||||
|
"""This is a wrapper for what we call a 'Node special attribute.'
|
||||||
|
This is any of the attributes of a Node that we can reference from
|
||||||
|
Environment variable substitution, such as $TARGET.abspath or
|
||||||
|
$SOURCES[1].filebase. We implement the same methods as Literal
|
||||||
|
so we can handle special characters, plus a for_signature method,
|
||||||
|
such that we can return some canonical string during signature
|
||||||
|
calculation to avoid unnecessary rebuilds."""
|
||||||
|
|
||||||
|
def __init__(self, lstr, for_signature=None):
|
||||||
|
"""The for_signature parameter, if supplied, will be the
|
||||||
|
canonical string we return from for_signature(). Else
|
||||||
|
we will simply return lstr."""
|
||||||
|
self.lstr = lstr
|
||||||
|
if for_signature:
|
||||||
|
self.forsig = for_signature
|
||||||
|
else:
|
||||||
|
self.forsig = lstr
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.lstr
|
||||||
|
|
||||||
|
def escape(self, escape_func):
|
||||||
|
return escape_func(self.lstr)
|
||||||
|
|
||||||
|
def for_signature(self):
|
||||||
|
return self.forsig
|
||||||
|
|
||||||
|
def is_literal(self):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def quote_spaces(arg):
|
||||||
|
"""Generic function for putting double quotes around any string that
|
||||||
|
has white space in it."""
|
||||||
|
if ' ' in arg or '\t' in arg:
|
||||||
|
return '"%s"' % arg
|
||||||
|
else:
|
||||||
|
return str(arg)
|
||||||
|
|
||||||
|
class CmdStringHolder(UserString.UserString):
|
||||||
|
"""This is a special class used to hold strings generated by
|
||||||
|
scons_subst() and scons_subst_list(). It defines a special method
|
||||||
|
escape(). When passed a function with an escape algorithm for a
|
||||||
|
particular platform, it will return the contained string with the
|
||||||
|
proper escape sequences inserted.
|
||||||
|
"""
|
||||||
|
def __init__(self, cmd, literal=None):
|
||||||
|
UserString.UserString.__init__(self, cmd)
|
||||||
|
self.literal = literal
|
||||||
|
|
||||||
|
def is_literal(self):
|
||||||
|
return self.literal
|
||||||
|
|
||||||
|
def escape(self, escape_func, quote_func=quote_spaces):
|
||||||
|
"""Escape the string with the supplied function. The
|
||||||
|
function is expected to take an arbitrary string, then
|
||||||
|
return it with all special characters escaped and ready
|
||||||
|
for passing to the command interpreter.
|
||||||
|
|
||||||
|
After calling this function, the next call to str() will
|
||||||
|
return the escaped string.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if self.is_literal():
|
||||||
|
return escape_func(self.data)
|
||||||
|
elif ' ' in self.data or '\t' in self.data:
|
||||||
|
return quote_func(self.data)
|
||||||
|
else:
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
def escape_list(list, escape_func):
|
||||||
|
"""Escape a list of arguments by running the specified escape_func
|
||||||
|
on every object in the list that has an escape() method."""
|
||||||
|
def escape(obj, escape_func=escape_func):
|
||||||
|
try:
|
||||||
|
e = obj.escape
|
||||||
|
except AttributeError:
|
||||||
|
return obj
|
||||||
|
else:
|
||||||
|
return e(escape_func)
|
||||||
|
return map(escape, list)
|
||||||
|
|
||||||
|
class NLWrapper:
|
||||||
|
"""A wrapper class that delays turning a list of sources or targets
|
||||||
|
into a NodeList until it's needed. The specified function supplied
|
||||||
|
when the object is initialized is responsible for turning raw nodes
|
||||||
|
into proxies that implement the special attributes like .abspath,
|
||||||
|
.source, etc. This way, we avoid creating those proxies just
|
||||||
|
"in case" someone is going to use $TARGET or the like, and only
|
||||||
|
go through the trouble if we really have to.
|
||||||
|
|
||||||
|
In practice, this might be a wash performance-wise, but it's a little
|
||||||
|
cleaner conceptually...
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, list, func):
|
||||||
|
self.list = list
|
||||||
|
self.func = func
|
||||||
|
def _return_nodelist(self):
|
||||||
|
return self.nodelist
|
||||||
|
def _gen_nodelist(self):
|
||||||
|
list = self.list
|
||||||
|
if list is None:
|
||||||
|
list = []
|
||||||
|
elif not is_List(list) and not is_Tuple(list):
|
||||||
|
list = [list]
|
||||||
|
# The map(self.func) call is what actually turns
|
||||||
|
# a list into appropriate proxies.
|
||||||
|
self.nodelist = SCons.Util.NodeList(map(self.func, list))
|
||||||
|
self._create_nodelist = self._return_nodelist
|
||||||
|
return self.nodelist
|
||||||
|
_create_nodelist = _gen_nodelist
|
||||||
|
|
||||||
|
|
||||||
|
class Targets_or_Sources(UserList.UserList):
|
||||||
|
"""A class that implements $TARGETS or $SOURCES expansions by in turn
|
||||||
|
wrapping a NLWrapper. This class handles the different methods used
|
||||||
|
to access the list, calling the NLWrapper to create proxies on demand.
|
||||||
|
|
||||||
|
Note that we subclass UserList.UserList purely so that the is_List()
|
||||||
|
function will identify an object of this class as a list during
|
||||||
|
variable expansion. We're not really using any UserList.UserList
|
||||||
|
methods in practice.
|
||||||
|
"""
|
||||||
|
def __init__(self, nl):
|
||||||
|
self.nl = nl
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
nl = self.nl._create_nodelist()
|
||||||
|
return getattr(nl, attr)
|
||||||
|
def __getitem__(self, i):
|
||||||
|
nl = self.nl._create_nodelist()
|
||||||
|
return nl[i]
|
||||||
|
def __getslice__(self, i, j):
|
||||||
|
nl = self.nl._create_nodelist()
|
||||||
|
i = max(i, 0); j = max(j, 0)
|
||||||
|
return nl[i:j]
|
||||||
|
def __str__(self):
|
||||||
|
nl = self.nl._create_nodelist()
|
||||||
|
return str(nl)
|
||||||
|
def __repr__(self):
|
||||||
|
nl = self.nl._create_nodelist()
|
||||||
|
return repr(nl)
|
||||||
|
|
||||||
|
class Target_or_Source:
|
||||||
|
"""A class that implements $TARGET or $SOURCE expansions by in turn
|
||||||
|
wrapping a NLWrapper. This class handles the different methods used
|
||||||
|
to access an individual proxy Node, calling the NLWrapper to create
|
||||||
|
a proxy on demand.
|
||||||
|
"""
|
||||||
|
def __init__(self, nl):
|
||||||
|
self.nl = nl
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
nl = self.nl._create_nodelist()
|
||||||
|
try:
|
||||||
|
nl0 = nl[0]
|
||||||
|
except IndexError:
|
||||||
|
# If there is nothing in the list, then we have no attributes to
|
||||||
|
# pass through, so raise AttributeError for everything.
|
||||||
|
raise AttributeError, "NodeList has no attribute: %s" % attr
|
||||||
|
return getattr(nl0, attr)
|
||||||
|
def __str__(self):
|
||||||
|
nl = self.nl._create_nodelist()
|
||||||
|
if nl:
|
||||||
|
return str(nl[0])
|
||||||
|
return ''
|
||||||
|
def __repr__(self):
|
||||||
|
nl = self.nl._create_nodelist()
|
||||||
|
if nl:
|
||||||
|
return repr(nl[0])
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def subst_dict(target, source):
|
||||||
|
"""Create a dictionary for substitution of special
|
||||||
|
construction variables.
|
||||||
|
|
||||||
|
This translates the following special arguments:
|
||||||
|
|
||||||
|
target - the target (object or array of objects),
|
||||||
|
used to generate the TARGET and TARGETS
|
||||||
|
construction variables
|
||||||
|
|
||||||
|
source - the source (object or array of objects),
|
||||||
|
used to generate the SOURCES and SOURCE
|
||||||
|
construction variables
|
||||||
|
"""
|
||||||
|
dict = {}
|
||||||
|
|
||||||
|
if target:
|
||||||
|
tnl = NLWrapper(target, lambda x: x.get_subst_proxy())
|
||||||
|
dict['TARGETS'] = Targets_or_Sources(tnl)
|
||||||
|
dict['TARGET'] = Target_or_Source(tnl)
|
||||||
|
else:
|
||||||
|
dict['TARGETS'] = None
|
||||||
|
dict['TARGET'] = None
|
||||||
|
|
||||||
|
if source:
|
||||||
|
def get_src_subst_proxy(node):
|
||||||
|
try:
|
||||||
|
rfile = node.rfile
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
node = rfile()
|
||||||
|
return node.get_subst_proxy()
|
||||||
|
snl = NLWrapper(source, get_src_subst_proxy)
|
||||||
|
dict['SOURCES'] = Targets_or_Sources(snl)
|
||||||
|
dict['SOURCE'] = Target_or_Source(snl)
|
||||||
|
else:
|
||||||
|
dict['SOURCES'] = None
|
||||||
|
dict['SOURCE'] = None
|
||||||
|
|
||||||
|
return dict
|
||||||
|
|
||||||
|
# Constants for the "mode" parameter to scons_subst_list() and
|
||||||
|
# scons_subst(). SUBST_RAW gives the raw command line. SUBST_CMD
|
||||||
|
# gives a command line suitable for passing to a shell. SUBST_SIG
|
||||||
|
# gives a command line appropriate for calculating the signature
|
||||||
|
# of a command line...if this changes, we should rebuild.
|
||||||
|
SUBST_CMD = 0
|
||||||
|
SUBST_RAW = 1
|
||||||
|
SUBST_SIG = 2
|
||||||
|
|
||||||
|
_rm = re.compile(r'\$[()]')
|
||||||
|
_remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)')
|
||||||
|
|
||||||
|
# Indexed by the SUBST_* constants above.
|
||||||
|
_regex_remove = [ _rm, None, _remove ]
|
||||||
|
|
||||||
|
# Regular expressions for splitting strings and handling substitutions,
|
||||||
|
# for use by the scons_subst() and scons_subst_list() functions:
|
||||||
|
#
|
||||||
|
# The first expression compiled matches all of the $-introduced tokens
|
||||||
|
# that we need to process in some way, and is used for substitutions.
|
||||||
|
# The expressions it matches are:
|
||||||
|
#
|
||||||
|
# "$$"
|
||||||
|
# "$("
|
||||||
|
# "$)"
|
||||||
|
# "$variable" [must begin with alphabetic or underscore]
|
||||||
|
# "${any stuff}"
|
||||||
|
#
|
||||||
|
# The second expression compiled is used for splitting strings into tokens
|
||||||
|
# to be processed, and it matches all of the tokens listed above, plus
|
||||||
|
# the following that affect how arguments do or don't get joined together:
|
||||||
|
#
|
||||||
|
# " " [white space]
|
||||||
|
# "non-white-space" [without any dollar signs]
|
||||||
|
# "$" [single dollar sign]
|
||||||
|
#
|
||||||
|
_dollar_exps_str = r'\$[\$\(\)]|\$[_a-zA-Z][\.\w]*|\${[^}]*}'
|
||||||
|
_dollar_exps = re.compile(r'(%s)' % _dollar_exps_str)
|
||||||
|
_separate_args = re.compile(r'(%s|\s+|[^\s\$]+|\$)' % _dollar_exps_str)
|
||||||
|
|
||||||
|
# This regular expression is used to replace strings of multiple white
|
||||||
|
# space characters in the string result from the scons_subst() function.
|
||||||
|
_space_sep = re.compile(r'[\t ]+(?![^{]*})')
|
||||||
|
|
||||||
|
def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None):
|
||||||
|
"""Expand a string containing construction variable substitutions.
|
||||||
|
|
||||||
|
This is the work-horse function for substitutions in file names
|
||||||
|
and the like. The companion scons_subst_list() function (below)
|
||||||
|
handles separating command lines into lists of arguments, so see
|
||||||
|
that function if that's what you're looking for.
|
||||||
|
"""
|
||||||
|
if type(strSubst) == types.StringType and string.find(strSubst, '$') < 0:
|
||||||
|
return strSubst
|
||||||
|
|
||||||
|
class StringSubber:
|
||||||
|
"""A class to construct the results of a scons_subst() call.
|
||||||
|
|
||||||
|
This binds a specific construction environment, mode, target and
|
||||||
|
source with two methods (substitute() and expand()) that handle
|
||||||
|
the expansion.
|
||||||
|
"""
|
||||||
|
def __init__(self, env, mode, target, source, conv, gvars):
|
||||||
|
self.env = env
|
||||||
|
self.mode = mode
|
||||||
|
self.target = target
|
||||||
|
self.source = source
|
||||||
|
self.conv = conv
|
||||||
|
self.gvars = gvars
|
||||||
|
|
||||||
|
def expand(self, s, lvars):
|
||||||
|
"""Expand a single "token" as necessary, returning an
|
||||||
|
appropriate string containing the expansion.
|
||||||
|
|
||||||
|
This handles expanding different types of things (strings,
|
||||||
|
lists, callables) appropriately. It calls the wrapper
|
||||||
|
substitute() method to re-expand things as necessary, so that
|
||||||
|
the results of expansions of side-by-side strings still get
|
||||||
|
re-evaluated separately, not smushed together.
|
||||||
|
"""
|
||||||
|
if is_String(s):
|
||||||
|
try:
|
||||||
|
s0, s1 = s[:2]
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
return s
|
||||||
|
if s0 != '$':
|
||||||
|
return s
|
||||||
|
if s1 == '$':
|
||||||
|
return '$'
|
||||||
|
elif s1 in '()':
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
key = s[1:]
|
||||||
|
if key[0] == '{' or string.find(key, '.') >= 0:
|
||||||
|
if key[0] == '{':
|
||||||
|
key = key[1:-1]
|
||||||
|
try:
|
||||||
|
s = eval(key, self.gvars, lvars)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except Exception, e:
|
||||||
|
if e.__class__ in AllowableExceptions:
|
||||||
|
return ''
|
||||||
|
raise_exception(e, self.target, s)
|
||||||
|
else:
|
||||||
|
if lvars.has_key(key):
|
||||||
|
s = lvars[key]
|
||||||
|
elif self.gvars.has_key(key):
|
||||||
|
s = self.gvars[key]
|
||||||
|
elif not NameError in AllowableExceptions:
|
||||||
|
raise_exception(NameError(key), self.target, s)
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
# Before re-expanding the result, handle
|
||||||
|
# recursive expansion by copying the local
|
||||||
|
# variable dictionary and overwriting a null
|
||||||
|
# string for the value of the variable name
|
||||||
|
# we just expanded.
|
||||||
|
#
|
||||||
|
# This could potentially be optimized by only
|
||||||
|
# copying lvars when s contains more expansions,
|
||||||
|
# but lvars is usually supposed to be pretty
|
||||||
|
# small, and deeply nested variable expansions
|
||||||
|
# are probably more the exception than the norm,
|
||||||
|
# so it should be tolerable for now.
|
||||||
|
lv = lvars.copy()
|
||||||
|
var = string.split(key, '.')[0]
|
||||||
|
lv[var] = ''
|
||||||
|
return self.substitute(s, lv)
|
||||||
|
elif is_List(s) or is_Tuple(s):
|
||||||
|
def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars):
|
||||||
|
return conv(substitute(l, lvars))
|
||||||
|
r = map(func, s)
|
||||||
|
return string.join(r)
|
||||||
|
elif callable(s):
|
||||||
|
try:
|
||||||
|
s = s(target=self.target,
|
||||||
|
source=self.source,
|
||||||
|
env=self.env,
|
||||||
|
for_signature=(self.mode != SUBST_CMD))
|
||||||
|
except TypeError:
|
||||||
|
# This probably indicates that it's a callable
|
||||||
|
# object that doesn't match our calling arguments
|
||||||
|
# (like an Action).
|
||||||
|
if self.mode == SUBST_RAW:
|
||||||
|
return s
|
||||||
|
s = self.conv(s)
|
||||||
|
return self.substitute(s, lvars)
|
||||||
|
elif s is None:
|
||||||
|
return ''
|
||||||
|
else:
|
||||||
|
return s
|
||||||
|
|
||||||
|
def substitute(self, args, lvars):
|
||||||
|
"""Substitute expansions in an argument or list of arguments.
|
||||||
|
|
||||||
|
This serves as a wrapper for splitting up a string into
|
||||||
|
separate tokens.
|
||||||
|
"""
|
||||||
|
if is_String(args) and not isinstance(args, CmdStringHolder):
|
||||||
|
try:
|
||||||
|
def sub_match(match, conv=self.conv, expand=self.expand, lvars=lvars):
|
||||||
|
return conv(expand(match.group(1), lvars))
|
||||||
|
result = _dollar_exps.sub(sub_match, args)
|
||||||
|
except TypeError:
|
||||||
|
# If the internal conversion routine doesn't return
|
||||||
|
# strings (it could be overridden to return Nodes, for
|
||||||
|
# example), then the 1.5.2 re module will throw this
|
||||||
|
# exception. Back off to a slower, general-purpose
|
||||||
|
# algorithm that works for all data types.
|
||||||
|
args = _separate_args.findall(args)
|
||||||
|
result = []
|
||||||
|
for a in args:
|
||||||
|
result.append(self.conv(self.expand(a, lvars)))
|
||||||
|
try:
|
||||||
|
result = string.join(result, '')
|
||||||
|
except TypeError:
|
||||||
|
if len(result) == 1:
|
||||||
|
result = result[0]
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
return self.expand(args, lvars)
|
||||||
|
|
||||||
|
if conv is None:
|
||||||
|
conv = _strconv[mode]
|
||||||
|
|
||||||
|
# Doing this every time is a bit of a waste, since the Executor
|
||||||
|
# has typically already populated the OverrideEnvironment with
|
||||||
|
# $TARGET/$SOURCE variables. We're keeping this (for now), though,
|
||||||
|
# because it supports existing behavior that allows us to call
|
||||||
|
# an Action directly with an arbitrary target+source pair, which
|
||||||
|
# we use in Tool/tex.py to handle calling $BIBTEX when necessary.
|
||||||
|
# If we dropped that behavior (or found another way to cover it),
|
||||||
|
# we could get rid of this call completely and just rely on the
|
||||||
|
# Executor setting the variables.
|
||||||
|
d = subst_dict(target, source)
|
||||||
|
if d:
|
||||||
|
lvars = lvars.copy()
|
||||||
|
lvars.update(d)
|
||||||
|
|
||||||
|
# We're (most likely) going to eval() things. If Python doesn't
|
||||||
|
# find a __builtins__ value in the global dictionary used for eval(),
|
||||||
|
# it copies the current global values for you. Avoid this by
|
||||||
|
# setting it explicitly and then deleting, so we don't pollute the
|
||||||
|
# construction environment Dictionary(ies) that are typically used
|
||||||
|
# for expansion.
|
||||||
|
gvars['__builtins__'] = __builtins__
|
||||||
|
|
||||||
|
ss = StringSubber(env, mode, target, source, conv, gvars)
|
||||||
|
result = ss.substitute(strSubst, lvars)
|
||||||
|
|
||||||
|
try:
|
||||||
|
del gvars['__builtins__']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if is_String(result):
|
||||||
|
# Remove $(-$) pairs and any stuff in between,
|
||||||
|
# if that's appropriate.
|
||||||
|
remove = _regex_remove[mode]
|
||||||
|
if remove:
|
||||||
|
result = remove.sub('', result)
|
||||||
|
if mode != SUBST_RAW:
|
||||||
|
# Compress strings of white space characters into
|
||||||
|
# a single space.
|
||||||
|
result = string.strip(_space_sep.sub(' ', result))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
#Subst_List_Strings = {}
|
||||||
|
|
||||||
|
def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None):
|
||||||
|
"""Substitute construction variables in a string (or list or other
|
||||||
|
object) and separate the arguments into a command list.
|
||||||
|
|
||||||
|
The companion scons_subst() function (above) handles basic
|
||||||
|
substitutions within strings, so see that function instead
|
||||||
|
if that's what you're looking for.
|
||||||
|
"""
|
||||||
|
# try:
|
||||||
|
# Subst_List_Strings[strSubst] = Subst_List_Strings[strSubst] + 1
|
||||||
|
# except KeyError:
|
||||||
|
# Subst_List_Strings[strSubst] = 1
|
||||||
|
# import SCons.Debug
|
||||||
|
# SCons.Debug.caller(1)
|
||||||
|
class ListSubber(UserList.UserList):
|
||||||
|
"""A class to construct the results of a scons_subst_list() call.
|
||||||
|
|
||||||
|
Like StringSubber, this class binds a specific construction
|
||||||
|
environment, mode, target and source with two methods
|
||||||
|
(substitute() and expand()) that handle the expansion.
|
||||||
|
|
||||||
|
In addition, however, this class is used to track the state of
|
||||||
|
the result(s) we're gathering so we can do the appropriate thing
|
||||||
|
whenever we have to append another word to the result--start a new
|
||||||
|
line, start a new word, append to the current word, etc. We do
|
||||||
|
this by setting the "append" attribute to the right method so
|
||||||
|
that our wrapper methods only need ever call ListSubber.append(),
|
||||||
|
and the rest of the object takes care of doing the right thing
|
||||||
|
internally.
|
||||||
|
"""
|
||||||
|
def __init__(self, env, mode, target, source, conv, gvars):
|
||||||
|
UserList.UserList.__init__(self, [])
|
||||||
|
self.env = env
|
||||||
|
self.mode = mode
|
||||||
|
self.target = target
|
||||||
|
self.source = source
|
||||||
|
self.conv = conv
|
||||||
|
self.gvars = gvars
|
||||||
|
|
||||||
|
if self.mode == SUBST_RAW:
|
||||||
|
self.add_strip = lambda x, s=self: s.append(x)
|
||||||
|
else:
|
||||||
|
self.add_strip = lambda x, s=self: None
|
||||||
|
self.in_strip = None
|
||||||
|
self.next_line()
|
||||||
|
|
||||||
|
def expand(self, s, lvars, within_list):
|
||||||
|
"""Expand a single "token" as necessary, appending the
|
||||||
|
expansion to the current result.
|
||||||
|
|
||||||
|
This handles expanding different types of things (strings,
|
||||||
|
lists, callables) appropriately. It calls the wrapper
|
||||||
|
substitute() method to re-expand things as necessary, so that
|
||||||
|
the results of expansions of side-by-side strings still get
|
||||||
|
re-evaluated separately, not smushed together.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if is_String(s):
|
||||||
|
try:
|
||||||
|
s0, s1 = s[:2]
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
self.append(s)
|
||||||
|
return
|
||||||
|
if s0 != '$':
|
||||||
|
self.append(s)
|
||||||
|
return
|
||||||
|
if s1 == '$':
|
||||||
|
self.append('$')
|
||||||
|
elif s1 == '(':
|
||||||
|
self.open_strip('$(')
|
||||||
|
elif s1 == ')':
|
||||||
|
self.close_strip('$)')
|
||||||
|
else:
|
||||||
|
key = s[1:]
|
||||||
|
if key[0] == '{' or string.find(key, '.') >= 0:
|
||||||
|
if key[0] == '{':
|
||||||
|
key = key[1:-1]
|
||||||
|
try:
|
||||||
|
s = eval(key, self.gvars, lvars)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except Exception, e:
|
||||||
|
if e.__class__ in AllowableExceptions:
|
||||||
|
return
|
||||||
|
raise_exception(e, self.target, s)
|
||||||
|
else:
|
||||||
|
if lvars.has_key(key):
|
||||||
|
s = lvars[key]
|
||||||
|
elif self.gvars.has_key(key):
|
||||||
|
s = self.gvars[key]
|
||||||
|
elif not NameError in AllowableExceptions:
|
||||||
|
raise_exception(NameError(), self.target, s)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Before re-expanding the result, handle
|
||||||
|
# recursive expansion by copying the local
|
||||||
|
# variable dictionary and overwriting a null
|
||||||
|
# string for the value of the variable name
|
||||||
|
# we just expanded.
|
||||||
|
lv = lvars.copy()
|
||||||
|
var = string.split(key, '.')[0]
|
||||||
|
lv[var] = ''
|
||||||
|
self.substitute(s, lv, 0)
|
||||||
|
self.this_word()
|
||||||
|
elif is_List(s) or is_Tuple(s):
|
||||||
|
for a in s:
|
||||||
|
self.substitute(a, lvars, 1)
|
||||||
|
self.next_word()
|
||||||
|
elif callable(s):
|
||||||
|
try:
|
||||||
|
s = s(target=self.target,
|
||||||
|
source=self.source,
|
||||||
|
env=self.env,
|
||||||
|
for_signature=(self.mode != SUBST_CMD))
|
||||||
|
except TypeError:
|
||||||
|
# This probably indicates that it's a callable
|
||||||
|
# object that doesn't match our calling arguments
|
||||||
|
# (like an Action).
|
||||||
|
if self.mode == SUBST_RAW:
|
||||||
|
self.append(s)
|
||||||
|
return
|
||||||
|
s = self.conv(s)
|
||||||
|
self.substitute(s, lvars, within_list)
|
||||||
|
elif s is None:
|
||||||
|
self.this_word()
|
||||||
|
else:
|
||||||
|
self.append(s)
|
||||||
|
|
||||||
|
def substitute(self, args, lvars, within_list):
|
||||||
|
"""Substitute expansions in an argument or list of arguments.
|
||||||
|
|
||||||
|
This serves as a wrapper for splitting up a string into
|
||||||
|
separate tokens.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if is_String(args) and not isinstance(args, CmdStringHolder):
|
||||||
|
args = _separate_args.findall(args)
|
||||||
|
for a in args:
|
||||||
|
if a[0] in ' \t\n\r\f\v':
|
||||||
|
if '\n' in a:
|
||||||
|
self.next_line()
|
||||||
|
elif within_list:
|
||||||
|
self.append(a)
|
||||||
|
else:
|
||||||
|
self.next_word()
|
||||||
|
else:
|
||||||
|
self.expand(a, lvars, within_list)
|
||||||
|
else:
|
||||||
|
self.expand(args, lvars, within_list)
|
||||||
|
|
||||||
|
def next_line(self):
|
||||||
|
"""Arrange for the next word to start a new line. This
|
||||||
|
is like starting a new word, except that we have to append
|
||||||
|
another line to the result."""
|
||||||
|
UserList.UserList.append(self, [])
|
||||||
|
self.next_word()
|
||||||
|
|
||||||
|
def this_word(self):
|
||||||
|
"""Arrange for the next word to append to the end of the
|
||||||
|
current last word in the result."""
|
||||||
|
self.append = self.add_to_current_word
|
||||||
|
|
||||||
|
def next_word(self):
|
||||||
|
"""Arrange for the next word to start a new word."""
|
||||||
|
self.append = self.add_new_word
|
||||||
|
|
||||||
|
def add_to_current_word(self, x):
|
||||||
|
"""Append the string x to the end of the current last word
|
||||||
|
in the result. If that is not possible, then just add
|
||||||
|
it as a new word. Make sure the entire concatenated string
|
||||||
|
inherits the object attributes of x (in particular, the
|
||||||
|
escape function) by wrapping it as CmdStringHolder."""
|
||||||
|
|
||||||
|
if not self.in_strip or self.mode != SUBST_SIG:
|
||||||
|
try:
|
||||||
|
current_word = self[-1][-1]
|
||||||
|
except IndexError:
|
||||||
|
self.add_new_word(x)
|
||||||
|
else:
|
||||||
|
# All right, this is a hack and it should probably
|
||||||
|
# be refactored out of existence in the future.
|
||||||
|
# The issue is that we want to smoosh words together
|
||||||
|
# and make one file name that gets escaped if
|
||||||
|
# we're expanding something like foo$EXTENSION,
|
||||||
|
# but we don't want to smoosh them together if
|
||||||
|
# it's something like >$TARGET, because then we'll
|
||||||
|
# treat the '>' like it's part of the file name.
|
||||||
|
# So for now, just hard-code looking for the special
|
||||||
|
# command-line redirection characters...
|
||||||
|
try:
|
||||||
|
last_char = str(current_word)[-1]
|
||||||
|
except IndexError:
|
||||||
|
last_char = '\0'
|
||||||
|
if last_char in '<>|':
|
||||||
|
self.add_new_word(x)
|
||||||
|
else:
|
||||||
|
y = current_word + x
|
||||||
|
|
||||||
|
# We used to treat a word appended to a literal
|
||||||
|
# as a literal itself, but this caused problems
|
||||||
|
# with interpreting quotes around space-separated
|
||||||
|
# targets on command lines. Removing this makes
|
||||||
|
# none of the "substantive" end-to-end tests fail,
|
||||||
|
# so we'll take this out but leave it commented
|
||||||
|
# for now in case there's a problem not covered
|
||||||
|
# by the test cases and we need to resurrect this.
|
||||||
|
#literal1 = self.literal(self[-1][-1])
|
||||||
|
#literal2 = self.literal(x)
|
||||||
|
y = self.conv(y)
|
||||||
|
if is_String(y):
|
||||||
|
#y = CmdStringHolder(y, literal1 or literal2)
|
||||||
|
y = CmdStringHolder(y, None)
|
||||||
|
self[-1][-1] = y
|
||||||
|
|
||||||
|
def add_new_word(self, x):
|
||||||
|
if not self.in_strip or self.mode != SUBST_SIG:
|
||||||
|
literal = self.literal(x)
|
||||||
|
x = self.conv(x)
|
||||||
|
if is_String(x):
|
||||||
|
x = CmdStringHolder(x, literal)
|
||||||
|
self[-1].append(x)
|
||||||
|
self.append = self.add_to_current_word
|
||||||
|
|
||||||
|
def literal(self, x):
|
||||||
|
try:
|
||||||
|
l = x.is_literal
|
||||||
|
except AttributeError:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return l()
|
||||||
|
|
||||||
|
def open_strip(self, x):
|
||||||
|
"""Handle the "open strip" $( token."""
|
||||||
|
self.add_strip(x)
|
||||||
|
self.in_strip = 1
|
||||||
|
|
||||||
|
def close_strip(self, x):
|
||||||
|
"""Handle the "close strip" $) token."""
|
||||||
|
self.add_strip(x)
|
||||||
|
self.in_strip = None
|
||||||
|
|
||||||
|
if conv is None:
|
||||||
|
conv = _strconv[mode]
|
||||||
|
|
||||||
|
# Doing this every time is a bit of a waste, since the Executor
|
||||||
|
# has typically already populated the OverrideEnvironment with
|
||||||
|
# $TARGET/$SOURCE variables. We're keeping this (for now), though,
|
||||||
|
# because it supports existing behavior that allows us to call
|
||||||
|
# an Action directly with an arbitrary target+source pair, which
|
||||||
|
# we use in Tool/tex.py to handle calling $BIBTEX when necessary.
|
||||||
|
# If we dropped that behavior (or found another way to cover it),
|
||||||
|
# we could get rid of this call completely and just rely on the
|
||||||
|
# Executor setting the variables.
|
||||||
|
d = subst_dict(target, source)
|
||||||
|
if d:
|
||||||
|
lvars = lvars.copy()
|
||||||
|
lvars.update(d)
|
||||||
|
|
||||||
|
# We're (most likely) going to eval() things. If Python doesn't
|
||||||
|
# find a __builtins__ value in the global dictionary used for eval(),
|
||||||
|
# it copies the current global values for you. Avoid this by
|
||||||
|
# setting it explicitly and then deleting, so we don't pollute the
|
||||||
|
# construction environment Dictionary(ies) that are typically used
|
||||||
|
# for expansion.
|
||||||
|
gvars['__builtins__'] = __builtins__
|
||||||
|
|
||||||
|
ls = ListSubber(env, mode, target, source, conv, gvars)
|
||||||
|
ls.substitute(strSubst, lvars, 0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
del gvars['__builtins__']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return ls.data
|
||||||
|
|
||||||
|
def scons_subst_once(strSubst, env, key):
|
||||||
|
"""Perform single (non-recursive) substitution of a single
|
||||||
|
construction variable keyword.
|
||||||
|
|
||||||
|
This is used when setting a variable when copying or overriding values
|
||||||
|
in an Environment. We want to capture (expand) the old value before
|
||||||
|
we override it, so people can do things like:
|
||||||
|
|
||||||
|
env2 = env.Clone(CCFLAGS = '$CCFLAGS -g')
|
||||||
|
|
||||||
|
We do this with some straightforward, brute-force code here...
|
||||||
|
"""
|
||||||
|
if type(strSubst) == types.StringType and string.find(strSubst, '$') < 0:
|
||||||
|
return strSubst
|
||||||
|
|
||||||
|
matchlist = ['$' + key, '${' + key + '}']
|
||||||
|
val = env.get(key, '')
|
||||||
|
def sub_match(match, val=val, matchlist=matchlist):
|
||||||
|
a = match.group(1)
|
||||||
|
if a in matchlist:
|
||||||
|
a = val
|
||||||
|
if is_List(a) or is_Tuple(a):
|
||||||
|
return string.join(map(str, a))
|
||||||
|
else:
|
||||||
|
return str(a)
|
||||||
|
|
||||||
|
if is_List(strSubst) or is_Tuple(strSubst):
|
||||||
|
result = []
|
||||||
|
for arg in strSubst:
|
||||||
|
if is_String(arg):
|
||||||
|
if arg in matchlist:
|
||||||
|
arg = val
|
||||||
|
if is_List(arg) or is_Tuple(arg):
|
||||||
|
result.extend(arg)
|
||||||
|
else:
|
||||||
|
result.append(arg)
|
||||||
|
else:
|
||||||
|
result.append(_dollar_exps.sub(sub_match, arg))
|
||||||
|
else:
|
||||||
|
result.append(arg)
|
||||||
|
return result
|
||||||
|
elif is_String(strSubst):
|
||||||
|
return _dollar_exps.sub(sub_match, strSubst)
|
||||||
|
else:
|
||||||
|
return strSubst
|
685
scons/scons-local-0.97/SCons/Taskmaster.py
Normal file
685
scons/scons-local-0.97/SCons/Taskmaster.py
Normal file
|
@ -0,0 +1,685 @@
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
__doc__ = """
|
||||||
|
Generic Taskmaster module for the SCons build engine.
|
||||||
|
|
||||||
|
This module contains the primary interface(s) between a wrapping user
|
||||||
|
interface and the SCons build engine. There are two key classes here:
|
||||||
|
|
||||||
|
Taskmaster
|
||||||
|
This is the main engine for walking the dependency graph and
|
||||||
|
calling things to decide what does or doesn't need to be built.
|
||||||
|
|
||||||
|
Task
|
||||||
|
This is the base class for allowing a wrapping interface to
|
||||||
|
decide what does or doesn't actually need to be done. The
|
||||||
|
intention is for a wrapping interface to subclass this as
|
||||||
|
appropriate for different types of behavior it may need.
|
||||||
|
|
||||||
|
The canonical example is the SCons native Python interface,
|
||||||
|
which has Task subclasses that handle its specific behavior,
|
||||||
|
like printing "`foo' is up to date" when a top-level target
|
||||||
|
doesn't need to be built, and handling the -c option by removing
|
||||||
|
targets as its "build" action. There is also a separate subclass
|
||||||
|
for suppressing this output when the -q option is used.
|
||||||
|
|
||||||
|
The Taskmaster instantiates a Task object for each (set of)
|
||||||
|
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"
|
||||||
|
|
||||||
|
import SCons.compat
|
||||||
|
|
||||||
|
import operator
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import SCons.Node
|
||||||
|
import SCons.Errors
|
||||||
|
|
||||||
|
StateString = SCons.Node.StateString
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# A subsystem for recording stats about how different Nodes are handled by
|
||||||
|
# the main Taskmaster loop. There's no external control here (no need for
|
||||||
|
# a --debug= option); enable it by changing the value of CollectStats.
|
||||||
|
|
||||||
|
CollectStats = None
|
||||||
|
|
||||||
|
class Stats:
|
||||||
|
"""
|
||||||
|
A simple class for holding statistics about the disposition of a
|
||||||
|
Node by the Taskmaster. If we're collecting statistics, each Node
|
||||||
|
processed by the Taskmaster gets one of these attached, in which case
|
||||||
|
the Taskmaster records its decision each time it processes the Node.
|
||||||
|
(Ideally, that's just once per Node.)
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
Instantiates a Taskmaster.Stats object, initializing all
|
||||||
|
appropriate counters to zero.
|
||||||
|
"""
|
||||||
|
self.considered = 0
|
||||||
|
self.already_handled = 0
|
||||||
|
self.problem = 0
|
||||||
|
self.child_failed = 0
|
||||||
|
self.not_built = 0
|
||||||
|
self.side_effects = 0
|
||||||
|
self.build = 0
|
||||||
|
|
||||||
|
StatsNodes = []
|
||||||
|
|
||||||
|
fmt = "%(considered)3d "\
|
||||||
|
"%(already_handled)3d " \
|
||||||
|
"%(problem)3d " \
|
||||||
|
"%(child_failed)3d " \
|
||||||
|
"%(not_built)3d " \
|
||||||
|
"%(side_effects)3d " \
|
||||||
|
"%(build)3d "
|
||||||
|
|
||||||
|
def dump_stats():
|
||||||
|
StatsNodes.sort(lambda a, b: cmp(str(a), str(b)))
|
||||||
|
for n in StatsNodes:
|
||||||
|
print (fmt % n.stats.__dict__) + str(n)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Task:
|
||||||
|
"""
|
||||||
|
Default SCons build engine task.
|
||||||
|
|
||||||
|
This controls the interaction of the actual building of node
|
||||||
|
and the rest of the engine.
|
||||||
|
|
||||||
|
This is expected to handle all of the normally-customizable
|
||||||
|
aspects of controlling a build, so any given application
|
||||||
|
*should* be able to do what it wants by sub-classing this
|
||||||
|
class and overriding methods as appropriate. If an application
|
||||||
|
needs to customze something by sub-classing Taskmaster (or
|
||||||
|
some other build engine class), we should first try to migrate
|
||||||
|
that functionality into this class.
|
||||||
|
|
||||||
|
Note that it's generally a good idea for sub-classes to call
|
||||||
|
these methods explicitly to update state, etc., rather than
|
||||||
|
roll their own interaction with Taskmaster from scratch.
|
||||||
|
"""
|
||||||
|
def __init__(self, tm, targets, top, node):
|
||||||
|
self.tm = tm
|
||||||
|
self.targets = targets
|
||||||
|
self.top = top
|
||||||
|
self.node = node
|
||||||
|
self.exc_clear()
|
||||||
|
|
||||||
|
def display(self, message):
|
||||||
|
"""
|
||||||
|
Hook to allow the calling interface to display a message.
|
||||||
|
|
||||||
|
This hook gets called as part of preparing a task for execution
|
||||||
|
(that is, a Node to be built). As part of figuring out what Node
|
||||||
|
should be built next, the actually target list may be altered,
|
||||||
|
along with a message describing the alteration. The calling
|
||||||
|
interface can subclass Task and provide a concrete implementation
|
||||||
|
of this method to see those messages.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def prepare(self):
|
||||||
|
"""
|
||||||
|
Called just before the task is executed.
|
||||||
|
|
||||||
|
This is mainly intended to give the target Nodes a chance to
|
||||||
|
unlink underlying files and make all necessary directories before
|
||||||
|
the Action is actually called to build the targets.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Now that it's the appropriate time, give the TaskMaster a
|
||||||
|
# chance to raise any exceptions it encountered while preparing
|
||||||
|
# this task.
|
||||||
|
self.exception_raise()
|
||||||
|
|
||||||
|
if self.tm.message:
|
||||||
|
self.display(self.tm.message)
|
||||||
|
self.tm.message = None
|
||||||
|
|
||||||
|
for t in self.targets:
|
||||||
|
t.prepare()
|
||||||
|
for s in t.side_effects:
|
||||||
|
s.prepare()
|
||||||
|
|
||||||
|
def get_target(self):
|
||||||
|
"""Fetch the target being built or updated by this task.
|
||||||
|
"""
|
||||||
|
return self.node
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
"""
|
||||||
|
Called to execute the task.
|
||||||
|
|
||||||
|
This method is called from multiple threads in a parallel build,
|
||||||
|
so only do thread safe stuff here. Do thread unsafe stuff in
|
||||||
|
prepare(), executed() or failed().
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
everything_was_cached = 1
|
||||||
|
for t in self.targets:
|
||||||
|
if not t.retrieve_from_cache():
|
||||||
|
everything_was_cached = 0
|
||||||
|
break
|
||||||
|
if not everything_was_cached:
|
||||||
|
self.targets[0].build()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except SystemExit:
|
||||||
|
exc_value = sys.exc_info()[1]
|
||||||
|
raise SCons.Errors.ExplicitExit(self.targets[0], exc_value.code)
|
||||||
|
except SCons.Errors.UserError:
|
||||||
|
raise
|
||||||
|
except SCons.Errors.BuildError:
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
raise SCons.Errors.TaskmasterException(self.targets[0],
|
||||||
|
sys.exc_info())
|
||||||
|
|
||||||
|
def executed(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."
|
||||||
|
"""
|
||||||
|
for t in self.targets:
|
||||||
|
if t.get_state() == SCons.Node.executing:
|
||||||
|
t.set_state(SCons.Node.executed)
|
||||||
|
t.built()
|
||||||
|
else:
|
||||||
|
t.visited()
|
||||||
|
|
||||||
|
def failed(self):
|
||||||
|
"""
|
||||||
|
Default action when a task fails: stop the build.
|
||||||
|
"""
|
||||||
|
self.fail_stop()
|
||||||
|
|
||||||
|
def fail_stop(self):
|
||||||
|
"""
|
||||||
|
Explicit stop-the-build failure.
|
||||||
|
"""
|
||||||
|
for t in self.targets:
|
||||||
|
t.set_state(SCons.Node.failed)
|
||||||
|
self.tm.stop()
|
||||||
|
|
||||||
|
# We're stopping because of a build failure, but give the
|
||||||
|
# calling Task class a chance to postprocess() the top-level
|
||||||
|
# target under which the build failure occurred.
|
||||||
|
self.targets = [self.tm.current_top]
|
||||||
|
self.top = 1
|
||||||
|
|
||||||
|
def fail_continue(self):
|
||||||
|
"""
|
||||||
|
Explicit continue-the-build failure.
|
||||||
|
|
||||||
|
This sets failure status on the target nodes and all of
|
||||||
|
their dependent parent nodes.
|
||||||
|
"""
|
||||||
|
for t in self.targets:
|
||||||
|
# Set failure state on all of the parents that were dependent
|
||||||
|
# on this failed build.
|
||||||
|
def set_state(node): node.set_state(SCons.Node.failed)
|
||||||
|
t.call_for_all_waiting_parents(set_state)
|
||||||
|
|
||||||
|
def make_ready_all(self):
|
||||||
|
"""
|
||||||
|
Marks all targets in a task ready for execution.
|
||||||
|
|
||||||
|
This is used when the interface needs every target Node to be
|
||||||
|
visited--the canonical example being the "scons -c" option.
|
||||||
|
"""
|
||||||
|
self.out_of_date = self.targets[:]
|
||||||
|
for t in self.targets:
|
||||||
|
t.disambiguate().set_state(SCons.Node.executing)
|
||||||
|
for s in t.side_effects:
|
||||||
|
s.set_state(SCons.Node.executing)
|
||||||
|
|
||||||
|
def make_ready_current(self):
|
||||||
|
"""
|
||||||
|
Marks all targets in a task ready for execution if any target
|
||||||
|
is not current.
|
||||||
|
|
||||||
|
This is the default behavior for building only what's necessary.
|
||||||
|
"""
|
||||||
|
self.out_of_date = []
|
||||||
|
for t in self.targets:
|
||||||
|
try:
|
||||||
|
is_up_to_date = t.disambiguate().current()
|
||||||
|
except EnvironmentError, e:
|
||||||
|
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
||||||
|
if is_up_to_date:
|
||||||
|
t.set_state(SCons.Node.up_to_date)
|
||||||
|
else:
|
||||||
|
self.out_of_date.append(t)
|
||||||
|
t.set_state(SCons.Node.executing)
|
||||||
|
for s in t.side_effects:
|
||||||
|
s.set_state(SCons.Node.executing)
|
||||||
|
|
||||||
|
make_ready = make_ready_current
|
||||||
|
|
||||||
|
def postprocess(self):
|
||||||
|
"""
|
||||||
|
Post-processes a task after it's been executed.
|
||||||
|
|
||||||
|
This examines all the targets just built (or not, we don't care
|
||||||
|
if the build was successful, or even if there was no build
|
||||||
|
because everything was up-to-date) to see if they have any
|
||||||
|
waiting parent Nodes, or Nodes waiting on a common side effect,
|
||||||
|
that can be put back on the candidates list.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# We may have built multiple targets, some of which may have
|
||||||
|
# common parents waiting for this build. Count up how many
|
||||||
|
# targets each parent was waiting for so we can subtract the
|
||||||
|
# values later, and so we *don't* put waiting side-effect Nodes
|
||||||
|
# back on the candidates list if the Node is also a waiting
|
||||||
|
# parent.
|
||||||
|
|
||||||
|
parents = {}
|
||||||
|
for t in self.targets:
|
||||||
|
for p in t.waiting_parents.keys():
|
||||||
|
parents[p] = parents.get(p, 0) + 1
|
||||||
|
|
||||||
|
for t in self.targets:
|
||||||
|
for s in t.side_effects:
|
||||||
|
if s.get_state() == SCons.Node.executing:
|
||||||
|
s.set_state(SCons.Node.no_state)
|
||||||
|
for p in s.waiting_parents.keys():
|
||||||
|
if not parents.has_key(p):
|
||||||
|
parents[p] = 1
|
||||||
|
for p in s.waiting_s_e.keys():
|
||||||
|
if p.ref_count == 0:
|
||||||
|
self.tm.candidates.append(p)
|
||||||
|
|
||||||
|
for p, subtract in parents.items():
|
||||||
|
p.ref_count = p.ref_count - subtract
|
||||||
|
if p.ref_count == 0:
|
||||||
|
self.tm.candidates.append(p)
|
||||||
|
|
||||||
|
for t in self.targets:
|
||||||
|
t.postprocess()
|
||||||
|
|
||||||
|
# Exception handling subsystem.
|
||||||
|
#
|
||||||
|
# Exceptions that occur while walking the DAG or examining Nodes
|
||||||
|
# must be raised, but must be raised at an appropriate time and in
|
||||||
|
# a controlled manner so we can, if necessary, recover gracefully,
|
||||||
|
# possibly write out signature information for Nodes we've updated,
|
||||||
|
# etc. This is done by having the Taskmaster tell us about the
|
||||||
|
# exception, and letting
|
||||||
|
|
||||||
|
def exc_info(self):
|
||||||
|
"""
|
||||||
|
Returns info about a recorded exception.
|
||||||
|
"""
|
||||||
|
return self.exception
|
||||||
|
|
||||||
|
def exc_clear(self):
|
||||||
|
"""
|
||||||
|
Clears any recorded exception.
|
||||||
|
|
||||||
|
This also changes the "exception_raise" attribute to point
|
||||||
|
to the appropriate do-nothing method.
|
||||||
|
"""
|
||||||
|
self.exception = (None, None, None)
|
||||||
|
self.exception_raise = self._no_exception_to_raise
|
||||||
|
|
||||||
|
def exception_set(self, exception=None):
|
||||||
|
"""
|
||||||
|
Records an exception to be raised at the appropriate time.
|
||||||
|
|
||||||
|
This also changes the "exception_raise" attribute to point
|
||||||
|
to the method that will, in fact
|
||||||
|
"""
|
||||||
|
if not exception:
|
||||||
|
exception = sys.exc_info()
|
||||||
|
self.exception = exception
|
||||||
|
self.exception_raise = self._exception_raise
|
||||||
|
|
||||||
|
def _no_exception_to_raise(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _exception_raise(self):
|
||||||
|
"""
|
||||||
|
Raises a pending exception that was recorded while getting a
|
||||||
|
Task ready for execution.
|
||||||
|
"""
|
||||||
|
exc = self.exc_info()[:]
|
||||||
|
try:
|
||||||
|
exc_type, exc_value, exc_traceback = exc
|
||||||
|
except ValueError:
|
||||||
|
exc_type, exc_value = exc
|
||||||
|
exc_traceback = None
|
||||||
|
raise exc_type, exc_value, exc_traceback
|
||||||
|
|
||||||
|
|
||||||
|
def find_cycle(stack):
|
||||||
|
if stack[0] == stack[-1]:
|
||||||
|
return stack
|
||||||
|
for n in stack[-1].waiting_parents.keys():
|
||||||
|
stack.append(n)
|
||||||
|
if find_cycle(stack):
|
||||||
|
return stack
|
||||||
|
stack.pop()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class Taskmaster:
|
||||||
|
"""
|
||||||
|
The Taskmaster for walking the dependency DAG.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, targets=[], tasker=Task, order=None, trace=None):
|
||||||
|
self.top_targets = targets[:]
|
||||||
|
self.top_targets.reverse()
|
||||||
|
self.candidates = []
|
||||||
|
self.tasker = tasker
|
||||||
|
if not order:
|
||||||
|
order = lambda l: l
|
||||||
|
self.order = order
|
||||||
|
self.message = None
|
||||||
|
self.trace = trace
|
||||||
|
self.next_candidate = self.find_next_candidate
|
||||||
|
|
||||||
|
def find_next_candidate(self):
|
||||||
|
"""
|
||||||
|
Returns the next candidate Node for (potential) evaluation.
|
||||||
|
|
||||||
|
The candidate list (really a stack) initially consists of all of
|
||||||
|
the top-level (command line) targets provided when the Taskmaster
|
||||||
|
was initialized. While we walk the DAG, visiting Nodes, all the
|
||||||
|
children that haven't finished processing get pushed on to the
|
||||||
|
candidate list. Each child can then be popped and examined in
|
||||||
|
turn for whether *their* children are all up-to-date, in which
|
||||||
|
case a Task will be created for their actual evaluation and
|
||||||
|
potential building.
|
||||||
|
|
||||||
|
Here is where we also allow candidate Nodes to alter the list of
|
||||||
|
Nodes that should be examined. This is used, for example, when
|
||||||
|
invoking SCons in a source directory. A source directory Node can
|
||||||
|
return its corresponding build directory Node, essentially saying,
|
||||||
|
"Hey, you really need to build this thing over here instead."
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return self.candidates.pop()
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
node = self.top_targets.pop()
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
self.current_top = node
|
||||||
|
alt, message = node.alter_targets()
|
||||||
|
if alt:
|
||||||
|
self.message = message
|
||||||
|
self.candidates.append(node)
|
||||||
|
self.candidates.extend(self.order(alt))
|
||||||
|
node = self.candidates.pop()
|
||||||
|
return node
|
||||||
|
|
||||||
|
def no_next_candidate(self):
|
||||||
|
"""
|
||||||
|
Stops Taskmaster processing by not returning a next candidate.
|
||||||
|
"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _find_next_ready_node(self):
|
||||||
|
"""
|
||||||
|
Finds the next node that is ready to be built.
|
||||||
|
|
||||||
|
This is *the* main guts of the DAG walk. We loop through the
|
||||||
|
list of candidates, looking for something that has no un-built
|
||||||
|
children (i.e., that is a leaf Node or has dependencies that are
|
||||||
|
all leaf Nodes or up-to-date). Candidate Nodes are re-scanned
|
||||||
|
(both the target Node itself and its sources, which are always
|
||||||
|
scanned in the context of a given target) to discover implicit
|
||||||
|
dependencies. A Node that must wait for some children to be
|
||||||
|
built will be put back on the candidates list after the children
|
||||||
|
have finished building. A Node that has been put back on the
|
||||||
|
candidates list in this way may have itself (or its sources)
|
||||||
|
re-scanned, in order to handle generated header files (e.g.) and
|
||||||
|
the implicit dependencies therein.
|
||||||
|
|
||||||
|
Note that this method does not do any signature calculation or
|
||||||
|
up-to-date check itself. All of that is handled by the Task
|
||||||
|
class. This is purely concerned with the dependency graph walk.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.ready_exc = None
|
||||||
|
|
||||||
|
T = self.trace
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
node = self.next_candidate()
|
||||||
|
if node is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
node = node.disambiguate()
|
||||||
|
state = node.get_state()
|
||||||
|
|
||||||
|
if CollectStats:
|
||||||
|
if not hasattr(node, 'stats'):
|
||||||
|
node.stats = Stats()
|
||||||
|
StatsNodes.append(node)
|
||||||
|
S = node.stats
|
||||||
|
S.considered = S.considered + 1
|
||||||
|
else:
|
||||||
|
S = None
|
||||||
|
|
||||||
|
if T: T.write('Taskmaster: %s:' % repr(str(node)))
|
||||||
|
|
||||||
|
# Skip this node if it has already been evaluated:
|
||||||
|
if state > SCons.Node.pending:
|
||||||
|
if S: S.already_handled = S.already_handled + 1
|
||||||
|
if T: T.write(' already handled (%s)\n' % StateString[state])
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Mark this node as being on the execution stack:
|
||||||
|
node.set_state(SCons.Node.pending)
|
||||||
|
|
||||||
|
try:
|
||||||
|
children = node.children()
|
||||||
|
except SystemExit:
|
||||||
|
exc_value = sys.exc_info()[1]
|
||||||
|
e = SCons.Errors.ExplicitExit(node, exc_value.code)
|
||||||
|
self.ready_exc = (SCons.Errors.ExplicitExit, e)
|
||||||
|
if T: T.write(' SystemExit\n')
|
||||||
|
return node
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
if T: T.write(' KeyboardInterrupt\n')
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
# We had a problem just trying to figure out the
|
||||||
|
# children (like a child couldn't be linked in to a
|
||||||
|
# BuildDir, or a Scanner threw something). Arrange to
|
||||||
|
# raise the exception when the Task is "executed."
|
||||||
|
self.ready_exc = sys.exc_info()
|
||||||
|
if S: S.problem = S.problem + 1
|
||||||
|
if T: T.write(' exception\n')
|
||||||
|
return node
|
||||||
|
|
||||||
|
if T and children:
|
||||||
|
c = map(str, children)
|
||||||
|
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)
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
if failed_children:
|
||||||
|
node.set_state(SCons.Node.failed)
|
||||||
|
if S: S.child_failed = S.child_failed + 1
|
||||||
|
if T:
|
||||||
|
c = map(str, failed_children)
|
||||||
|
c.sort()
|
||||||
|
T.write(' children failed:\n %s\n' % c)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Detect dependency cycles:
|
||||||
|
pending_nodes = filter(lambda I: I[0] == SCons.Node.pending, childinfo)
|
||||||
|
if pending_nodes:
|
||||||
|
for p in pending_nodes:
|
||||||
|
cycle = find_cycle([p[2], 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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
if S: S.not_built = S.not_built + 1
|
||||||
|
if T:
|
||||||
|
c = map(str, not_built)
|
||||||
|
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.
|
||||||
|
side_effects = filter(lambda N:
|
||||||
|
N.get_state() == SCons.Node.executing,
|
||||||
|
node.side_effects)
|
||||||
|
if side_effects:
|
||||||
|
map(lambda n, P=node: n.add_to_waiting_s_e(P), side_effects)
|
||||||
|
if S: S.side_effects = S.side_effects + 1
|
||||||
|
if T:
|
||||||
|
c = map(str, side_effects)
|
||||||
|
c.sort()
|
||||||
|
T.write(' waiting on side effects:\n %s\n' % c)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# The default when we've gotten through all of the checks above:
|
||||||
|
# this node is ready to be built.
|
||||||
|
if S: S.build = S.build + 1
|
||||||
|
if T: T.write(' evaluating %s\n' % node)
|
||||||
|
return node
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def next_task(self):
|
||||||
|
"""
|
||||||
|
Returns the next task to be executed.
|
||||||
|
|
||||||
|
This simply asks for the next Node to be evaluated, and then wraps
|
||||||
|
it in the specific Task subclass with which we were initialized.
|
||||||
|
"""
|
||||||
|
node = self._find_next_ready_node()
|
||||||
|
|
||||||
|
if node is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
tlist = node.get_executor().targets
|
||||||
|
|
||||||
|
task = self.tasker(self, tlist, node is self.current_top, node)
|
||||||
|
try:
|
||||||
|
task.make_ready()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
# We had a problem just trying to get this task ready (like
|
||||||
|
# a child couldn't be linked in to a BuildDir when deciding
|
||||||
|
# whether this node is current). Arrange to raise the
|
||||||
|
# exception when the Task is "executed."
|
||||||
|
self.ready_exc = sys.exc_info()
|
||||||
|
|
||||||
|
if self.ready_exc:
|
||||||
|
task.exception_set(self.ready_exc)
|
||||||
|
|
||||||
|
self.ready_exc = None
|
||||||
|
|
||||||
|
return task
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""
|
||||||
|
Stops the current build completely.
|
||||||
|
"""
|
||||||
|
self.next_candidate = self.no_next_candidate
|
|
@ -10,7 +10,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -32,21 +32,22 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/386asm.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/386asm.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
from SCons.Tool.PharLapCommon import addPharLapPaths
|
from SCons.Tool.PharLapCommon import addPharLapPaths
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
import as
|
as_module = __import__('as', globals(), locals(), [])
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for ar to an Environment."""
|
"""Add Builders and construction variables for ar to an Environment."""
|
||||||
as.generate(env)
|
as_module.generate(env)
|
||||||
|
|
||||||
env['AS'] = '386asm'
|
env['AS'] = '386asm'
|
||||||
env['ASFLAGS'] = SCons.Util.CLVar('')
|
env['ASFLAGS'] = SCons.Util.CLVar('')
|
||||||
|
env['ASPPFLAGS'] = '$ASFLAGS'
|
||||||
env['ASCOM'] = '$AS $ASFLAGS $SOURCES -o $TARGET'
|
env['ASCOM'] = '$AS $ASFLAGS $SOURCES -o $TARGET'
|
||||||
env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES -o $TARGET'
|
env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $SOURCES -o $TARGET'
|
||||||
|
|
||||||
addPharLapPaths(env)
|
addPharLapPaths(env)
|
||||||
|
|
|
@ -10,7 +10,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -32,10 +32,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/BitKeeper.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/BitKeeper.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
@ -45,7 +44,8 @@ def generate(env):
|
||||||
|
|
||||||
def BitKeeperFactory(env=env):
|
def BitKeeperFactory(env=env):
|
||||||
""" """
|
""" """
|
||||||
return SCons.Builder.Builder(action = "$BITKEEPERCOM", env = env)
|
act = SCons.Action.Action("$BITKEEPERCOM", "$BITKEEPERCOMSTR")
|
||||||
|
return SCons.Builder.Builder(action = act, env = env)
|
||||||
|
|
||||||
#setattr(env, 'BitKeeper', BitKeeperFactory)
|
#setattr(env, 'BitKeeper', BitKeeperFactory)
|
||||||
env.BitKeeper = BitKeeperFactory
|
env.BitKeeper = BitKeeperFactory
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,8 +31,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/CVS.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/CVS.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
@ -48,7 +49,8 @@ def generate(env):
|
||||||
# be across a network and must use POSIX slashes as separators.
|
# be across a network and must use POSIX slashes as separators.
|
||||||
module = module + '/'
|
module = module + '/'
|
||||||
env['CVSCOM'] = '$CVS $CVSFLAGS co $CVSCOFLAGS -d ${TARGET.dir} $CVSMODULE${TARGET.posix}'
|
env['CVSCOM'] = '$CVS $CVSFLAGS co $CVSCOFLAGS -d ${TARGET.dir} $CVSMODULE${TARGET.posix}'
|
||||||
return SCons.Builder.Builder(action = '$CVSCOM',
|
act = SCons.Action.Action('$CVSCOM', '$CVSCOMSTR')
|
||||||
|
return SCons.Builder.Builder(action = act,
|
||||||
env = env,
|
env = env,
|
||||||
CVSREPOSITORY = repos,
|
CVSREPOSITORY = repos,
|
||||||
CVSMODULE = module)
|
CVSMODULE = module)
|
|
@ -5,7 +5,7 @@ Stuff for processing Java.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ Stuff for processing Java.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/JavaCommon.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/JavaCommon.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -42,13 +42,19 @@ if java_parsing:
|
||||||
# This is a really cool parser from Charles Crain
|
# This is a really cool parser from Charles Crain
|
||||||
# that finds appropriate class names in Java source.
|
# that finds appropriate class names in Java source.
|
||||||
|
|
||||||
# A regular expression that will find, in a java file: newlines;
|
# A regular expression that will find, in a java file:
|
||||||
# any alphanumeric token (keyword, class name, specifier); open or
|
# newlines;
|
||||||
# close brackets; a single-line comment "//"; the multi-line comment
|
# double-backslashes;
|
||||||
# begin and end tokens /* and */; single or double quotes; and
|
# a single-line comment "//";
|
||||||
# single or double quotes preceeded by a backslash.
|
# single or double quotes preceeded by a backslash;
|
||||||
_reToken = re.compile(r'(\n|//|\\[\'"]|[\'"\{\}]|[A-Za-z_][\w\.]*|' +
|
# single quotes, double quotes, open or close braces, semi-colons;
|
||||||
r'/\*|\*/)')
|
# any alphanumeric token (keyword, class name, specifier);
|
||||||
|
# the multi-line comment begin and end tokens /* and */;
|
||||||
|
# array declarations "[]";
|
||||||
|
# semi-colons;
|
||||||
|
# periods.
|
||||||
|
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.]|' +
|
||||||
|
r'[A-Za-z_][\w\.]*|/\*|\*/|\[\])')
|
||||||
|
|
||||||
class OuterState:
|
class OuterState:
|
||||||
"""The initial state for parsing a Java file for classes,
|
"""The initial state for parsing a Java file for classes,
|
||||||
|
@ -61,6 +67,9 @@ if java_parsing:
|
||||||
self.nextAnon = 1
|
self.nextAnon = 1
|
||||||
self.package = None
|
self.package = None
|
||||||
|
|
||||||
|
def trace(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def __getClassState(self):
|
def __getClassState(self):
|
||||||
try:
|
try:
|
||||||
return self.classState
|
return self.classState
|
||||||
|
@ -93,41 +102,51 @@ if java_parsing:
|
||||||
self.skipState = ret
|
self.skipState = ret
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def openBracket(self):
|
||||||
|
self.brackets = self.brackets + 1
|
||||||
|
|
||||||
|
def closeBracket(self):
|
||||||
|
self.brackets = self.brackets - 1
|
||||||
|
if len(self.stackBrackets) and \
|
||||||
|
self.brackets == self.stackBrackets[-1]:
|
||||||
|
self.listOutputs.append(string.join(self.listClasses, '$'))
|
||||||
|
self.listClasses.pop()
|
||||||
|
self.stackBrackets.pop()
|
||||||
|
|
||||||
def parseToken(self, token):
|
def parseToken(self, token):
|
||||||
if token[:2] == '//':
|
if token[:2] == '//':
|
||||||
return IgnoreState('\n', self)
|
return IgnoreState('\n', self)
|
||||||
elif token == '/*':
|
elif token == '/*':
|
||||||
return IgnoreState('*/', self)
|
return IgnoreState('*/', self)
|
||||||
elif token == '{':
|
elif token == '{':
|
||||||
self.brackets = self.brackets + 1
|
self.openBracket()
|
||||||
elif token == '}':
|
elif token == '}':
|
||||||
self.brackets = self.brackets - 1
|
self.closeBracket()
|
||||||
if len(self.stackBrackets) and \
|
elif token in [ '"', "'" ]:
|
||||||
self.brackets == self.stackBrackets[-1]:
|
|
||||||
self.listOutputs.append(string.join(self.listClasses, '$'))
|
|
||||||
self.listClasses.pop()
|
|
||||||
self.stackBrackets.pop()
|
|
||||||
elif token == '"' or token == "'":
|
|
||||||
return IgnoreState(token, self)
|
return IgnoreState(token, self)
|
||||||
elif token == "new":
|
elif token == "new":
|
||||||
# anonymous inner class
|
# anonymous inner class
|
||||||
if len(self.listClasses) > 0:
|
if len(self.listClasses) > 0:
|
||||||
return self.__getAnonClassState()
|
return self.__getAnonClassState()
|
||||||
return self.__getSkipState() # Skip the class name
|
return self.__getSkipState() # Skip the class name
|
||||||
elif token == 'class' or token == 'interface':
|
elif token in ['class', 'interface', 'enum']:
|
||||||
if len(self.listClasses) == 0:
|
if len(self.listClasses) == 0:
|
||||||
self.nextAnon = 1
|
self.nextAnon = 1
|
||||||
self.stackBrackets.append(self.brackets)
|
self.stackBrackets.append(self.brackets)
|
||||||
return self.__getClassState()
|
return self.__getClassState()
|
||||||
elif token == 'package':
|
elif token == 'package':
|
||||||
return self.__getPackageState()
|
return self.__getPackageState()
|
||||||
|
elif token == '.':
|
||||||
|
# Skip the attribute, it might be named "class", in which
|
||||||
|
# case we don't want to treat the following token as
|
||||||
|
# an inner class name...
|
||||||
|
return self.__getSkipState()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def addAnonClass(self):
|
def addAnonClass(self):
|
||||||
"""Add an anonymous inner class"""
|
"""Add an anonymous inner class"""
|
||||||
clazz = self.listClasses[0]
|
clazz = self.listClasses[0]
|
||||||
self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
|
self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
|
||||||
self.brackets = self.brackets + 1
|
|
||||||
self.nextAnon = self.nextAnon + 1
|
self.nextAnon = self.nextAnon + 1
|
||||||
|
|
||||||
def setPackage(self, package):
|
def setPackage(self, package):
|
||||||
|
@ -140,9 +159,17 @@ if java_parsing:
|
||||||
self.outer_state = outer_state
|
self.outer_state = outer_state
|
||||||
self.tokens_to_find = 2
|
self.tokens_to_find = 2
|
||||||
def parseToken(self, token):
|
def parseToken(self, token):
|
||||||
# This is an anonymous class if and only if the next token is a bracket
|
# This is an anonymous class if and only if the next
|
||||||
|
# non-whitespace token is a bracket
|
||||||
|
if token == '\n':
|
||||||
|
return self
|
||||||
if token == '{':
|
if token == '{':
|
||||||
|
self.outer_state.openBracket()
|
||||||
self.outer_state.addAnonClass()
|
self.outer_state.addAnonClass()
|
||||||
|
elif token == '}':
|
||||||
|
self.outer_state.closeBracket()
|
||||||
|
elif token in ['"', "'"]:
|
||||||
|
return IgnoreState(token, self)
|
||||||
return self.outer_state
|
return self.outer_state
|
||||||
|
|
||||||
class SkipState:
|
class SkipState:
|
||||||
|
@ -193,7 +220,7 @@ if java_parsing:
|
||||||
def parse_java_file(fn):
|
def parse_java_file(fn):
|
||||||
return parse_java(open(fn, 'r').read())
|
return parse_java(open(fn, 'r').read())
|
||||||
|
|
||||||
def parse_java(contents):
|
def parse_java(contents, trace=None):
|
||||||
"""Parse a .java file and return a double of package directory,
|
"""Parse a .java file and return a double of package directory,
|
||||||
plus a list of .class files that compiling that .java file will
|
plus a list of .class files that compiling that .java file will
|
||||||
produce"""
|
produce"""
|
||||||
|
@ -204,6 +231,7 @@ if java_parsing:
|
||||||
# The regex produces a bunch of groups, but only one will
|
# The regex produces a bunch of groups, but only one will
|
||||||
# have anything in it.
|
# have anything in it.
|
||||||
currstate = currstate.parseToken(token)
|
currstate = currstate.parseToken(token)
|
||||||
|
if trace: trace(token, currstate)
|
||||||
if initial.package:
|
if initial.package:
|
||||||
package = string.replace(initial.package, '.', os.sep)
|
package = string.replace(initial.package, '.', os.sep)
|
||||||
return (package, initial.listOutputs)
|
return (package, initial.listOutputs)
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,10 +31,11 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/Perforce.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/Perforce.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
@ -42,18 +43,21 @@ import SCons.Util
|
||||||
# This function should maybe be moved to SCons.Util?
|
# This function should maybe be moved to SCons.Util?
|
||||||
from SCons.Tool.PharLapCommon import addPathIfNotExists
|
from SCons.Tool.PharLapCommon import addPathIfNotExists
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Variables that we want to import from the base OS environment.
|
# Variables that we want to import from the base OS environment.
|
||||||
_import_env = [ 'P4PORT', 'P4CLIENT', 'P4USER', 'USER', 'USERNAME', 'P4PASSWD',
|
_import_env = [ 'P4PORT', 'P4CLIENT', 'P4USER', 'USER', 'USERNAME', 'P4PASSWD',
|
||||||
'P4CHARSET', 'P4LANGUAGE', 'SYSTEMROOT' ]
|
'P4CHARSET', 'P4LANGUAGE', 'SYSTEMROOT' ]
|
||||||
|
|
||||||
|
PerforceAction = SCons.Action.Action('$P4COM', '$P4COMSTR')
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add a Builder factory function and construction variables for
|
"""Add a Builder factory function and construction variables for
|
||||||
Perforce to an Environment."""
|
Perforce to an Environment."""
|
||||||
|
|
||||||
def PerforceFactory(env=env):
|
def PerforceFactory(env=env):
|
||||||
""" """
|
""" """
|
||||||
return SCons.Builder.Builder(action = '$P4COM',
|
return SCons.Builder.Builder(action = PerforceAction, env = env)
|
||||||
env = env)
|
|
||||||
|
|
||||||
#setattr(env, 'Perforce', PerforceFactory)
|
#setattr(env, 'Perforce', PerforceFactory)
|
||||||
env.Perforce = PerforceFactory
|
env.Perforce = PerforceFactory
|
||||||
|
@ -70,8 +74,8 @@ def generate(env):
|
||||||
# Perforce seems to use the PWD environment variable rather than
|
# Perforce seems to use the PWD environment variable rather than
|
||||||
# calling getcwd() for itself, which is odd. If no PWD variable
|
# calling getcwd() for itself, which is odd. If no PWD variable
|
||||||
# is present, p4 WILL call getcwd, but this seems to cause problems
|
# is present, p4 WILL call getcwd, but this seems to cause problems
|
||||||
# with good ol' Win32's tilde-mangling for long file names.
|
# with good ol' Windows's tilde-mangling for long file names.
|
||||||
environ['PWD'] = SCons.Node.FS.default_fs.Dir('#').get_abspath()
|
environ['PWD'] = env.Dir('#').get_abspath()
|
||||||
|
|
||||||
for var in _import_env:
|
for var in _import_env:
|
||||||
v = os.environ.get(var)
|
v = os.environ.get(var)
|
|
@ -7,7 +7,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -29,7 +29,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/PharLapCommon.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/PharLapCommon.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,8 +31,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/RCS.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/RCS.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
@ -42,7 +43,8 @@ def generate(env):
|
||||||
|
|
||||||
def RCSFactory(env=env):
|
def RCSFactory(env=env):
|
||||||
""" """
|
""" """
|
||||||
return SCons.Builder.Builder(action = '$RCS_COCOM', env = env)
|
act = SCons.Action.Action('$RCS_COCOM', '$RCS_COCOMSTR')
|
||||||
|
return SCons.Builder.Builder(action = act, env = env)
|
||||||
|
|
||||||
#setattr(env, 'RCS', RCSFactory)
|
#setattr(env, 'RCS', RCSFactory)
|
||||||
env.RCS = RCSFactory
|
env.RCS = RCSFactory
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,8 +31,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/SCCS.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/SCCS.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
@ -42,7 +43,8 @@ def generate(env):
|
||||||
|
|
||||||
def SCCSFactory(env=env):
|
def SCCSFactory(env=env):
|
||||||
""" """
|
""" """
|
||||||
return SCons.Builder.Builder(action = '$SCCSCOM', env = env)
|
act = SCons.Action.Action('$SCCSCOM', '$SCCSCOMSTR')
|
||||||
|
return SCons.Builder.Builder(action = act, env = env)
|
||||||
|
|
||||||
#setattr(env, 'SCCS', SCCSFactory)
|
#setattr(env, 'SCCS', SCCSFactory)
|
||||||
env.SCCS = SCCSFactory
|
env.SCCS = SCCSFactory
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,10 +31,11 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/Subversion.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/Subversion.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
@ -47,7 +48,8 @@ def generate(env):
|
||||||
# fail if repos is not an absolute path name?
|
# fail if repos is not an absolute path name?
|
||||||
if module != '':
|
if module != '':
|
||||||
module = os.path.join(module, '')
|
module = os.path.join(module, '')
|
||||||
return SCons.Builder.Builder(action = '$SVNCOM',
|
act = SCons.Action.Action('$SVNCOM', '$SVNCOMSTR')
|
||||||
|
return SCons.Builder.Builder(action = act,
|
||||||
env = env,
|
env = env,
|
||||||
SVNREPOSITORY = repos,
|
SVNREPOSITORY = repos,
|
||||||
SVNMODULE = module)
|
SVNMODULE = module)
|
|
@ -14,7 +14,7 @@ tool definition.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -36,58 +36,129 @@ tool definition.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/__init__.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/__init__.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import imp
|
import imp
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import SCons.Builder
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
import SCons.Defaults
|
import SCons.Scanner
|
||||||
|
import SCons.Scanner.C
|
||||||
|
import SCons.Scanner.D
|
||||||
|
import SCons.Scanner.LaTeX
|
||||||
|
import SCons.Scanner.Prog
|
||||||
|
|
||||||
class ToolSpec:
|
DefaultToolpath=[]
|
||||||
def __init__(self, name):
|
|
||||||
|
CScanner = SCons.Scanner.C.CScanner()
|
||||||
|
DScanner = SCons.Scanner.D.DScanner()
|
||||||
|
LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner()
|
||||||
|
ProgramScanner = SCons.Scanner.Prog.ProgramScanner()
|
||||||
|
SourceFileScanner = SCons.Scanner.Base({}, name='SourceFileScanner')
|
||||||
|
|
||||||
|
CSuffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc",
|
||||||
|
".h", ".H", ".hxx", ".hpp", ".hh",
|
||||||
|
".F", ".fpp", ".FPP",
|
||||||
|
".m", ".mm",
|
||||||
|
".S", ".spp", ".SPP"]
|
||||||
|
|
||||||
|
DSuffixes = ['.d']
|
||||||
|
|
||||||
|
IDLSuffixes = [".idl", ".IDL"]
|
||||||
|
|
||||||
|
LaTeXSuffixes = [".tex", ".ltx", ".latex"]
|
||||||
|
|
||||||
|
for suffix in CSuffixes:
|
||||||
|
SourceFileScanner.add_scanner(suffix, CScanner)
|
||||||
|
|
||||||
|
for suffix in DSuffixes:
|
||||||
|
SourceFileScanner.add_scanner(suffix, DScanner)
|
||||||
|
|
||||||
|
for suffix in LaTeXSuffixes:
|
||||||
|
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
|
||||||
|
|
||||||
|
class Tool:
|
||||||
|
def __init__(self, name, toolpath=[], **kw):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.toolpath = toolpath + DefaultToolpath
|
||||||
|
# remember these so we can merge them into the call
|
||||||
|
self.init_kw = kw
|
||||||
|
|
||||||
|
module = self._tool_module()
|
||||||
|
self.generate = module.generate
|
||||||
|
self.exists = module.exists
|
||||||
|
|
||||||
|
def _tool_module(self):
|
||||||
|
oldpythonpath = sys.path
|
||||||
|
sys.path = self.toolpath + sys.path
|
||||||
|
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
file, path, desc = imp.find_module(self.name, self.toolpath)
|
||||||
|
try:
|
||||||
|
return imp.load_module(self.name, file, path, desc)
|
||||||
|
finally:
|
||||||
|
if file:
|
||||||
|
file.close()
|
||||||
|
except ImportError, e:
|
||||||
|
try:
|
||||||
|
import zipimport
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
for aPath in self.toolpath:
|
||||||
|
try:
|
||||||
|
importer = zipimport.zipimporter(aPath)
|
||||||
|
return importer.load_module(self.name)
|
||||||
|
except ImportError, e:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
sys.path = oldpythonpath
|
||||||
|
|
||||||
|
full_name = 'SCons.Tool.' + self.name
|
||||||
|
try:
|
||||||
|
return sys.modules[full_name]
|
||||||
|
except KeyError:
|
||||||
|
try:
|
||||||
|
smpath = sys.modules['SCons.Tool'].__path__
|
||||||
|
try:
|
||||||
|
file, path, desc = imp.find_module(self.name, smpath)
|
||||||
|
module = imp.load_module(full_name, file, path, desc)
|
||||||
|
setattr(SCons.Tool, self.name, module)
|
||||||
|
if file:
|
||||||
|
file.close()
|
||||||
|
return module
|
||||||
|
except ImportError, e:
|
||||||
|
try:
|
||||||
|
import zipimport
|
||||||
|
importer = zipimport.zipimporter( sys.modules['SCons.Tool'].__path__[0] )
|
||||||
|
module = importer.load_module(full_name)
|
||||||
|
setattr(SCons.Tool, self.name, module)
|
||||||
|
return module
|
||||||
|
except ImportError, e:
|
||||||
|
m = "No tool named '%s': %s" % (self.name, e)
|
||||||
|
raise SCons.Errors.UserError, m
|
||||||
|
except ImportError, e:
|
||||||
|
m = "No tool named '%s': %s" % (self.name, e)
|
||||||
|
raise SCons.Errors.UserError, m
|
||||||
|
|
||||||
def __call__(self, env, *args, **kw):
|
def __call__(self, env, *args, **kw):
|
||||||
|
if self.init_kw is not None:
|
||||||
|
# Merge call kws into init kws;
|
||||||
|
# but don't bash self.init_kw.
|
||||||
|
if kw is not None:
|
||||||
|
call_kw = kw
|
||||||
|
kw = self.init_kw.copy()
|
||||||
|
kw.update(call_kw)
|
||||||
|
else:
|
||||||
|
kw = self.init_kw
|
||||||
env.Append(TOOLS = [ self.name ])
|
env.Append(TOOLS = [ self.name ])
|
||||||
apply(self.generate, ( env, ) + args, kw)
|
apply(self.generate, ( env, ) + args, kw)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def Tool(name, toolpath=[]):
|
|
||||||
"Select a canned Tool specification, optionally searching in toolpath."
|
|
||||||
|
|
||||||
try:
|
|
||||||
file, path, desc = imp.find_module(name, toolpath)
|
|
||||||
try:
|
|
||||||
module = imp.load_module(name, file, path, desc)
|
|
||||||
spec = ToolSpec(name)
|
|
||||||
spec.generate = module.generate
|
|
||||||
spec.exists = module.exists
|
|
||||||
return spec
|
|
||||||
finally:
|
|
||||||
if file:
|
|
||||||
file.close()
|
|
||||||
except ImportError, e:
|
|
||||||
pass
|
|
||||||
|
|
||||||
full_name = 'SCons.Tool.' + name
|
|
||||||
if not sys.modules.has_key(full_name):
|
|
||||||
try:
|
|
||||||
file, path, desc = imp.find_module(name,
|
|
||||||
sys.modules['SCons.Tool'].__path__)
|
|
||||||
mod = imp.load_module(full_name, file, path, desc)
|
|
||||||
setattr(SCons.Tool, name, mod)
|
|
||||||
except ImportError, e:
|
|
||||||
raise SCons.Errors.UserError, "No tool named '%s': %s" % (name, e)
|
|
||||||
if file:
|
|
||||||
file.close()
|
|
||||||
spec = ToolSpec(name)
|
|
||||||
spec.generate = sys.modules[full_name].generate
|
|
||||||
spec.exists = sys.modules[full_name].exists
|
|
||||||
return spec
|
|
||||||
|
|
||||||
def createProgBuilder(env):
|
def createProgBuilder(env):
|
||||||
"""This is a utility function that creates the Program
|
"""This is a utility function that creates the Program
|
||||||
Builder in an Environment if it is not there already.
|
Builder in an Environment if it is not there already.
|
||||||
|
@ -98,13 +169,14 @@ def createProgBuilder(env):
|
||||||
try:
|
try:
|
||||||
program = env['BUILDERS']['Program']
|
program = env['BUILDERS']['Program']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
import SCons.Defaults
|
||||||
program = SCons.Builder.Builder(action = SCons.Defaults.LinkAction,
|
program = SCons.Builder.Builder(action = SCons.Defaults.LinkAction,
|
||||||
emitter = '$PROGEMITTER',
|
emitter = '$PROGEMITTER',
|
||||||
prefix = '$PROGPREFIX',
|
prefix = '$PROGPREFIX',
|
||||||
suffix = '$PROGSUFFIX',
|
suffix = '$PROGSUFFIX',
|
||||||
src_suffix = '$OBJSUFFIX',
|
src_suffix = '$OBJSUFFIX',
|
||||||
src_builder = 'Object',
|
src_builder = 'Object',
|
||||||
target_scanner = SCons.Defaults.ProgScan)
|
target_scanner = ProgramScanner)
|
||||||
env['BUILDERS']['Program'] = program
|
env['BUILDERS']['Program'] = program
|
||||||
|
|
||||||
return program
|
return program
|
||||||
|
@ -119,7 +191,12 @@ def createStaticLibBuilder(env):
|
||||||
try:
|
try:
|
||||||
static_lib = env['BUILDERS']['StaticLibrary']
|
static_lib = env['BUILDERS']['StaticLibrary']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
static_lib = SCons.Builder.Builder(action = SCons.Defaults.ArAction,
|
action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
|
||||||
|
if env.Detect('ranlib'):
|
||||||
|
ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
|
||||||
|
action_list.append(ranlib_action)
|
||||||
|
|
||||||
|
static_lib = SCons.Builder.Builder(action = action_list,
|
||||||
emitter = '$LIBEMITTER',
|
emitter = '$LIBEMITTER',
|
||||||
prefix = '$LIBPREFIX',
|
prefix = '$LIBPREFIX',
|
||||||
suffix = '$LIBSUFFIX',
|
suffix = '$LIBSUFFIX',
|
||||||
|
@ -140,19 +217,44 @@ def createSharedLibBuilder(env):
|
||||||
try:
|
try:
|
||||||
shared_lib = env['BUILDERS']['SharedLibrary']
|
shared_lib = env['BUILDERS']['SharedLibrary']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
import SCons.Defaults
|
||||||
action_list = [ SCons.Defaults.SharedCheck,
|
action_list = [ SCons.Defaults.SharedCheck,
|
||||||
SCons.Defaults.ShLinkAction ]
|
SCons.Defaults.ShLinkAction ]
|
||||||
shared_lib = SCons.Builder.Builder(action = action_list,
|
shared_lib = SCons.Builder.Builder(action = action_list,
|
||||||
emitter = "$SHLIBEMITTER",
|
emitter = "$SHLIBEMITTER",
|
||||||
prefix = '$SHLIBPREFIX',
|
prefix = '$SHLIBPREFIX',
|
||||||
suffix = '$SHLIBSUFFIX',
|
suffix = '$SHLIBSUFFIX',
|
||||||
target_scanner = SCons.Defaults.ProgScan,
|
target_scanner = ProgramScanner,
|
||||||
src_suffix = '$SHOBJSUFFIX',
|
src_suffix = '$SHOBJSUFFIX',
|
||||||
src_builder = 'SharedObject')
|
src_builder = 'SharedObject')
|
||||||
env['BUILDERS']['SharedLibrary'] = shared_lib
|
env['BUILDERS']['SharedLibrary'] = shared_lib
|
||||||
|
|
||||||
return shared_lib
|
return shared_lib
|
||||||
|
|
||||||
|
def createLoadableModuleBuilder(env):
|
||||||
|
"""This is a utility function that creates the LoadableModule
|
||||||
|
Builder in an Environment if it is not there already.
|
||||||
|
|
||||||
|
If it is already there, we return the existing one.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
ld_module = env['BUILDERS']['LoadableModule']
|
||||||
|
except KeyError:
|
||||||
|
import SCons.Defaults
|
||||||
|
action_list = [ SCons.Defaults.SharedCheck,
|
||||||
|
SCons.Defaults.LdModuleLinkAction ]
|
||||||
|
ld_module = SCons.Builder.Builder(action = action_list,
|
||||||
|
emitter = "$SHLIBEMITTER",
|
||||||
|
prefix = '$LDMODULEPREFIX',
|
||||||
|
suffix = '$LDMODULESUFFIX',
|
||||||
|
target_scanner = ProgramScanner,
|
||||||
|
src_suffix = '$SHOBJSUFFIX',
|
||||||
|
src_builder = 'SharedObject')
|
||||||
|
env['BUILDERS']['LoadableModule'] = ld_module
|
||||||
|
|
||||||
|
return ld_module
|
||||||
|
|
||||||
def createObjBuilders(env):
|
def createObjBuilders(env):
|
||||||
"""This is a utility function that creates the StaticObject
|
"""This is a utility function that creates the StaticObject
|
||||||
and SharedObject Builders in an Environment if they
|
and SharedObject Builders in an Environment if they
|
||||||
|
@ -166,6 +268,7 @@ def createObjBuilders(env):
|
||||||
The return is a 2-tuple of (StaticObject, SharedObject)
|
The return is a 2-tuple of (StaticObject, SharedObject)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
static_obj = env['BUILDERS']['StaticObject']
|
static_obj = env['BUILDERS']['StaticObject']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -174,7 +277,8 @@ def createObjBuilders(env):
|
||||||
prefix = '$OBJPREFIX',
|
prefix = '$OBJPREFIX',
|
||||||
suffix = '$OBJSUFFIX',
|
suffix = '$OBJSUFFIX',
|
||||||
src_builder = ['CFile', 'CXXFile'],
|
src_builder = ['CFile', 'CXXFile'],
|
||||||
source_scanner = SCons.Defaults.ObjSourceScan, single_source=1)
|
source_scanner = SourceFileScanner,
|
||||||
|
single_source = 1)
|
||||||
env['BUILDERS']['StaticObject'] = static_obj
|
env['BUILDERS']['StaticObject'] = static_obj
|
||||||
env['BUILDERS']['Object'] = static_obj
|
env['BUILDERS']['Object'] = static_obj
|
||||||
|
|
||||||
|
@ -186,7 +290,8 @@ def createObjBuilders(env):
|
||||||
prefix = '$SHOBJPREFIX',
|
prefix = '$SHOBJPREFIX',
|
||||||
suffix = '$SHOBJSUFFIX',
|
suffix = '$SHOBJSUFFIX',
|
||||||
src_builder = ['CFile', 'CXXFile'],
|
src_builder = ['CFile', 'CXXFile'],
|
||||||
source_scanner = SCons.Defaults.ObjSourceScan, single_source=1)
|
source_scanner = SourceFileScanner,
|
||||||
|
single_source = 1)
|
||||||
env['BUILDERS']['SharedObject'] = shared_obj
|
env['BUILDERS']['SharedObject'] = shared_obj
|
||||||
|
|
||||||
return (static_obj, shared_obj)
|
return (static_obj, shared_obj)
|
||||||
|
@ -246,10 +351,10 @@ def tool_list(platform, env):
|
||||||
if str(platform) == 'win32':
|
if str(platform) == 'win32':
|
||||||
"prefer Microsoft tools on Windows"
|
"prefer Microsoft tools on Windows"
|
||||||
linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ]
|
linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ]
|
||||||
c_compilers = ['msvc', 'mingw', 'gcc', 'icl', 'icc', 'cc', 'bcc32' ]
|
c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
|
||||||
cxx_compilers = ['msvc', 'icc', 'g++', 'c++', 'bcc32' ]
|
cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ]
|
||||||
assemblers = ['masm', 'nasm', 'gas', '386asm' ]
|
assemblers = ['masm', 'nasm', 'gas', '386asm' ]
|
||||||
fortran_compilers = ['g77', 'ifl', 'cvf', 'fortran']
|
fortran_compilers = ['g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran']
|
||||||
ars = ['mslib', 'ar', 'tlib']
|
ars = ['mslib', 'ar', 'tlib']
|
||||||
elif str(platform) == 'os2':
|
elif str(platform) == 'os2':
|
||||||
"prefer IBM tools on OS/2"
|
"prefer IBM tools on OS/2"
|
||||||
|
@ -265,7 +370,7 @@ def tool_list(platform, env):
|
||||||
c_compilers = ['sgicc', 'gcc', 'cc']
|
c_compilers = ['sgicc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['sgic++', 'g++', 'c++']
|
cxx_compilers = ['sgic++', 'g++', 'c++']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['f77', 'g77', 'fortran']
|
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
||||||
ars = ['sgiar']
|
ars = ['sgiar']
|
||||||
elif str(platform) == 'sunos':
|
elif str(platform) == 'sunos':
|
||||||
"prefer Forte tools on SunOS"
|
"prefer Forte tools on SunOS"
|
||||||
|
@ -273,7 +378,7 @@ def tool_list(platform, env):
|
||||||
c_compilers = ['suncc', 'gcc', 'cc']
|
c_compilers = ['suncc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['sunc++', 'g++', 'c++']
|
cxx_compilers = ['sunc++', 'g++', 'c++']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['f77', 'g77', 'fortran']
|
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
||||||
ars = ['sunar']
|
ars = ['sunar']
|
||||||
elif str(platform) == 'hpux':
|
elif str(platform) == 'hpux':
|
||||||
"prefer aCC tools on HP-UX"
|
"prefer aCC tools on HP-UX"
|
||||||
|
@ -281,7 +386,7 @@ def tool_list(platform, env):
|
||||||
c_compilers = ['hpcc', 'gcc', 'cc']
|
c_compilers = ['hpcc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['hpc++', 'g++', 'c++']
|
cxx_compilers = ['hpc++', 'g++', 'c++']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['f77', 'g77', 'fortran']
|
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
||||||
ars = ['ar']
|
ars = ['ar']
|
||||||
elif str(platform) == 'aix':
|
elif str(platform) == 'aix':
|
||||||
"prefer AIX Visual Age tools on AIX"
|
"prefer AIX Visual Age tools on AIX"
|
||||||
|
@ -289,15 +394,23 @@ def tool_list(platform, env):
|
||||||
c_compilers = ['aixcc', 'gcc', 'cc']
|
c_compilers = ['aixcc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['aixc++', 'g++', 'c++']
|
cxx_compilers = ['aixc++', 'g++', 'c++']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['aixf77', 'g77', 'fortran']
|
fortran_compilers = ['f95', 'f90', 'aixf77', 'g77', 'fortran']
|
||||||
|
ars = ['ar']
|
||||||
|
elif str(platform) == 'darwin':
|
||||||
|
"prefer GNU tools on Mac OS X, except for some linkers and IBM tools"
|
||||||
|
linkers = ['applelink', 'gnulink']
|
||||||
|
c_compilers = ['gcc', 'cc']
|
||||||
|
cxx_compilers = ['g++', 'c++']
|
||||||
|
assemblers = ['as']
|
||||||
|
fortran_compilers = ['f95', 'f90', 'g77']
|
||||||
ars = ['ar']
|
ars = ['ar']
|
||||||
else:
|
else:
|
||||||
"prefer GNU tools on all other platforms"
|
"prefer GNU tools on all other platforms"
|
||||||
linkers = ['gnulink', 'mslink', 'ilink']
|
linkers = ['gnulink', 'mslink', 'ilink']
|
||||||
c_compilers = ['gcc', 'msvc', 'icc', 'cc']
|
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
||||||
cxx_compilers = ['g++', 'msvc', 'icc', 'c++']
|
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
|
||||||
assemblers = ['gas', 'nasm', 'masm']
|
assemblers = ['gas', 'nasm', 'masm']
|
||||||
fortran_compilers = ['g77', 'ifort', 'ifl', 'fortran']
|
fortran_compilers = ['f95', 'f90', 'g77', 'ifort', 'ifl', 'fortran']
|
||||||
ars = ['ar', 'mslib']
|
ars = ['ar', 'mslib']
|
||||||
|
|
||||||
c_compiler = FindTool(c_compilers, env) or c_compilers[0]
|
c_compiler = FindTool(c_compilers, env) or c_compilers[0]
|
||||||
|
@ -314,7 +427,7 @@ def tool_list(platform, env):
|
||||||
ar = None
|
ar = None
|
||||||
else:
|
else:
|
||||||
# Don't use g++ if the C compiler has built-in C++ support:
|
# Don't use g++ if the C compiler has built-in C++ support:
|
||||||
if c_compiler in ('msvc', 'icc'):
|
if c_compiler in ('msvc', 'intelc', 'icc'):
|
||||||
cxx_compiler = None
|
cxx_compiler = None
|
||||||
else:
|
else:
|
||||||
cxx_compiler = FindTool(cxx_compilers, env) or cxx_compilers[0]
|
cxx_compiler = FindTool(cxx_compilers, env) or cxx_compilers[0]
|
||||||
|
@ -327,12 +440,15 @@ def tool_list(platform, env):
|
||||||
'dmd',
|
'dmd',
|
||||||
'dvipdf', 'dvips', 'gs',
|
'dvipdf', 'dvips', 'gs',
|
||||||
'jar', 'javac', 'javah',
|
'jar', 'javac', 'javah',
|
||||||
'latex', 'lex', 'm4', 'midl', 'msvs',
|
'latex', 'lex',
|
||||||
|
'm4', 'midl', 'msvs',
|
||||||
'pdflatex', 'pdftex', 'Perforce',
|
'pdflatex', 'pdftex', 'Perforce',
|
||||||
'RCS', 'rmic', 'SCCS',
|
'RCS', 'rmic', 'rpcgen',
|
||||||
|
'SCCS',
|
||||||
# 'Subversion',
|
# 'Subversion',
|
||||||
'swig',
|
'swig',
|
||||||
'tar', 'tex', 'yacc', 'zip'],
|
'tar', 'tex',
|
||||||
|
'yacc', 'zip'],
|
||||||
env)
|
env)
|
||||||
|
|
||||||
tools = ([linker, c_compiler, cxx_compiler,
|
tools = ([linker, c_compiler, cxx_compiler,
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,12 +31,11 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixc++.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixc++.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import SCons.Platform.aix
|
import SCons.Platform.aix
|
||||||
import SCons.Script.SConscript
|
|
||||||
|
|
||||||
cplusplus = __import__('c++', globals(), locals(), [])
|
cplusplus = __import__('c++', globals(), locals(), [])
|
||||||
|
|
||||||
|
@ -48,7 +47,7 @@ def get_xlc(env):
|
||||||
return SCons.Platform.aix.get_xlc(env, xlc, xlc_r, packages)
|
return SCons.Platform.aix.get_xlc(env, xlc, xlc_r, packages)
|
||||||
|
|
||||||
def smart_cxxflags(source, target, env, for_signature):
|
def smart_cxxflags(source, target, env, for_signature):
|
||||||
build_dir = SCons.Script.SConscript.GetBuildPath()
|
build_dir = env.GetBuildPath()
|
||||||
if build_dir:
|
if build_dir:
|
||||||
return '-qtempinc=' + os.path.join(build_dir, 'tempinc')
|
return '-qtempinc=' + os.path.join(build_dir, 'tempinc')
|
||||||
return ''
|
return ''
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixcc.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixcc.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixf77.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixf77.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixlink.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/aixlink.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
|
@ -1,6 +1,6 @@
|
||||||
"""SCons.Tool.swig
|
"""SCons.Tool.applelink
|
||||||
|
|
||||||
Tool-specific initialization for swig.
|
Tool-specific initialization for the Apple gnu-like linker.
|
||||||
|
|
||||||
There normally shouldn't be any need to import this module directly.
|
There normally shouldn't be any need to import this module directly.
|
||||||
It will usually be imported through the generic SCons.Tool.Tool()
|
It will usually be imported through the generic SCons.Tool.Tool()
|
||||||
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,33 +31,34 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/swig.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/applelink.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
|
||||||
import SCons.Tool
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
def swigSuffixEmitter(env, source):
|
import gnulink
|
||||||
if '-c++' in SCons.Util.CLVar(env.subst("$SWIGFLAGS")):
|
|
||||||
return '$SWIGCXXFILESUFFIX'
|
|
||||||
else:
|
|
||||||
return '$SWIGCFILESUFFIX'
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for swig to an Environment."""
|
"""Add Builders and construction variables for applelink to an
|
||||||
c_file, cxx_file = SCons.Tool.createCFileBuilders(env)
|
Environment."""
|
||||||
|
gnulink.generate(env)
|
||||||
|
|
||||||
c_file.suffix['.i'] = swigSuffixEmitter
|
env['FRAMEWORKPATHPREFIX'] = '-F'
|
||||||
cxx_file.suffix['.i'] = swigSuffixEmitter
|
env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__)}'
|
||||||
|
env['_FRAMEWORKS'] = '${_concat("-framework ", FRAMEWORKS, "", __env__)}'
|
||||||
|
env['LINKCOM'] = env['LINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS'
|
||||||
|
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib')
|
||||||
|
env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS'
|
||||||
|
|
||||||
|
# override the default for loadable modules, which are different
|
||||||
|
# on OS X than dynamic shared libs. echoing what XCode does for
|
||||||
|
# pre/suffixes:
|
||||||
|
env['LDMODULEPREFIX'] = ''
|
||||||
|
env['LDMODULESUFFIX'] = ''
|
||||||
|
env['LDMODULEFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -bundle')
|
||||||
|
env['LDMODULECOM'] = '$LDMODULE -o ${TARGET} $LDMODULEFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
|
||||||
|
|
||||||
c_file.add_action('.i', '$SWIGCOM')
|
|
||||||
cxx_file.add_action('.i', '$SWIGCOM')
|
|
||||||
|
|
||||||
env['SWIG'] = 'swig'
|
|
||||||
env['SWIGFLAGS'] = SCons.Util.CLVar('')
|
|
||||||
env['SWIGCFILESUFFIX'] = '_wrap$CFILESUFFIX'
|
|
||||||
env['SWIGCXXFILESUFFIX'] = '_wrap$CXXFILESUFFIX'
|
|
||||||
env['SWIGCOM'] = '$SWIG $SWIGFLAGS -o $TARGET $SOURCES'
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return env.Detect(['swig'])
|
import sys
|
||||||
|
return sys.platform == 'darwin'
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,28 +31,27 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/ar.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/ar.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for ar to an Environment."""
|
"""Add Builders and construction variables for ar to an Environment."""
|
||||||
SCons.Tool.createStaticLibBuilder(env)
|
SCons.Tool.createStaticLibBuilder(env)
|
||||||
|
|
||||||
arcom = '$AR $ARFLAGS $TARGET $SOURCES'
|
|
||||||
ranlib = 'ranlib'
|
|
||||||
if env.Detect(ranlib):
|
|
||||||
arcom = arcom + '\n$RANLIB $RANLIBFLAGS $TARGET'
|
|
||||||
|
|
||||||
env['AR'] = 'ar'
|
env['AR'] = 'ar'
|
||||||
env['ARFLAGS'] = SCons.Util.CLVar('r')
|
env['ARFLAGS'] = SCons.Util.CLVar('rc')
|
||||||
env['RANLIB'] = ranlib
|
env['ARCOM'] = '$AR $ARFLAGS $TARGET $SOURCES'
|
||||||
env['RANLIBFLAGS'] = SCons.Util.CLVar('')
|
|
||||||
env['ARCOM'] = arcom
|
|
||||||
env['LIBPREFIX'] = 'lib'
|
env['LIBPREFIX'] = 'lib'
|
||||||
env['LIBSUFFIX'] = '.a'
|
env['LIBSUFFIX'] = '.a'
|
||||||
|
|
||||||
|
if env.Detect('ranlib'):
|
||||||
|
env['RANLIB'] = 'ranlib'
|
||||||
|
env['RANLIBFLAGS'] = SCons.Util.CLVar('')
|
||||||
|
env['RANLIBCOM'] = '$RANLIB $RANLIBFLAGS $TARGET'
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return env.Detect('ar')
|
return env.Detect('ar')
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/as.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/as.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
@ -52,16 +52,21 @@ def generate(env):
|
||||||
|
|
||||||
for suffix in ASSuffixes:
|
for suffix in ASSuffixes:
|
||||||
static_obj.add_action(suffix, SCons.Defaults.ASAction)
|
static_obj.add_action(suffix, SCons.Defaults.ASAction)
|
||||||
|
shared_obj.add_action(suffix, SCons.Defaults.ASAction)
|
||||||
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
||||||
|
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
|
||||||
|
|
||||||
for suffix in ASPPSuffixes:
|
for suffix in ASPPSuffixes:
|
||||||
static_obj.add_action(suffix, SCons.Defaults.ASPPAction)
|
static_obj.add_action(suffix, SCons.Defaults.ASPPAction)
|
||||||
|
shared_obj.add_action(suffix, SCons.Defaults.ASPPAction)
|
||||||
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
||||||
|
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
|
||||||
|
|
||||||
env['AS'] = env.Detect(assemblers) or 'as'
|
env['AS'] = env.Detect(assemblers) or 'as'
|
||||||
env['ASFLAGS'] = SCons.Util.CLVar('')
|
env['ASFLAGS'] = SCons.Util.CLVar('')
|
||||||
env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES'
|
env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES'
|
||||||
env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
|
env['ASPPFLAGS'] = '$ASFLAGS'
|
||||||
|
env['ASPPCOM'] = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return env.Detect(assemblers)
|
return env.Detect(assemblers)
|
|
@ -5,7 +5,7 @@ XXX
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ XXX
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/bcc32.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/bcc32.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -63,10 +63,12 @@ def generate(env):
|
||||||
|
|
||||||
env['CC'] = 'bcc32'
|
env['CC'] = 'bcc32'
|
||||||
env['CCFLAGS'] = SCons.Util.CLVar('')
|
env['CCFLAGS'] = SCons.Util.CLVar('')
|
||||||
env['CCCOM'] = '$CC -q $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
|
env['CFLAGS'] = SCons.Util.CLVar('')
|
||||||
|
env['CCCOM'] = '$CC -q $CFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o$TARGET $SOURCES'
|
||||||
env['SHCC'] = '$CC'
|
env['SHCC'] = '$CC'
|
||||||
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
||||||
env['SHCCCOM'] = '$SHCC -WD $SHCCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
|
env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS')
|
||||||
|
env['SHCCCOM'] = '$SHCC -WD $SHCFLAGS $SHCCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o$TARGET $SOURCES'
|
||||||
env['CPPDEFPREFIX'] = '-D'
|
env['CPPDEFPREFIX'] = '-D'
|
||||||
env['CPPDEFSUFFIX'] = ''
|
env['CPPDEFSUFFIX'] = ''
|
||||||
env['INCPREFIX'] = '-I'
|
env['INCPREFIX'] = '-I'
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/c++.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/c++.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ import SCons.Util
|
||||||
|
|
||||||
compilers = ['CC', 'c++']
|
compilers = ['CC', 'c++']
|
||||||
|
|
||||||
CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++']
|
CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++', '.mm']
|
||||||
if SCons.Util.case_sensitive_suffixes('.c', '.C'):
|
if SCons.Util.case_sensitive_suffixes('.c', '.C'):
|
||||||
CXXSuffixes.append('.C')
|
CXXSuffixes.append('.C')
|
||||||
|
|
||||||
|
@ -60,6 +60,8 @@ def generate(env):
|
||||||
Add Builders and construction variables for Visual Age C++ compilers
|
Add Builders and construction variables for Visual Age C++ compilers
|
||||||
to an Environment.
|
to an Environment.
|
||||||
"""
|
"""
|
||||||
|
import SCons.Tool
|
||||||
|
import SCons.Tool.cc
|
||||||
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
||||||
|
|
||||||
for suffix in CXXSuffixes:
|
for suffix in CXXSuffixes:
|
||||||
|
@ -68,12 +70,14 @@ def generate(env):
|
||||||
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
||||||
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
|
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
|
||||||
|
|
||||||
|
SCons.Tool.cc.add_common_cc_variables(env)
|
||||||
|
|
||||||
env['CXX'] = 'c++'
|
env['CXX'] = 'c++'
|
||||||
env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
||||||
env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
|
env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $_CCCOMCOM $SOURCES'
|
||||||
env['SHCXX'] = '$CXX'
|
env['SHCXX'] = '$CXX'
|
||||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
|
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
|
||||||
env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
|
env['SHCXXCOM'] = '$SHCXX -o $TARGET -c $SHCXXFLAGS $_CCCOMCOM $SOURCES'
|
||||||
|
|
||||||
env['CPPDEFPREFIX'] = '-D'
|
env['CPPDEFPREFIX'] = '-D'
|
||||||
env['CPPDEFSUFFIX'] = ''
|
env['CPPDEFSUFFIX'] = ''
|
|
@ -8,7 +8,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,16 +30,38 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/cc.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/cc.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
CSuffixes = ['.c']
|
CSuffixes = ['.c', '.m']
|
||||||
if not SCons.Util.case_sensitive_suffixes('.c', '.C'):
|
if not SCons.Util.case_sensitive_suffixes('.c', '.C'):
|
||||||
CSuffixes.append('.C')
|
CSuffixes.append('.C')
|
||||||
|
|
||||||
|
def add_common_cc_variables(env):
|
||||||
|
"""
|
||||||
|
Add underlying common "C compiler" variables that
|
||||||
|
are used by multiple tools (specifically, c++).
|
||||||
|
"""
|
||||||
|
if not env.has_key('_CCCOMCOM'):
|
||||||
|
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'
|
||||||
|
|
||||||
|
if not env.has_key('CCFLAGS'):
|
||||||
|
env['CCFLAGS'] = SCons.Util.CLVar('')
|
||||||
|
|
||||||
|
if not env.has_key('SHCCFLAGS'):
|
||||||
|
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""
|
"""
|
||||||
Add Builders and construction variables for C compilers to an Environment.
|
Add Builders and construction variables for C compilers to an Environment.
|
||||||
|
@ -52,12 +74,14 @@ def generate(env):
|
||||||
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
|
||||||
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
|
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
|
||||||
|
|
||||||
|
add_common_cc_variables(env)
|
||||||
|
|
||||||
env['CC'] = 'cc'
|
env['CC'] = 'cc'
|
||||||
env['CCFLAGS'] = SCons.Util.CLVar('')
|
env['CFLAGS'] = SCons.Util.CLVar('')
|
||||||
env['CCCOM'] = '$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
|
env['CCCOM'] = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES'
|
||||||
env['SHCC'] = '$CC'
|
env['SHCC'] = '$CC'
|
||||||
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS')
|
||||||
env['SHCCCOM'] = '$SHCC $SHCCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
|
env['SHCCCOM'] = '$SHCC -o $TARGET -c $SHCFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES'
|
||||||
|
|
||||||
env['CPPDEFPREFIX'] = '-D'
|
env['CPPDEFPREFIX'] = '-D'
|
||||||
env['CPPDEFSUFFIX'] = ''
|
env['CPPDEFSUFFIX'] = ''
|
|
@ -5,7 +5,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,9 +27,8 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/cvf.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/cvf.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Util
|
|
||||||
import fortran
|
import fortran
|
||||||
|
|
||||||
compilers = ['f90']
|
compilers = ['f90']
|
||||||
|
@ -40,10 +39,10 @@ def generate(env):
|
||||||
fortran.generate(env)
|
fortran.generate(env)
|
||||||
|
|
||||||
env['FORTRAN'] = 'f90'
|
env['FORTRAN'] = 'f90'
|
||||||
env['FORTRANCOM'] = '$FORTRAN $FORTRANFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.win32} /object:${TARGET.win32}'
|
env['FORTRANCOM'] = '$FORTRAN $FORTRANFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}'
|
||||||
env['FORTRANPPCOM'] = '$FORTRAN $FORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.win32} /object:${TARGET.win32}'
|
env['FORTRANPPCOM'] = '$FORTRAN $FORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}'
|
||||||
env['SHFORTRANCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.win32} /object:${TARGET.win32}'
|
env['SHFORTRANCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}'
|
||||||
env['SHFORTRANPPCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.win32} /object:${TARGET.win32}'
|
env['SHFORTRANPPCOM'] = '$SHFORTRAN $SHFORTRANFLAGS $CPPFLAGS $_CPPDEFFLAGS $_FORTRANMODFLAG $_FORTRANINCFLAGS /compile_only ${SOURCES.windows} /object:${TARGET.windows}'
|
||||||
env['OBJSUFFIX'] = '.obj'
|
env['OBJSUFFIX'] = '.obj'
|
||||||
env['FORTRANMODDIR'] = '${TARGET.dir}'
|
env['FORTRANMODDIR'] = '${TARGET.dir}'
|
||||||
env['FORTRANMODDIRPREFIX'] = '/module:'
|
env['FORTRANMODDIRPREFIX'] = '/module:'
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/default.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/default.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
|
|
@ -7,7 +7,7 @@ Coded by Andy Friesen (andy@ikagames.com)
|
||||||
15 November 2003
|
15 November 2003
|
||||||
|
|
||||||
There are a number of problems with this script at this point in time.
|
There are a number of problems with this script at this point in time.
|
||||||
The one that irritates me the most is the win32 linker setup. The D
|
The one that irritates me the most is the Windows linker setup. The D
|
||||||
linker doesn't have a way to add lib paths on the commandline, as far
|
linker doesn't have a way to add lib paths on the commandline, as far
|
||||||
as I can see. You have to specify paths relative to the SConscript or
|
as I can see. You have to specify paths relative to the SConscript or
|
||||||
use absolute paths. To hack around it, add '#/blah'. This will link
|
use absolute paths. To hack around it, add '#/blah'. This will link
|
||||||
|
@ -31,7 +31,7 @@ Lib tool variables:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -53,15 +53,16 @@ Lib tool variables:
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dmd.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dmd.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import string
|
import string
|
||||||
|
|
||||||
import SCons.Tool
|
import SCons.Action
|
||||||
import SCons.Scanner.D
|
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
|
import SCons.Scanner.D
|
||||||
|
import SCons.Tool
|
||||||
|
|
||||||
# Adapted from c++.py
|
# Adapted from c++.py
|
||||||
def isD(source):
|
def isD(source):
|
||||||
|
@ -85,14 +86,16 @@ def generate(env):
|
||||||
|
|
||||||
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
||||||
|
|
||||||
static_obj.add_action('.d', '$DCOM')
|
DAction = SCons.Action.Action('$DCOM', '$DCOMSTR')
|
||||||
shared_obj.add_action('.d', '$DCOM')
|
|
||||||
|
static_obj.add_action('.d', DAction)
|
||||||
|
shared_obj.add_action('.d', DAction)
|
||||||
static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
|
static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
|
||||||
shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
|
shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
|
||||||
|
|
||||||
env['DC'] = 'dmd'
|
env['DC'] = 'dmd'
|
||||||
env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of$TARGET $SOURCES'
|
env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of$TARGET $SOURCES'
|
||||||
env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs)} $)'
|
env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||||
env['_DVERFLAGS'] = '$( ${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)} $)'
|
env['_DVERFLAGS'] = '$( ${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)} $)'
|
||||||
env['_DDEBUGFLAGS'] = '$( ${_concat(DDEBUGPREFIX, DDEBUG, DDEBUGSUFFIX, __env__)} $)'
|
env['_DDEBUGFLAGS'] = '$( ${_concat(DDEBUGPREFIX, DDEBUG, DDEBUGSUFFIX, __env__)} $)'
|
||||||
env['_DFLAGS'] = '$( ${_concat(DFLAGPREFIX, DFLAGS, DFLAGSUFFIX, __env__)} $)'
|
env['_DFLAGS'] = '$( ${_concat(DFLAGPREFIX, DFLAGS, DFLAGSUFFIX, __env__)} $)'
|
||||||
|
@ -129,7 +132,7 @@ def generate(env):
|
||||||
env['DLIB'] = 'lib'
|
env['DLIB'] = 'lib'
|
||||||
env['DLIBCOM'] = '$DLIB $_DLIBFLAGS -c $TARGET $SOURCES $_DLINKLIBFLAGS'
|
env['DLIBCOM'] = '$DLIB $_DLIBFLAGS -c $TARGET $SOURCES $_DLINKLIBFLAGS'
|
||||||
|
|
||||||
env['_DLINKLIBFLAGS'] = '$( ${_concat(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, __env__, RDirs)} $)'
|
env['_DLINKLIBFLAGS'] = '$( ${_concat(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||||
env['_DLIBFLAGS'] = '$( ${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)} $)'
|
env['_DLIBFLAGS'] = '$( ${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)} $)'
|
||||||
env['DLINKFLAGS'] = []
|
env['DLINKFLAGS'] = []
|
||||||
env['DLIBLINKPREFIX'] = ''
|
env['DLIBLINKPREFIX'] = ''
|
||||||
|
@ -152,6 +155,10 @@ def generate(env):
|
||||||
def _smartLink(source, target, env, for_signature,
|
def _smartLink(source, target, env, for_signature,
|
||||||
defaultLinker=linkcom):
|
defaultLinker=linkcom):
|
||||||
if isD(source):
|
if isD(source):
|
||||||
|
# XXX I'm not sure how to add a $DLINKCOMSTR variable
|
||||||
|
# so that it works with this _smartLink() logic,
|
||||||
|
# and I don't have a D compiler/linker to try it out,
|
||||||
|
# so we'll leave it alone for now.
|
||||||
return '$DLINKCOM'
|
return '$DLINKCOM'
|
||||||
else:
|
else:
|
||||||
return defaultLinker
|
return defaultLinker
|
||||||
|
@ -164,6 +171,10 @@ def generate(env):
|
||||||
def _smartLib(source, target, env, for_signature,
|
def _smartLib(source, target, env, for_signature,
|
||||||
defaultLib=arcom):
|
defaultLib=arcom):
|
||||||
if isD(source):
|
if isD(source):
|
||||||
|
# XXX I'm not sure how to add a $DLIBCOMSTR variable
|
||||||
|
# so that it works with this _smartLib() logic, and
|
||||||
|
# I don't have a D compiler/archiver to try it out,
|
||||||
|
# so we'll leave it alone for now.
|
||||||
return '$DLIBCOM'
|
return '$DLIBCOM'
|
||||||
else:
|
else:
|
||||||
return defaultLib
|
return defaultLib
|
||||||
|
@ -190,6 +201,8 @@ def generate(env):
|
||||||
env.Append(LIBS = ['phobos'])
|
env.Append(LIBS = ['phobos'])
|
||||||
if 'pthread' not in libs:
|
if 'pthread' not in libs:
|
||||||
env.Append(LIBS = ['pthread'])
|
env.Append(LIBS = ['pthread'])
|
||||||
|
if 'm' not in libs:
|
||||||
|
env.Append(LIBS = ['m'])
|
||||||
return defaultLinker
|
return defaultLinker
|
||||||
env['SMART_LINKCOM'] = smart_link[linkcom] = _smartLink
|
env['SMART_LINKCOM'] = smart_link[linkcom] = _smartLink
|
||||||
|
|
58
scons/scons-local-0.97/SCons/Tool/dvi.py
Normal file
58
scons/scons-local-0.97/SCons/Tool/dvi.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
"""SCons.Tool.dvi
|
||||||
|
|
||||||
|
Common DVI Builder definition for various other Tool modules that use it.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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/engine/SCons/Tool/dvi.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.Builder
|
||||||
|
import SCons.Tool
|
||||||
|
|
||||||
|
DVIBuilder = None
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
try:
|
||||||
|
env['BUILDERS']['DVI']
|
||||||
|
except KeyError:
|
||||||
|
global DVIBuilder
|
||||||
|
|
||||||
|
if DVIBuilder is None:
|
||||||
|
# The suffix is hard-coded to '.dvi', not configurable via a
|
||||||
|
# construction variable like $DVISUFFIX, because the output
|
||||||
|
# file name is hard-coded within TeX.
|
||||||
|
DVIBuilder = SCons.Builder.Builder(action = {},
|
||||||
|
source_scanner = SCons.Tool.LaTeXScanner,
|
||||||
|
suffix = '.dvi',
|
||||||
|
emitter = {},
|
||||||
|
source_ext_match = None)
|
||||||
|
|
||||||
|
env['BUILDERS']['DVI'] = DVIBuilder
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
# This only puts a skeleton Builder in place, so if someone
|
||||||
|
# references this Tool directly, it's always "available."
|
||||||
|
return 1
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,23 +31,42 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dvipdf.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dvipdf.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
|
import SCons.Action
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
|
import SCons.Tool.pdf
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
PDFAction = None
|
||||||
|
|
||||||
|
def PDFEmitter(target, source, env):
|
||||||
|
"""Strips any .aux or .log files from the input source list.
|
||||||
|
These are created by the TeX Builder that in all likelihood was
|
||||||
|
used to generate the .dvi file we're using as input, and we only
|
||||||
|
care about the .dvi file.
|
||||||
|
"""
|
||||||
|
def strip_suffixes(n):
|
||||||
|
return not SCons.Util.splitext(str(n))[1] in ['.aux', '.log']
|
||||||
|
source = filter(strip_suffixes, source)
|
||||||
|
return (target, source)
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for dvipdf to an Environment."""
|
"""Add Builders and construction variables for dvipdf to an Environment."""
|
||||||
try:
|
global PDFAction
|
||||||
bld = env['BUILDERS']['PDF']
|
if PDFAction is None:
|
||||||
except KeyError:
|
PDFAction = SCons.Action.Action('$DVIPDFCOM', '$DVIPDFCOMSTR')
|
||||||
bld = SCons.Defaults.PDF()
|
|
||||||
env['BUILDERS']['PDF'] = bld
|
import pdf
|
||||||
bld.add_action('.dvi', '$PDFCOM')
|
pdf.generate(env)
|
||||||
|
|
||||||
|
bld = env['BUILDERS']['PDF']
|
||||||
|
bld.add_action('.dvi', PDFAction)
|
||||||
|
bld.add_emitter('.dvi', PDFEmitter)
|
||||||
|
|
||||||
env['DVIPDF'] = 'dvipdf'
|
env['DVIPDF'] = 'dvipdf'
|
||||||
env['DVIPDFFLAGS'] = SCons.Util.CLVar('')
|
env['DVIPDFFLAGS'] = SCons.Util.CLVar('')
|
||||||
env['DVIPDFCOM'] = '$DVIPDF $DVIPDFFLAGS $SOURCES $TARGET'
|
env['DVIPDFCOM'] = 'cd ${TARGET.dir} && $DVIPDF $DVIPDFFLAGS ${SOURCE.file} ${TARGET.file}'
|
||||||
|
|
||||||
# Deprecated synonym.
|
# Deprecated synonym.
|
||||||
env['PDFCOM'] = ['$DVIPDFCOM']
|
env['PDFCOM'] = ['$DVIPDFCOM']
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,25 +31,38 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dvips.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/dvips.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
import SCons.Defaults
|
import SCons.Builder
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
PostScript = SCons.Builder.Builder(action = '$PSCOM',
|
PSAction = None
|
||||||
prefix = '$PSPREFIX',
|
PSBuilder = None
|
||||||
suffix = '$PSSUFFIX',
|
|
||||||
src_suffix = '.dvi',
|
|
||||||
src_builder = 'DVI')
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for dvips to an Environment."""
|
"""Add Builders and construction variables for dvips to an Environment."""
|
||||||
env['BUILDERS']['PostScript'] = PostScript
|
global PSAction
|
||||||
|
if PSAction is None:
|
||||||
|
PSAction = SCons.Action.Action('$PSCOM', '$PSCOMSTR')
|
||||||
|
|
||||||
|
global PSBuilder
|
||||||
|
if PSBuilder is None:
|
||||||
|
PSBuilder = SCons.Builder.Builder(action = PSAction,
|
||||||
|
prefix = '$PSPREFIX',
|
||||||
|
suffix = '$PSSUFFIX',
|
||||||
|
src_suffix = '.dvi',
|
||||||
|
src_builder = 'DVI')
|
||||||
|
|
||||||
|
env['BUILDERS']['PostScript'] = PSBuilder
|
||||||
|
|
||||||
env['DVIPS'] = 'dvips'
|
env['DVIPS'] = 'dvips'
|
||||||
env['DVIPSFLAGS'] = SCons.Util.CLVar('')
|
env['DVIPSFLAGS'] = SCons.Util.CLVar('')
|
||||||
env['PSCOM'] = '$DVIPS $DVIPSFLAGS -o $TARGET $SOURCES'
|
# I'm not quite sure I got the directories and filenames right for build_dir
|
||||||
|
# We need to be in the correct directory for the sake of latex \includegraphics eps included files.
|
||||||
|
env['PSCOM'] = 'cd ${TARGET.dir} && $DVIPS $DVIPSFLAGS -o ${TARGET.file} ${SOURCE.file}'
|
||||||
|
env['PSPREFIX'] = ''
|
||||||
|
env['PSSUFFIX'] = '.ps'
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return env.Detect('dvips')
|
return env.Detect('dvips')
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f77.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f77.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Scanner.Fortran
|
import SCons.Scanner.Fortran
|
||||||
|
@ -53,7 +53,8 @@ else:
|
||||||
F77Scan = SCons.Scanner.Fortran.FortranScan("F77PATH")
|
F77Scan = SCons.Scanner.Fortran.FortranScan("F77PATH")
|
||||||
|
|
||||||
for suffix in F77Suffixes + F77PPSuffixes:
|
for suffix in F77Suffixes + F77PPSuffixes:
|
||||||
SCons.Defaults.ObjSourceScan.add_scanner(suffix, F77Scan)
|
SCons.Tool.SourceFileScanner.add_scanner(suffix, F77Scan)
|
||||||
|
del suffix
|
||||||
|
|
||||||
#
|
#
|
||||||
fVLG = fortran.VariableListGenerator
|
fVLG = fortran.VariableListGenerator
|
||||||
|
@ -61,19 +62,23 @@ fVLG = fortran.VariableListGenerator
|
||||||
F77Generator = fVLG('F77', 'FORTRAN', '_FORTRAND')
|
F77Generator = fVLG('F77', 'FORTRAN', '_FORTRAND')
|
||||||
F77FlagsGenerator = fVLG('F77FLAGS', 'FORTRANFLAGS')
|
F77FlagsGenerator = fVLG('F77FLAGS', 'FORTRANFLAGS')
|
||||||
F77CommandGenerator = fVLG('F77COM', 'FORTRANCOM', '_F77COMD')
|
F77CommandGenerator = fVLG('F77COM', 'FORTRANCOM', '_F77COMD')
|
||||||
|
F77CommandStrGenerator = fVLG('F77COMSTR', 'FORTRANCOMSTR', '_F77COMSTRD')
|
||||||
F77PPCommandGenerator = fVLG('F77PPCOM', 'FORTRANPPCOM', '_F77PPCOMD')
|
F77PPCommandGenerator = fVLG('F77PPCOM', 'FORTRANPPCOM', '_F77PPCOMD')
|
||||||
|
F77PPCommandStrGenerator = fVLG('F77PPCOMSTR', 'FORTRANPPCOMSTR', '_F77PPCOMSTRD')
|
||||||
ShF77Generator = fVLG('SHF77', 'SHFORTRAN', 'F77', 'FORTRAN', '_FORTRAND')
|
ShF77Generator = fVLG('SHF77', 'SHFORTRAN', 'F77', 'FORTRAN', '_FORTRAND')
|
||||||
ShF77FlagsGenerator = fVLG('SHF77FLAGS', 'SHFORTRANFLAGS')
|
ShF77FlagsGenerator = fVLG('SHF77FLAGS', 'SHFORTRANFLAGS')
|
||||||
ShF77CommandGenerator = fVLG('SHF77COM', 'SHFORTRANCOM', '_SHF77COMD')
|
ShF77CommandGenerator = fVLG('SHF77COM', 'SHFORTRANCOM', '_SHF77COMD')
|
||||||
|
ShF77CommandStrGenerator = fVLG('SHF77COMSTR', 'SHFORTRANCOMSTR', '_SHF77COMSTRD')
|
||||||
ShF77PPCommandGenerator = fVLG('SHF77PPCOM', 'SHFORTRANPPCOM', '_SHF77PPCOMD')
|
ShF77PPCommandGenerator = fVLG('SHF77PPCOM', 'SHFORTRANPPCOM', '_SHF77PPCOMD')
|
||||||
|
ShF77PPCommandStrGenerator = fVLG('SHF77PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF77PPCOMSTRD')
|
||||||
|
|
||||||
del fVLG
|
del fVLG
|
||||||
|
|
||||||
#
|
#
|
||||||
F77Action = SCons.Action.Action('$_F77COMG ')
|
F77Action = SCons.Action.Action('$_F77COMG ', '$_F77COMSTRG')
|
||||||
F77PPAction = SCons.Action.Action('$_F77PPCOMG ')
|
F77PPAction = SCons.Action.Action('$_F77PPCOMG ', '$_F77PPCOMSTRG')
|
||||||
ShF77Action = SCons.Action.Action('$_SHF77COMG ')
|
ShF77Action = SCons.Action.Action('$_SHF77COMG ', '$_SHF77COMSTRG')
|
||||||
ShF77PPAction = SCons.Action.Action('$_SHF77PPCOMG ')
|
ShF77PPAction = SCons.Action.Action('$_SHF77PPCOMG ', '$_SHF77PPCOMSTRG')
|
||||||
|
|
||||||
def add_to_env(env):
|
def add_to_env(env):
|
||||||
"""Add Builders and construction variables for f77 to an Environment."""
|
"""Add Builders and construction variables for f77 to an Environment."""
|
||||||
|
@ -93,22 +98,26 @@ def add_to_env(env):
|
||||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||||
|
|
||||||
env['_F77G'] = F77Generator
|
env['_F77G'] = F77Generator
|
||||||
env['_F77FLAGSG'] = F77FlagsGenerator
|
env['_F77FLAGSG'] = F77FlagsGenerator
|
||||||
env['_F77COMG'] = F77CommandGenerator
|
env['_F77COMG'] = F77CommandGenerator
|
||||||
env['_F77PPCOMG'] = F77PPCommandGenerator
|
env['_F77PPCOMG'] = F77PPCommandGenerator
|
||||||
|
env['_F77COMSTRG'] = F77CommandStrGenerator
|
||||||
|
env['_F77PPCOMSTRG'] = F77PPCommandStrGenerator
|
||||||
|
|
||||||
env['_SHF77G'] = ShF77Generator
|
env['_SHF77G'] = ShF77Generator
|
||||||
env['_SHF77FLAGSG'] = ShF77FlagsGenerator
|
env['_SHF77FLAGSG'] = ShF77FlagsGenerator
|
||||||
env['_SHF77COMG'] = ShF77CommandGenerator
|
env['_SHF77COMG'] = ShF77CommandGenerator
|
||||||
env['_SHF77PPCOMG'] = ShF77PPCommandGenerator
|
env['_SHF77PPCOMG'] = ShF77PPCommandGenerator
|
||||||
|
env['_SHF77COMSTRG'] = ShF77CommandStrGenerator
|
||||||
|
env['_SHF77PPCOMSTRG'] = ShF77PPCommandStrGenerator
|
||||||
|
|
||||||
env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs)} $)'
|
env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||||
|
|
||||||
env['_F77COMD'] = '$_F77G $_F77FLAGSG $_F77INCFLAGS -c -o $TARGET $SOURCES'
|
env['_F77COMD'] = '$_F77G -o $TARGET -c $_F77FLAGSG $_F77INCFLAGS $SOURCES'
|
||||||
env['_F77PPCOMD'] = '$_F77G $_F77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
|
env['_F77PPCOMD'] = '$_F77G -o $TARGET -c $_F77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS $SOURCES'
|
||||||
env['_SHF77COMD'] = '$_SHF77G $_SHF77FLAGSG $_F77INCFLAGS -c -o $TARGET $SOURCES'
|
env['_SHF77COMD'] = '$_SHF77G -o $TARGET -c $_SHF77FLAGSG $_F77INCFLAGS $SOURCES'
|
||||||
env['_SHF77PPCOMD'] = '$_SHF77G $_SHF77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES'
|
env['_SHF77PPCOMD'] = '$_SHF77G -o $TARGET -c $_SHF77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS $SOURCES'
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
fortran.add_to_env(env)
|
fortran.add_to_env(env)
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f90.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f90.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Scanner.Fortran
|
import SCons.Scanner.Fortran
|
||||||
|
@ -53,7 +53,8 @@ else:
|
||||||
F90Scan = SCons.Scanner.Fortran.FortranScan("F90PATH")
|
F90Scan = SCons.Scanner.Fortran.FortranScan("F90PATH")
|
||||||
|
|
||||||
for suffix in F90Suffixes + F90PPSuffixes:
|
for suffix in F90Suffixes + F90PPSuffixes:
|
||||||
SCons.Defaults.ObjSourceScan.add_scanner(suffix, F90Scan)
|
SCons.Tool.SourceFileScanner.add_scanner(suffix, F90Scan)
|
||||||
|
del suffix
|
||||||
|
|
||||||
#
|
#
|
||||||
fVLG = fortran.VariableListGenerator
|
fVLG = fortran.VariableListGenerator
|
||||||
|
@ -61,19 +62,23 @@ fVLG = fortran.VariableListGenerator
|
||||||
F90Generator = fVLG('F90', 'FORTRAN', '_FORTRAND')
|
F90Generator = fVLG('F90', 'FORTRAN', '_FORTRAND')
|
||||||
F90FlagsGenerator = fVLG('F90FLAGS', 'FORTRANFLAGS')
|
F90FlagsGenerator = fVLG('F90FLAGS', 'FORTRANFLAGS')
|
||||||
F90CommandGenerator = fVLG('F90COM', 'FORTRANCOM', '_F90COMD')
|
F90CommandGenerator = fVLG('F90COM', 'FORTRANCOM', '_F90COMD')
|
||||||
|
F90CommandStrGenerator = fVLG('F90COMSTR', 'FORTRANCOMSTR', '_F90COMSTRD')
|
||||||
F90PPCommandGenerator = fVLG('F90PPCOM', 'FORTRANPPCOM', '_F90PPCOMD')
|
F90PPCommandGenerator = fVLG('F90PPCOM', 'FORTRANPPCOM', '_F90PPCOMD')
|
||||||
|
F90PPCommandStrGenerator = fVLG('F90PPCOMSTR', 'FORTRANPPCOMSTR', '_F90PPCOMSTRD')
|
||||||
ShF90Generator = fVLG('SHF90', 'SHFORTRAN', 'F90', 'FORTRAN', '_FORTRAND')
|
ShF90Generator = fVLG('SHF90', 'SHFORTRAN', 'F90', 'FORTRAN', '_FORTRAND')
|
||||||
ShF90FlagsGenerator = fVLG('SHF90FLAGS', 'SHFORTRANFLAGS')
|
ShF90FlagsGenerator = fVLG('SHF90FLAGS', 'SHFORTRANFLAGS')
|
||||||
ShF90CommandGenerator = fVLG('SHF90COM', 'SHFORTRANCOM', '_SHF90COMD')
|
ShF90CommandGenerator = fVLG('SHF90COM', 'SHFORTRANCOM', '_SHF90COMD')
|
||||||
|
ShF90CommandStrGenerator = fVLG('SHF90COMSTR', 'SHFORTRANCOMSTR', '_SHF90COMSTRD')
|
||||||
ShF90PPCommandGenerator = fVLG('SHF90PPCOM', 'SHFORTRANPPCOM', '_SHF90PPCOMD')
|
ShF90PPCommandGenerator = fVLG('SHF90PPCOM', 'SHFORTRANPPCOM', '_SHF90PPCOMD')
|
||||||
|
ShF90PPCommandStrGenerator = fVLG('SHF90PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF90PPCOMSTRD')
|
||||||
|
|
||||||
del fVLG
|
del fVLG
|
||||||
|
|
||||||
#
|
#
|
||||||
F90Action = SCons.Action.Action('$_F90COMG ')
|
F90Action = SCons.Action.Action('$_F90COMG ', '$_F90COMSTRG')
|
||||||
F90PPAction = SCons.Action.Action('$_F90PPCOMG ')
|
F90PPAction = SCons.Action.Action('$_F90PPCOMG ', '$_F90PPCOMSTRG')
|
||||||
ShF90Action = SCons.Action.Action('$_SHF90COMG ')
|
ShF90Action = SCons.Action.Action('$_SHF90COMG ', '$_SHF90COMSTRG')
|
||||||
ShF90PPAction = SCons.Action.Action('$_SHF90PPCOMG ')
|
ShF90PPAction = SCons.Action.Action('$_SHF90PPCOMG ', '$_SHF90PPCOMSTRG')
|
||||||
|
|
||||||
def add_to_env(env):
|
def add_to_env(env):
|
||||||
"""Add Builders and construction variables for f90 to an Environment."""
|
"""Add Builders and construction variables for f90 to an Environment."""
|
||||||
|
@ -93,24 +98,32 @@ def add_to_env(env):
|
||||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||||
|
|
||||||
env['_F90G'] = F90Generator
|
env['_F90G'] = F90Generator
|
||||||
env['_F90FLAGSG'] = F90FlagsGenerator
|
env['_F90FLAGSG'] = F90FlagsGenerator
|
||||||
env['_F90COMG'] = F90CommandGenerator
|
env['_F90COMG'] = F90CommandGenerator
|
||||||
env['_F90PPCOMG'] = F90PPCommandGenerator
|
env['_F90COMSTRG'] = F90CommandStrGenerator
|
||||||
|
env['_F90PPCOMG'] = F90PPCommandGenerator
|
||||||
|
env['_F90PPCOMSTRG'] = F90PPCommandStrGenerator
|
||||||
|
|
||||||
env['_SHF90G'] = ShF90Generator
|
env['_SHF90G'] = ShF90Generator
|
||||||
env['_SHF90FLAGSG'] = ShF90FlagsGenerator
|
env['_SHF90FLAGSG'] = ShF90FlagsGenerator
|
||||||
env['_SHF90COMG'] = ShF90CommandGenerator
|
env['_SHF90COMG'] = ShF90CommandGenerator
|
||||||
env['_SHF90PPCOMG'] = ShF90PPCommandGenerator
|
env['_SHF90COMSTRG'] = ShF90CommandStrGenerator
|
||||||
|
env['_SHF90PPCOMG'] = ShF90PPCommandGenerator
|
||||||
|
env['_SHF90PPCOMSTRG'] = ShF90PPCommandStrGenerator
|
||||||
|
|
||||||
env['_F90INCFLAGS'] = '$( ${_concat(INCPREFIX, F90PATH, INCSUFFIX, __env__, RDirs)} $)'
|
env['_F90INCFLAGS'] = '$( ${_concat(INCPREFIX, F90PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||||
env['_F90COMD'] = '$_F90G $_F90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_F90COMD'] = '$_F90G -o $TARGET -c $_F90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_F90PPCOMD'] = '$_F90G $_F90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_F90PPCOMD'] = '$_F90G -o $TARGET -c $_F90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_SHF90COMD'] = '$_SHF90G $_SHF90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_SHF90COMD'] = '$_SHF90G -o $TARGET -c $_SHF90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_SHF90PPCOMD'] = '$_SHF90G $_SHF90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_SHF90PPCOMD'] = '$_SHF90G -o $TARGET -c $_SHF90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
fortran.add_to_env(env)
|
fortran.add_to_env(env)
|
||||||
|
|
||||||
|
import f77
|
||||||
|
f77.add_to_env(env)
|
||||||
|
|
||||||
add_to_env(env)
|
add_to_env(env)
|
||||||
|
|
||||||
env['_FORTRAND'] = env.Detect(compilers) or 'f90'
|
env['_FORTRAND'] = env.Detect(compilers) or 'f90'
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f95.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/f95.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
@ -52,7 +52,8 @@ else:
|
||||||
F95Scan = SCons.Scanner.Fortran.FortranScan("F95PATH")
|
F95Scan = SCons.Scanner.Fortran.FortranScan("F95PATH")
|
||||||
|
|
||||||
for suffix in F95Suffixes + F95PPSuffixes:
|
for suffix in F95Suffixes + F95PPSuffixes:
|
||||||
SCons.Defaults.ObjSourceScan.add_scanner(suffix, F95Scan)
|
SCons.Tool.SourceFileScanner.add_scanner(suffix, F95Scan)
|
||||||
|
del suffix
|
||||||
|
|
||||||
#
|
#
|
||||||
fVLG = fortran.VariableListGenerator
|
fVLG = fortran.VariableListGenerator
|
||||||
|
@ -60,19 +61,23 @@ fVLG = fortran.VariableListGenerator
|
||||||
F95Generator = fVLG('F95', 'FORTRAN', '_FORTRAND')
|
F95Generator = fVLG('F95', 'FORTRAN', '_FORTRAND')
|
||||||
F95FlagsGenerator = fVLG('F95FLAGS', 'FORTRANFLAGS')
|
F95FlagsGenerator = fVLG('F95FLAGS', 'FORTRANFLAGS')
|
||||||
F95CommandGenerator = fVLG('F95COM', 'FORTRANCOM', '_F95COMD')
|
F95CommandGenerator = fVLG('F95COM', 'FORTRANCOM', '_F95COMD')
|
||||||
|
F95CommandStrGenerator = fVLG('F95COMSTR', 'FORTRANCOMSTR', '_F95COMSTRD')
|
||||||
F95PPCommandGenerator = fVLG('F95PPCOM', 'FORTRANPPCOM', '_F95PPCOMD')
|
F95PPCommandGenerator = fVLG('F95PPCOM', 'FORTRANPPCOM', '_F95PPCOMD')
|
||||||
|
F95PPCommandStrGenerator = fVLG('F95PPCOMSTR', 'FORTRANPPCOMSTR', '_F95PPCOMSTRD')
|
||||||
ShF95Generator = fVLG('SHF95', 'SHFORTRAN', 'F95', 'FORTRAN', '_FORTRAND')
|
ShF95Generator = fVLG('SHF95', 'SHFORTRAN', 'F95', 'FORTRAN', '_FORTRAND')
|
||||||
ShF95FlagsGenerator = fVLG('SHF95FLAGS', 'SHFORTRANFLAGS')
|
ShF95FlagsGenerator = fVLG('SHF95FLAGS', 'SHFORTRANFLAGS')
|
||||||
ShF95CommandGenerator = fVLG('SHF95COM', 'SHFORTRANCOM', '_SHF95COMD')
|
ShF95CommandGenerator = fVLG('SHF95COM', 'SHFORTRANCOM', '_SHF95COMD')
|
||||||
|
ShF95CommandStrGenerator = fVLG('SHF95COMSTR', 'SHFORTRANCOMSTR', '_SHF95COMSTRD')
|
||||||
ShF95PPCommandGenerator = fVLG('SHF95PPCOM', 'SHFORTRANPPCOM', '_SHF95PPCOMD')
|
ShF95PPCommandGenerator = fVLG('SHF95PPCOM', 'SHFORTRANPPCOM', '_SHF95PPCOMD')
|
||||||
|
ShF95PPCommandStrGenerator = fVLG('SHF95PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF95PPCOMSTRD')
|
||||||
|
|
||||||
del fVLG
|
del fVLG
|
||||||
|
|
||||||
#
|
#
|
||||||
F95Action = SCons.Action.Action('$_F95COMG ')
|
F95Action = SCons.Action.Action('$_F95COMG ', '$_F95COMSTRG')
|
||||||
F95PPAction = SCons.Action.Action('$_F95PPCOMG ')
|
F95PPAction = SCons.Action.Action('$_F95PPCOMG ', '$_F95PPCOMSTRG')
|
||||||
ShF95Action = SCons.Action.Action('$_SHF95COMG ')
|
ShF95Action = SCons.Action.Action('$_SHF95COMG ', '$_SHF95COMSTRG')
|
||||||
ShF95PPAction = SCons.Action.Action('$_SHF95PPCOMG ')
|
ShF95PPAction = SCons.Action.Action('$_SHF95PPCOMG ', '$_SHF95PPCOMSTRG')
|
||||||
|
|
||||||
def add_to_env(env):
|
def add_to_env(env):
|
||||||
"""Add Builders and construction variables for f95 to an Environment."""
|
"""Add Builders and construction variables for f95 to an Environment."""
|
||||||
|
@ -92,25 +97,36 @@ def add_to_env(env):
|
||||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||||
|
|
||||||
env['_F95G'] = F95Generator
|
env['_F95G'] = F95Generator
|
||||||
env['_F95FLAGSG'] = F95FlagsGenerator
|
env['_F95FLAGSG'] = F95FlagsGenerator
|
||||||
env['_F95COMG'] = F95CommandGenerator
|
env['_F95COMG'] = F95CommandGenerator
|
||||||
env['_F95PPCOMG'] = F95PPCommandGenerator
|
env['_F95COMSTRG'] = F95CommandStrGenerator
|
||||||
|
env['_F95PPCOMG'] = F95PPCommandGenerator
|
||||||
|
env['_F95PPCOMSTRG'] = F95PPCommandStrGenerator
|
||||||
|
|
||||||
env['_SHF95G'] = ShF95Generator
|
env['_SHF95G'] = ShF95Generator
|
||||||
env['_SHF95FLAGSG'] = ShF95FlagsGenerator
|
env['_SHF95FLAGSG'] = ShF95FlagsGenerator
|
||||||
env['_SHF95COMG'] = ShF95CommandGenerator
|
env['_SHF95COMG'] = ShF95CommandGenerator
|
||||||
env['_SHF95PPCOMG'] = ShF95PPCommandGenerator
|
env['_SHF95COMSTRG'] = ShF95CommandStrGenerator
|
||||||
|
env['_SHF95PPCOMG'] = ShF95PPCommandGenerator
|
||||||
|
env['_SHF95PPCOMSTRG'] = ShF95PPCommandStrGenerator
|
||||||
|
|
||||||
env['_F95INCFLAGS'] = '$( ${_concat(INCPREFIX, F95PATH, INCSUFFIX, __env__, RDirs)} $)'
|
env['_F95INCFLAGS'] = '$( ${_concat(INCPREFIX, F95PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||||
|
|
||||||
env['_F95COMD'] = '$_F95G $_F95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_F95COMD'] = '$_F95G -o $TARGET -c $_F95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_F95PPCOMD'] = '$_F95G $_F95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_F95PPCOMD'] = '$_F95G -o $TARGET -c $_F95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_SHF95COMD'] = '$_SHF95G $_SHF95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_SHF95COMD'] = '$_SHF95G -o $TARGET -c $_SHF95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_SHF95PPCOMD'] = '$_SHF95G $_SHF95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_SHF95PPCOMD'] = '$_SHF95G -o $TARGET -c $_SHF95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
fortran.add_to_env(env)
|
fortran.add_to_env(env)
|
||||||
|
|
||||||
|
import f77
|
||||||
|
f77.add_to_env(env)
|
||||||
|
|
||||||
|
import f90
|
||||||
|
f90.add_to_env(env)
|
||||||
|
|
||||||
add_to_env(env)
|
add_to_env(env)
|
||||||
|
|
||||||
env['_FORTRAND'] = env.Detect(compilers) or 'f95'
|
env['_FORTRAND'] = env.Detect(compilers) or 'f95'
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/fortran.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/fortran.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
|
@ -62,7 +62,8 @@ else:
|
||||||
FortranScan = SCons.Scanner.Fortran.FortranScan("FORTRANPATH")
|
FortranScan = SCons.Scanner.Fortran.FortranScan("FORTRANPATH")
|
||||||
|
|
||||||
for suffix in FortranSuffixes + FortranPPSuffixes:
|
for suffix in FortranSuffixes + FortranPPSuffixes:
|
||||||
SCons.Defaults.ObjSourceScan.add_scanner(suffix, FortranScan)
|
SCons.Tool.SourceFileScanner.add_scanner(suffix, FortranScan)
|
||||||
|
del suffix
|
||||||
|
|
||||||
#
|
#
|
||||||
def _fortranEmitter(target, source, env):
|
def _fortranEmitter(target, source, env):
|
||||||
|
@ -78,9 +79,10 @@ def _fortranEmitter(target, source, env):
|
||||||
modules = SCons.Util.unique(modules)
|
modules = SCons.Util.unique(modules)
|
||||||
# Convert module name to a .mod filename
|
# Convert module name to a .mod filename
|
||||||
suffix = env.subst('$FORTRANMODSUFFIX')
|
suffix = env.subst('$FORTRANMODSUFFIX')
|
||||||
|
moddir = env.subst('$FORTRANMODDIR')
|
||||||
modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
|
modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
|
||||||
for m in modules:
|
for m in modules:
|
||||||
target.append(env.fs.File(m))
|
target.append(env.fs.File(m, moddir))
|
||||||
return (target, source)
|
return (target, source)
|
||||||
|
|
||||||
def FortranEmitter(target, source, env):
|
def FortranEmitter(target, source, env):
|
||||||
|
@ -94,7 +96,7 @@ def ShFortranEmitter(target, source, env):
|
||||||
class VariableListGenerator:
|
class VariableListGenerator:
|
||||||
def __init__(self, *variablelist):
|
def __init__(self, *variablelist):
|
||||||
self.variablelist = variablelist
|
self.variablelist = variablelist
|
||||||
def __call__(self, env, target, source, for_signature):
|
def __call__(self, env, target, source, for_signature=0):
|
||||||
for v in self.variablelist:
|
for v in self.variablelist:
|
||||||
try: return env[v]
|
try: return env[v]
|
||||||
except KeyError: pass
|
except KeyError: pass
|
||||||
|
@ -104,32 +106,40 @@ class VariableListGenerator:
|
||||||
FortranGenerator = VariableListGenerator('FORTRAN', 'F77', '_FORTRAND')
|
FortranGenerator = VariableListGenerator('FORTRAN', 'F77', '_FORTRAND')
|
||||||
FortranFlagsGenerator = VariableListGenerator('FORTRANFLAGS', 'F77FLAGS')
|
FortranFlagsGenerator = VariableListGenerator('FORTRANFLAGS', 'F77FLAGS')
|
||||||
FortranCommandGenerator = VariableListGenerator('FORTRANCOM', 'F77COM', '_FORTRANCOMD')
|
FortranCommandGenerator = VariableListGenerator('FORTRANCOM', 'F77COM', '_FORTRANCOMD')
|
||||||
|
FortranCommandStrGenerator = VariableListGenerator('FORTRANCOMSTR', 'F77COMSTR', '_FORTRANCOMSTRD')
|
||||||
FortranPPCommandGenerator = VariableListGenerator('FORTRANPPCOM', 'F77PPCOM', '_FORTRANPPCOMD')
|
FortranPPCommandGenerator = VariableListGenerator('FORTRANPPCOM', 'F77PPCOM', '_FORTRANPPCOMD')
|
||||||
|
FortranPPCommandStrGenerator = VariableListGenerator('FORTRANPPCOMSTR', 'F77PPCOMSTR', '_FORTRANPPCOMSTRD')
|
||||||
ShFortranGenerator = VariableListGenerator('SHFORTRAN', 'SHF77', 'FORTRAN', 'F77', '_FORTRAND')
|
ShFortranGenerator = VariableListGenerator('SHFORTRAN', 'SHF77', 'FORTRAN', 'F77', '_FORTRAND')
|
||||||
ShFortranFlagsGenerator = VariableListGenerator('SHFORTRANFLAGS', 'SHF77FLAGS')
|
ShFortranFlagsGenerator = VariableListGenerator('SHFORTRANFLAGS', 'SHF77FLAGS')
|
||||||
ShFortranCommandGenerator = VariableListGenerator('SHFORTRANCOM', 'SHF77COM', '_SHFORTRANCOMD')
|
ShFortranCommandGenerator = VariableListGenerator('SHFORTRANCOM', 'SHF77COM', '_SHFORTRANCOMD')
|
||||||
|
ShFortranCommandStrGenerator = VariableListGenerator('SHFORTRANCOMSTR', 'SHF77COMSTR', '_SHFORTRANCOMSTRD')
|
||||||
ShFortranPPCommandGenerator = VariableListGenerator('SHFORTRANPPCOM', 'SHF77PPCOM', '_SHFORTRANPPCOMD')
|
ShFortranPPCommandGenerator = VariableListGenerator('SHFORTRANPPCOM', 'SHF77PPCOM', '_SHFORTRANPPCOMD')
|
||||||
|
ShFortranPPCommandStrGenerator = VariableListGenerator('SHFORTRANPPCOMSTR', 'SHF77PPCOMSTR', '_SHFORTRANPPCOMSTRD')
|
||||||
|
|
||||||
#
|
#
|
||||||
FortranAction = SCons.Action.Action('$_FORTRANCOMG ')
|
FortranAction = SCons.Action.Action('$_FORTRANCOMG ', '$_FORTRANCOMSTRG')
|
||||||
FortranPPAction = SCons.Action.Action('$_FORTRANPPCOMG ')
|
FortranPPAction = SCons.Action.Action('$_FORTRANPPCOMG ', '$_FORTRANPPCOMSTRG')
|
||||||
ShFortranAction = SCons.Action.Action('$_SHFORTRANCOMG ')
|
ShFortranAction = SCons.Action.Action('$_SHFORTRANCOMG ', '$_SHFORTRANCOMSTRG')
|
||||||
ShFortranPPAction = SCons.Action.Action('$_SHFORTRANPPCOMG ')
|
ShFortranPPAction = SCons.Action.Action('$_SHFORTRANPPCOMG ', '$_SHFORTRANPPCOMSTRG')
|
||||||
|
|
||||||
def add_to_env(env):
|
def add_to_env(env):
|
||||||
"""Add Builders and construction variables for Fortran to an Environment."""
|
"""Add Builders and construction variables for Fortran to an Environment."""
|
||||||
|
|
||||||
env['_FORTRANG'] = FortranGenerator
|
env['_FORTRANG'] = FortranGenerator
|
||||||
env['_FORTRANFLAGSG'] = FortranFlagsGenerator
|
env['_FORTRANFLAGSG'] = FortranFlagsGenerator
|
||||||
env['_FORTRANCOMG'] = FortranCommandGenerator
|
env['_FORTRANCOMG'] = FortranCommandGenerator
|
||||||
env['_FORTRANPPCOMG'] = FortranPPCommandGenerator
|
env['_FORTRANCOMSTRG'] = FortranCommandStrGenerator
|
||||||
|
env['_FORTRANPPCOMG'] = FortranPPCommandGenerator
|
||||||
|
env['_FORTRANPPCOMSTRG'] = FortranPPCommandStrGenerator
|
||||||
|
|
||||||
env['_SHFORTRANG'] = ShFortranGenerator
|
env['_SHFORTRANG'] = ShFortranGenerator
|
||||||
env['_SHFORTRANFLAGSG'] = ShFortranFlagsGenerator
|
env['_SHFORTRANFLAGSG'] = ShFortranFlagsGenerator
|
||||||
env['_SHFORTRANCOMG'] = ShFortranCommandGenerator
|
env['_SHFORTRANCOMG'] = ShFortranCommandGenerator
|
||||||
env['_SHFORTRANPPCOMG'] = ShFortranPPCommandGenerator
|
env['_SHFORTRANCOMSTRG'] = ShFortranCommandStrGenerator
|
||||||
|
env['_SHFORTRANPPCOMG'] = ShFortranPPCommandGenerator
|
||||||
|
env['_SHFORTRANPPCOMSTRG'] = ShFortranPPCommandStrGenerator
|
||||||
|
|
||||||
env['_FORTRANINCFLAGS'] = '$( ${_concat(INCPREFIX, FORTRANPATH, INCSUFFIX, __env__, RDirs)} $)'
|
env['_FORTRANINCFLAGS'] = '$( ${_concat(INCPREFIX, FORTRANPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||||
|
|
||||||
env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX
|
env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX
|
||||||
env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX
|
env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX
|
||||||
|
@ -137,7 +147,7 @@ def add_to_env(env):
|
||||||
env['FORTRANMODDIR'] = '' # where the compiler should place .mod files
|
env['FORTRANMODDIR'] = '' # where the compiler should place .mod files
|
||||||
env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
|
env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
|
||||||
env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
|
env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
|
||||||
env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__)} $)'
|
env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)'
|
||||||
|
|
||||||
env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes)
|
env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes)
|
||||||
|
|
||||||
|
@ -155,10 +165,10 @@ def add_to_env(env):
|
||||||
static_obj.add_emitter(suffix, FortranEmitter)
|
static_obj.add_emitter(suffix, FortranEmitter)
|
||||||
shared_obj.add_emitter(suffix, ShFortranEmitter)
|
shared_obj.add_emitter(suffix, ShFortranEmitter)
|
||||||
|
|
||||||
env['_FORTRANCOMD'] = '$_FORTRANG $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_FORTRANCOMD'] = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_FORTRANPPCOMD'] = '$_FORTRANG $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_FORTRANPPCOMD'] = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_SHFORTRANCOMD'] = '$_SHFORTRANG $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_SHFORTRANCOMD'] = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
env['_SHFORTRANPPCOMD'] = '$_SHFORTRANG $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG -c -o $TARGET $SOURCES'
|
env['_SHFORTRANPPCOMD'] = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
import f77
|
import f77
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/g++.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/g++.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/g77.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/g77.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import f77
|
import f77
|
||||||
|
|
|
@ -9,7 +9,7 @@ selection method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
|
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,15 +31,15 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/gas.py 0.96.1.D001 2004/08/23 09:55:29 knight"
|
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Tool/gas.py 0.97.D001 2007/05/17 11:35:19 knight"
|
||||||
|
|
||||||
import as
|
as_module = __import__('as', globals(), locals(), [])
|
||||||
|
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for as to an Environment."""
|
"""Add Builders and construction variables for as to an Environment."""
|
||||||
as.generate(env)
|
as_module.generate(env)
|
||||||
|
|
||||||
env['AS'] = env.Detect(assemblers) or 'as'
|
env['AS'] = env.Detect(assemblers) or 'as'
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue