diff options
author | sgk@google.com <sgk@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-01 22:23:13 +0000 |
---|---|---|
committer | sgk@google.com <sgk@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-01 22:23:13 +0000 |
commit | d7721ce3023c27120203f4d8f4e0a6d8d861268f (patch) | |
tree | d4f9b861fc309d49399aeb21ccb24b6269c0277a /site_scons | |
parent | a945fbaeec0eaf25b36a47659e81b69d310b63b8 (diff) | |
download | chromium_src-d7721ce3023c27120203f4d8f4e0a6d8d861268f.zip chromium_src-d7721ce3023c27120203f4d8f4e0a6d8d861268f.tar.gz chromium_src-d7721ce3023c27120203f4d8f4e0a6d8d861268f.tar.bz2 |
Remove Hammer files.
Updates chromium_builders.py to remove import and use of deleted module.
Review URL: http://codereview.chromium.org/42667
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12987 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'site_scons')
35 files changed, 1 insertions, 7946 deletions
diff --git a/site_scons/site_init.py b/site_scons/site_init.py deleted file mode 100644 index 369b886..0000000 --- a/site_scons/site_init.py +++ /dev/null @@ -1,416 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Software construction toolkit site_scons configuration. - -This module sets up SCons for use with this toolkit. This should contain setup -which occurs outside of environments. If a method operates within the context -of an environment, it should instead go in a tool in site_tools and be invoked -for the target environment. -""" - -import __builtin__ -import sys -import SCons - - -def _HostPlatform(): - """Returns the current host platform. - - That is, the platform we're actually running SCons on. You shouldn't use - this inside your SConscript files; instead, include the appropriate - target_platform tool for your environments. When you call - BuildEnvironments(), only environments with the current host platform will be - built. - - Returns: - The host platform name - one of ('WINDOWS', 'LINUX', 'MAC'). - """ - - platform_map = { - 'win32': 'WINDOWS', - 'cygwin': 'WINDOWS', - 'linux': 'LINUX', - 'linux2': 'LINUX', - 'darwin': 'MAC', - } - - if sys.platform not in platform_map: - print ('site_init.py warning: platform "%s" is not in platfom map.' % - sys.platform) - - return platform_map.get(sys.platform, sys.platform) - - -#------------------------------------------------------------------------------ - - -def _CheckBuildModes(build_modes, environments, host_platform): - """Checks the build modes for the environments. - - Args: - build_modes: List of build mode strings. - environments: List of SCons environments. - host_platform: Host platform string. - - Raises: - ValueError: build groups and/or types invalid. - """ - # Make sure the list of environments for the current host platform have - # unique BUILD_TYPE. This ensures they won't overwrite each others' build - # output. (It is ok for build types in different host platforms to overlap; - # that is, WINDOWS and MAC can both have a 'dbg' build type.) - all_build_types = [] - all_build_groups = {} - build_desc = {} - for e in environments: - if not e.Overlap(e['HOST_PLATFORMS'], [host_platform, '*']): - continue - if e['BUILD_TYPE'] in all_build_types: - raise ValueError('Multiple environments have the same BUILD_TYPE=%s' % - e['BUILD_TYPE']) - else: - all_build_types.append(e['BUILD_TYPE']) - build_desc[e['BUILD_TYPE']] = e.get('BUILD_TYPE_DESCRIPTION') - - # Keep track of build groups and the build types which belong to them - for g in e['BUILD_GROUPS']: - if g not in all_build_groups: - all_build_groups[g] = [] - # Don't allow build types and groups to share names - if g in all_build_types: - raise ValueError('Build group %s also specified as BUILD_TYPE.' % g) - else: - all_build_types.append(g) - all_build_groups[g].append(e['BUILD_TYPE']) - - # Add help for build types - help_text = ''' -Use --mode=type to specify the type of build to perform. The following types -may be specified: -''' - - for build_type in all_build_types: - if build_type not in all_build_groups: - help_text += ' %-16s %s\n' % ( - build_type, build_desc.get(build_type, '')) - - help_text += ''' -The following build groups may also be specified via --mode. Build groups -build one or more of the other build types. The available build groups are: -''' - - groups_sorted = all_build_groups.keys() - groups_sorted.sort() - for g in groups_sorted: - help_text += ' %-16s %s\n' % (g, ','.join(all_build_groups[g])) - - help_text += ''' -Multiple modes may be specified, separated by commas: --mode=mode1,mode2. If -no mode is specified, the default group will be built. This is equivalent to -specifying --mode=default. - ''' - SCons.Script.Help(help_text) - - # Make sure all build modes specified by the user are ones which apply to - # the current environment. - for mode in build_modes: - if mode not in all_build_types and mode not in all_build_groups: - print ('Warning: Ignoring build mode "%s", which is not defined on this ' - 'platform.' % mode) - - -#------------------------------------------------------------------------------ - - -def BuildEnvironmentSConscripts(env): - """Evaluates SConscripts for the environment. - - Called by BuildEnvironments(). - """ - # Read SConscript for each component - # TODO(rspangler): Remove BUILD_COMPONENTS once all projects have - # transitioned to the BUILD_SCONSCRIPTS nomenclature. - for c in env.SubstList2('$BUILD_SCONSCRIPTS', '$BUILD_COMPONENTS'): - # Clone the environment so components can't interfere with each other - ec = env.Clone() - - if ec.Entry(c).isdir(): - # The component is a directory, so assume it contains a SConscript - # file. - c_dir = ec.Dir(c) - - # Use 'build.scons' as the default filename, but if that doesn't - # exist, fall back to 'SConscript'. - c_script = c_dir.File('build.scons') - if not c_script.exists(): - c_script = c_dir.File('SConscript') - else: - # The component is a SConscript file. - c_script = ec.File(c) - c_dir = c_script.dir - - # Make c_dir a string. - c_dir = str(c_dir) - - # Use build_dir differently depending on where the SConscript is. - if not ec.RelativePath('$TARGET_ROOT', c_dir).startswith('..'): - # The above expression means: if c_dir is $TARGET_ROOT or anything - # under it. Going from c_dir to $TARGET_ROOT and dropping the not fails - # to include $TARGET_ROOT. - # We want to be able to allow people to use addRepository to back things - # under $TARGET_ROOT/$OBJ_ROOT with things from above the current - # directory. When we are passed a SConscript that is already under - # $TARGET_ROOT, we should not use build_dir. - ec.SConscript(c_script, exports={'env': ec}, duplicate=0) - elif not ec.RelativePath('$MAIN_DIR', c_dir).startswith('..'): - # The above expression means: if c_dir is $MAIN_DIR or anything - # under it. Going from c_dir to $TARGET_ROOT and dropping the not fails - # to include $MAIN_DIR. - # Also, if we are passed a SConscript that - # is not under $MAIN_DIR, we should fail loudly, because it is unclear how - # this will correspond to things under $OBJ_ROOT. - ec.SConscript(c_script, build_dir='$OBJ_ROOT/' + c_dir, - exports={'env': ec}, duplicate=0) - else: - raise SCons.Error.UserError( - 'Bad location for a SConscript. "%s" is not under ' - '\$TARGET_ROOT or \$MAIN_DIR' % c_script) - - -def BuildEnvironments(environments): - """Build a collection of SConscripts under a collection of environments. - - Only environments with HOST_PLATFORMS containing the platform specified by - --host-platform (or the native host platform, if --host-platform was not - specified) will be matched. - - Each matching environment is checked against the modes passed to the --mode - command line argument (or 'default', if no mode(s) were specified). If any - of the modes match the environment's BUILD_TYPE or any of the environment's - BUILD_GROUPS, all the BUILD_SCONSCRIPTS (and for legacy reasons, - BUILD_COMPONENTS) in that environment will be built. - - Args: - environments: List of SCons environments. - - Returns: - List of environments which were actually evaluated (built). - """ - # Get options - build_modes = SCons.Script.GetOption('build_mode') - # TODO(rspangler): Remove support legacy MODE= argument, once everyone has - # transitioned to --mode. - legacy_mode_option = SCons.Script.ARGUMENTS.get('MODE') - if legacy_mode_option: - build_modes = legacy_mode_option - build_modes = build_modes.split(',') - - host_platform = SCons.Script.GetOption('host_platform') - if not host_platform: - host_platform = _HostPlatform() - - # Check build modes - _CheckBuildModes(build_modes, environments, host_platform) - - environments_to_evaluate = [] - for e in environments: - if not e.Overlap(e['HOST_PLATFORMS'], [host_platform, '*']): - continue # Environment requires a host platform which isn't us - - if e.Overlap([e['BUILD_TYPE'], e['BUILD_GROUPS']], build_modes): - environments_to_evaluate.append(e) - - for e in environments_to_evaluate: - # Make this the root environment for deferred functions, so they don't - # execute until our call to ExecuteDefer(). - e.SetDeferRoot() - - # Defer building the SConscripts, so that other tools can do - # per-environment setup first. - e.Defer(BuildEnvironmentSConscripts) - - # Execute deferred functions - e.ExecuteDefer() - - # Add help on targets. - AddTargetHelp() - - # Return list of environments actually evaluated - return environments_to_evaluate - - -#------------------------------------------------------------------------------ - - -def _ToolExists(): - """Replacement for SCons tool module exists() function, if one isn't present. - - Returns: - True. This enables modules which always exist not to need to include a - dummy exists() function. - """ - return True - - -def _ToolModule(self): - """Thunk for SCons.Tool.Tool._tool_module to patch in exists() function. - - Returns: - The module from the original SCons.Tool.Tool._tool_module call, with an - exists() method added if it wasn't present. - """ - module = self._tool_module_orig() - if not hasattr(module, 'exists'): - module.exists = _ToolExists - - return module - -#------------------------------------------------------------------------------ - - -def AddSiteDir(site_dir): - """Adds a site directory, as if passed to the --site-dir option. - - Args: - site_dir: Site directory path to add, relative to the location of the - SConstruct file. - - This may be called from the SConscript file to add a local site scons - directory for a project. This does the following: - * Adds site_dir/site_scons to sys.path. - * Imports site_dir/site_init.py. - * Adds site_dir/site_scons to the SCons tools path. - """ - # Call the same function that SCons does for the --site-dir option. - SCons.Script.Main._load_site_scons_dir( - SCons.Node.FS.get_default_fs().SConstruct_dir, site_dir) - - -#------------------------------------------------------------------------------ - - -_new_options_help = ''' -Additional options for SCons: - - --mode=MODE Specify build mode (see below). - --host-platform=PLATFORM Force SCons to use PLATFORM as the host platform, - instead of the actual platform on which SCons is - run. Useful for examining the dependency tree - which would be created, but not useful for - actually running the build because it'll attempt - to use the wrong tools for your actual platform. - --site-path=DIRLIST Comma-separated list of additional site - directory paths; each is processed as if passed - to --site-dir. -''' - -def SiteInitMain(): - """Main code executed in site_init.""" - - # Bail out if we've been here before. This is needed to handle the case where - # this site_init.py has been dropped into a project directory. - if hasattr(__builtin__, 'BuildEnvironments'): - return - - # Let people use new global methods directly. - __builtin__.AddSiteDir = AddSiteDir - __builtin__.BuildEnvironments = BuildEnvironments - # Legacy method names - # TODO(rspangler): Remove these once they're no longer used anywhere. - __builtin__.BuildComponents = BuildEnvironments - - - # Set list of default tools for component_setup - __builtin__.component_setup_tools = [ - # Defer must be first so other tools can register environment - # setup/cleanup functions. - 'defer', - # Component_targets must precede component_builders so builders can - # define target groups. - 'component_targets', - 'command_output', - 'component_bits', - 'component_builders', - 'concat_source', - 'environment_tools', - 'publish', - 'replicate', - ] - - # Patch Tool._tool_module method to fill in an exists() method for the - # module if it isn't present. - # TODO(sgk): This functionality should be patched into SCons itself by - # changing Tool.__init__(). - SCons.Tool.Tool._tool_module_orig = SCons.Tool.Tool._tool_module - SCons.Tool.Tool._tool_module = _ToolModule - - # Add our options - SCons.Script.AddOption( - '--mode', '--build-mode', - dest='build_mode', - nargs=1, type='string', - action='store', - metavar='MODE', - default='default', - help='build mode(s)') - SCons.Script.AddOption( - '--host-platform', - dest='host_platform', - nargs=1, type='string', - action='store', - metavar='PLATFORM', - help='build mode(s)') - SCons.Script.AddOption( - '--site-path', - dest='site_path', - nargs=1, type='string', - action='store', - metavar='PATH', - help='comma-separated list of site directories') - - SCons.Script.Help(_new_options_help) - - # Check for site path. This is a list of site directories which each are - # processed as if they were passed to --site-dir. - site_path = SCons.Script.GetOption('site_path') - if site_path: - for site_dir in site_path.split(','): - AddSiteDir(site_dir) - - # Since our site dir was specified on the SCons command line, SCons will - # normally only look at our site dir. Add back checking for project-local - # site_scons directories. - if not SCons.Script.GetOption('no_site_dir'): - SCons.Script.Main._load_site_scons_dir( - SCons.Node.FS.get_default_fs().SConstruct_dir, None) - -# Run main code -SiteInitMain() diff --git a/site_scons/site_tools/MSVSNew.py b/site_scons/site_tools/MSVSNew.py deleted file mode 100644 index e20035b..0000000 --- a/site_scons/site_tools/MSVSNew.py +++ /dev/null @@ -1,51 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -__doc__ = """SCons.Tool.msvs - -Tool-specific initialization for Microsof Visual Studio files. - -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. -""" - -try: - import SCons.Node.MSVS as MSVS -except ImportError: - # Until this gets finished enough to become part of base SCons. - import _Node_MSVS as MSVS - -def generate(env): - """ - Add Builders and construction variables for MSVS to the - construction environment. - """ - env.AddMethod(MSVS.MSVSFolder) - env.AddMethod(MSVS.MSVSProject) - env.AddMethod(MSVS.MSVSSolution) - -def exists(env): - return True diff --git a/site_scons/site_tools/_Node_MSVS.py b/site_scons/site_tools/_Node_MSVS.py deleted file mode 100644 index 4b83d56..0000000 --- a/site_scons/site_tools/_Node_MSVS.py +++ /dev/null @@ -1,1463 +0,0 @@ -# -# __COPYRIGHT__ -# -# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -__doc__ = """SCons.Node.MSVS - -New implementation of Visual Studio project generation for SCons. -""" - -import md5 -import os -import random -import re -import UserList -import xml.dom -import xml.dom.minidom - -import SCons.Node.FS -import SCons.Script -import SCons.Util - -from SCons.Debug import Trace -TODO = 0 - -# Initialize random number generator -random.seed() - - -#------------------------------------------------------------------------------ -# Entry point for supplying a fixed map of GUIDs for testing. - -GUIDMap = {} - - -#------------------------------------------------------------------------------ -# Helper functions - - -def MakeGuid(name, seed='msvs_new'): - """Returns a GUID for the specified target name. - - Args: - name: Target name. - seed: Seed for MD5 hash. - Returns: - A GUID-line string calculated from the name and seed. - - This generates something which looks like a GUID, but depends only on the - name and seed. This means the same name/seed will always generate the same - GUID, so that projects and solutions which refer to each other can explicitly - determine the GUID to refer to explicitly. It also means that the GUID will - not change when the project for a target is rebuilt. - """ - # Calculate a MD5 signature for the seed and name. - d = md5.new(str(seed) + str(name)).hexdigest().upper() - # Convert most of the signature to GUID form (discard the rest) - guid = ('{' + d[:8] + '-' + d[8:12] + '-' + d[12:16] + '-' + d[16:20] - + '-' + d[20:32] + '}') - return guid - - -#------------------------------------------------------------------------------ -# Global look up of string names. - -class LookupError(Exception): - def __str__(self): - string, expanded = self.args - if string == expanded: - return string - else: - return '%s (%s)' % (string, expanded) - -_lookup_dict = {} - -def LookupAdd(item, result): - _lookup_dict[item] = result - _lookup_dict[result] = result - -def Lookup(item): - """Looks up an MSVS item in the global dictionary. - - Args: - item: A path (string) or instance for looking up. - Returns: - An instance from the global _lookup_dict. - - Raises an exception if the item does not exist in the _lookup_dict. - """ - global _lookup_dict - try: - return _lookup_dict[item] - except KeyError: - return SCons.Node.FS.default_fs.Entry(item, create=False) - -def LookupCreate(klass, item, *args, **kw): - """Looks up an MSVS item, creating it if it doesn't already exist. - - Args: - klass: The class of item being looked up, or created if it - doesn't already exist in the global _lookup_dict. - item: The a string (or instance) being looked up. - *args: positional arguments passed to the klass.initialize() method. - **kw: keyword arguments passed to the klass.initialize() method. - Returns: - An instance from the global _lookup_dict, or None if the item does - not exist in the _lookup_dict. - - This raises a LookupError if the found instance doesn't match the - requested klass. - - When creating a new instance, this populates the _lookup_dict with - both the item and the instance itself as keys, so that looking up - the instance will return itself. - """ - global _lookup_dict - result = _lookup_dict.get(item) - if result: - if not isinstance(result, klass): - raise LookupError, "tried to redefine %s as a %s" % (item, klass) - return result - result = klass() - result.initialize(item, *args, **kw) - LookupAdd(item, result) - return result - - -#------------------------------------------------------------------------------ - -class FileList(object): - def __init__(self, entries=None): - if isinstance(entries, FileList): - entries = entries.entries - self.entries = entries or [] - def __getitem__(self, i): - return self.entries[i] - def __setitem__(self, i, item): - self.entries[i] = item - def __delitem__(self, i): - del self.entries[i] - def __add__(self, other): - if isinstance(other, FileList): - return self.__class__(self.entries + other.entries) - elif isinstance(other, type(self.entries)): - return self.__class__(self.entries + other) - else: - return self.__class__(self.entries + list(other)) - def __radd__(self, other): - if isinstance(other, FileList): - return self.__class__(other.entries + self.entries) - elif isinstance(other, type(self.entries)): - return self.__class__(other + self.entries) - else: - return self.__class__(list(other) + self.entries) - def __iadd__(self, other): - if isinstance(other, FileList): - self.entries += other.entries - elif isinstance(other, type(self.entries)): - self.entries += other - else: - self.entries += list(other) - return self - def append(self, item): - return self.entries.append(item) - def extend(self, item): - return self.entries.extend(item) - def index(self, item, *args): - return self.entries.index(item, *args) - def remove(self, item): - return self.entries.remove(item) - -def FileListWalk(top, topdown=True, onerror=None): - """ - """ - try: - entries = top.entries - except AttributeError, err: - if onerror is not None: - onerror(err) - return - - dirs, nondirs = [], [] - for entry in entries: - if hasattr(entry, 'entries'): - dirs.append(entry) - else: - nondirs.append(entry) - - if topdown: - yield top, dirs, nondirs - for entry in dirs: - for x in FileListWalk(entry, topdown, onerror): - yield x - if not topdown: - yield top, dirs, nondirs - -#------------------------------------------------------------------------------ - -class _MSVSFolder(FileList): - """Folder in a Visual Studio solution.""" - - entry_type_guid = '{2150E333-8FDC-42A3-9474-1A3956D46DE8}' - - def initialize(self, path, name=None, entries=None, guid=None, items=None): - """Initializes the folder. - - Args: - path: The unique name of the folder, by which other MSVS Nodes can - refer to it. This is not necessarily the name that gets printed - in the .sln file. - name: The name of this folder as actually written in a generated - .sln file. The default is - entries: List of folder entries to nest inside this folder. May contain - Folder or Project objects. May be None, if the folder is empty. - guid: GUID to use for folder, if not None. - items: List of solution items to include in the folder project. May be - None, if the folder does not directly contain items. - """ - super(_MSVSFolder, self).__init__(entries) - - # For folder entries, the path is the same as the name - self.msvs_path = path - self.msvs_name = name or path - - self.guid = guid - - # Copy passed lists (or set to empty lists) - self.items = list(items or []) - - def get_guid(self): - if self.guid is None: - guid = GUIDMap.get(self.msvs_path) - if not guid: - # The GUID for the folder can be random, since it's used only inside - # solution files and doesn't need to be consistent across runs. - guid = MakeGuid(random.random()) - self.guid = guid - return self.guid - - def get_msvs_path(self, sln): - return self.msvs_name - -def MSVSFolder(env, item, *args, **kw): - return LookupCreate(_MSVSFolder, item, *args, **kw) - -#------------------------------------------------------------------------------ - -class MSVSConfig(object): - """Visual Studio configuration.""" - def __init__(self, Name, config_type, tools=None, **attrs): - """Initializes the configuration. - - Args: - **attrs: Configuration attributes. - """ - # Special handling for attributes that we want to make more - # convenient for the user. - ips = attrs.get('InheritedPropertySheets') - if ips: - if isinstance(ips, list): - ips = ';'.join(ips) - attrs['InheritedPropertySheets'] = ips.replace('/', '\\') - - self.Name = Name - self.config_type = config_type - self.tools = tools - self.attrs = attrs - - def CreateElement(self, doc, project): - """Creates an element for the configuration. - - Args: - doc: xml.dom.Document object to use for node creation. - - Returns: - A new xml.dom.Element for the configuration. - """ - node = doc.createElement(self.config_type) - node.setAttribute('Name', self.Name) - for k, v in self.attrs.items(): - node.setAttribute(k, v) - - tools = self.tools - if tools is None: - tools = project.tools or [] - if not SCons.Util.is_List(tools): - tools = [tools] - tool_objects = [] - for t in tools: - if not isinstance(t, MSVSTool): - t = MSVSTool(t) - tool_objects.append(t) - for t in tool_objects: - node.appendChild(t.CreateElement(doc)) - - return node - - -class MSVSFileListBase(FileList): - """Base class for a file list in a Visual Studio project file.""" - - def CreateElement(self, doc, node_func=lambda x: x): - """Creates an element for an MSVSFileListBase subclass. - - Args: - doc: xml.dom.Document object to use for node creation. - node_func: Function to use to return Nodes for objects that - don't have a CreateElement() method of their own. - - Returns: - A new xml.dom.Element for the MSVSFileListBase object. - """ - node = doc.createElement(self.element_name) - for entry in self.entries: - if hasattr(entry, 'CreateElement'): - n = entry.CreateElement(doc, node_func) - else: - n = node_func(entry) - node.appendChild(n) - return node - - -class MSVSFiles(MSVSFileListBase): - """Files list in a Visual Studio project file.""" - element_name = 'Files' - - -class MSVSFilter(MSVSFileListBase): - """Filter (that is, a virtual folder) in a Visual Studio project file.""" - - element_name = 'Filter' - - def __init__(self, Name, entries=None): - """Initializes the folder. - - Args: - Name: Filter (folder) name. - entries: List of filenames and/or Filter objects contained. - """ - super(MSVSFilter, self).__init__(entries) - self.Name = Name - - def CreateElement(self, doc, node_func=lambda x: x): - """Creates an element for the Filter. - - Args: - doc: xml.dom.Document object to use for node creation. - node_func: Function to use to return Nodes for objects that - don't have a CreateElement() method of their own. - - Returns: - A new xml.dom.Element for the filter. - """ - node = super(MSVSFilter, self).CreateElement(doc, node_func) - node.setAttribute('Name', self.Name) - return node - - -class MSVSTool(object): - """Visual Studio tool.""" - - def __init__(self, Name, **attrs): - """Initializes the tool. - - Args: - Name: Tool name. - **attrs: Tool attributes. - """ - - val = attrs.get('AdditionalDependencies') - if val: - if isinstance(val, list): - val = ' '.join(val) - attrs['AdditionalDependencies'] = val.replace('/', '\\') - - val = attrs.get('AdditionalIncludeDirectories') - if val: - if isinstance(val, list): - val = ';'.join(val) - attrs['AdditionalIncludeDirectories'] = val.replace('/', '\\') - - val = attrs.get('AdditionalManifestFiles') - if val: - if isinstance(val, list): - val = ';'.join(val) - attrs['AdditionalManifestFiles'] = val.replace('/', '\\') - - val = attrs.get('CommandLine') - if val: - if isinstance(val, list): - val = '\r\n'.join(val) - attrs['CommandLine'] = val.replace('/', '\\') - - val = attrs.get('PreprocessorDefinitions') - if val: - if isinstance(val, list): - val = ';'.join(val) - attrs['PreprocessorDefinitions'] = val - - for a in ('ImportLibrary', - 'ObjectFile', - 'OutputFile', - 'Outputs', - 'XMLDocumentationFileName'): - val = attrs.get(a) - if val: - val = val.replace('/', '\\') - attrs[a] = val - - self.Name = Name - self.attrs = attrs - - def CreateElement(self, doc): - """Creates an element for the tool. - - Args: - doc: xml.dom.Document object to use for node creation. - - Returns: - A new xml.dom.Element for the tool. - """ - node = doc.createElement('Tool') - node.setAttribute('Name', self.Name) - for k, v in self.attrs.items(): - node.setAttribute(k, v) - return node - - def _format(self): - """Formats a tool specification for debug printing""" - xml_impl = xml.dom.getDOMImplementation() - doc = xml_impl.createDocument(None, 'VisualStudioProject', None) - return self.CreateElement(doc).toprettyxml() - - def diff(self, other): - for key, value in self.attrs.items(): - if other.attrs[key] == value: - del self.attrs[key] - - -class MSVSToolFile(object): - """Visual Studio tool file specification.""" - - def __init__(self, node, **attrs): - """Initializes the tool. - - Args: - node: Node for the Tool File - **attrs: Tool File attributes. - """ - self.node = node - - def CreateElement(self, doc, project): - result = doc.createElement('ToolFile') - result.setAttribute('RelativePath', project.get_rel_path(self.node)) - return result - - -#------------------------------------------------------------------------------ - -def MSVSAction(target, source, env): - target[0].Write(env) - -MSVSProjectAction = SCons.Script.Action(MSVSAction, - "Generating Visual Studio project `$TARGET' ...") - -class _MSVSProject(SCons.Node.FS.File): - """Visual Studio project.""" - - entry_type_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' - initialized = False - - def initialize(self, env, path, name = None, - dependencies = None, - guid = None, - buildtargets = [], - files = [], - root_namespace = None, - keyword = None, - relative_path_prefix = None, - local_directory_prefix = None, - relative_path_substitutions = [], - tools = None, - configurations = None, - **attrs): - """Initializes the project. - - Args: - path: Relative path to project file. - name: Name of project. If None, the name will be the same as the base - name of the project file. - dependencies: List of other Project objects this project is dependent - upon, if not None. - guid: GUID to use for project, if not None. - buildtargets: List of target(s) being built by this project. - files: List of source files for the project. This will be - supplemented by any source files of buildtargets. - root_namespace: The value of the RootNamespace attribute of the - project, if not None. The default is to use the same - string as the name. - relative_path_prefix: A prefix to be appended to the beginning of - every file name in the list. The canonical use is to specify - './' to make files explicitly relative to the local directory. - tools: A list of MSVSTool objects or strings representing - tools to be used to build this project. This will be used - for any configurations that don't provide their own - per-configuration tool list. - configurations: A list of MSVSConfig objects representing - configurations built by this project. - """ - if name is None: - if buildtargets: - name = os.path.splitext(buildtargets[0].name)[0] - else: - name = os.path.splitext(os.path.basename(path))[0] - if not root_namespace: - root_namespace or name - - if self.initialized: - # TODO(sgk): fill in - if self.msvs_name != name: - pass - if self.root_namespace != root_namespace: - pass - if self.relative_path_prefix != relative_path_prefix: - pass - if self.guid != guid: - pass - #if self.env != env: - # pass - else: - self.buildtargets = [] - self.configurations = [] - self.dependencies = [] - self.file_configurations = {} - self.files = MSVSFiles([]) - self.tool_files = [] - self.file_lists = [] - self.initialized = True - self.keyword = None - self.local_directory_prefix = '' - self.relative_path_prefix = '' - self.relative_path_substitutions = [] - self.root_namespace = name - - self.attrs = attrs - self.env = env - self.guid = guid - self.msvs_name = name - self.msvs_path = path - if relative_path_prefix: - self.relative_path_prefix = relative_path_prefix - if local_directory_prefix: - self.local_directory_prefix = local_directory_prefix - for left, right in relative_path_substitutions: - t = (left.replace('/', '\\'), right.replace('/', '\\')) - self.relative_path_substitutions.append(t) - if root_namespace: - self.root_namespace = root_namespace - if keyword: - self.keyword = keyword - self.tools = tools - - self.buildtargets.extend(buildtargets) - self.configurations.extend(configurations or []) - self.dependencies.extend(list(dependencies or [])) - self.AddFiles(files) - - env.Command(self, [], MSVSProjectAction) - - def args2nodes(self, entries): - result = [] - for entry in entries: - if SCons.Util.is_String(entry): - entry = self.env.File(entry) - result.append(entry.srcnode()) - elif hasattr(entry, 'entries'): - entry.entries = self.args2nodes(entry.entries) - result.append(entry) - elif isinstance(entry, (list, UserList.UserList)): - result.extend(self.args2nodes(entry)) - elif hasattr(entry, 'sources') and entry.sources: - result.extend(entry.sources) - else: - result.append(entry.srcnode()) - return result - - def FindFile(self, node): - try: - flat_file_dict = self.flat_file_dict - except AttributeError: - flat_file_dict = {} - file_list = self.files[:] - while file_list: - entry = file_list.pop(0) - if not isinstance(entry, (list, UserList.UserList)): - entry = [entry] - for f in entry: - if hasattr(f, 'entries'): - file_list.extend(f.entries) - else: - flat_file_dict[f] = True - flat_file_dict[f.srcnode()] = True - if hasattr(f, 'sources'): - for s in f.sources: - flat_file_dict[s] = True - flat_file_dict[s.srcnode()] = True - self.flat_file_dict = flat_file_dict - - return flat_file_dict.get(node) - - def get_guid(self): - if self.guid is None: - guid = GUIDMap.get(self.msvs_path) - if not guid: - # Set GUID from path - # TODO(rspangler): This is fragile. - # 1. We can't just use the project filename sans path, since there - # could be multiple projects with the same base name (for example, - # foo/unittest.vcproj and bar/unittest.vcproj). - # 2. The path needs to be relative to $SOURCE_ROOT, so that the project - # GUID is the same whether it's included from base/base.sln or - # foo/bar/baz/baz.sln. - # 3. The GUID needs to be the same each time this builder is invoked, - # so that we don't need to rebuild the solution when the - # project changes. - # 4. We should be able to handle pre-built project files by reading the - # GUID from the files. - guid = MakeGuid(self.msvs_path) - self.guid = guid - return self.guid - - def get_msvs_path(self, sln): - return sln.rel_path(self).replace('/', '\\') - - def get_rel_path(self, node): - result = self.rel_path(node) - if self.relative_path_prefix: - if not result.startswith('..'): - result = self.relative_path_prefix + result - elif not os.path.split(result)[0]: - result = self.local_directory_prefix + result - result = result.replace('/', '\\') - for left, right in self.relative_path_substitutions: - result = result.replace(left, right) - return result - - def AddConfig(self, Name, tools=None, **attrs): - """Adds a configuration to the parent node. - - Args: - Name: The name of the configuration. - tools: List of tools (strings or Tool objects); may be None. - **attrs: Configuration attributes. - """ - if tools is None: - # No tool list specifically for this configuration, - # use the Project's as a default. - tools = self.tools - if not attrs.has_key('ConfigurationType'): - # No ConfigurationType specifically for this configuration, - # use the Project's as a default. - try: - attrs['ConfigurationType'] = self.attrs['ConfigurationType'] - except KeyError: - pass - if attrs.has_key('InheritedPropertySheets'): - ips = attrs['InheritedPropertySheets'] - attrs['InheritedPropertySheets'] = self.env.subst(ips) - c = MSVSConfig(Name, 'Configuration', tools=tools, **attrs) - self.configurations.append(c) - - def AddFiles(self, files): - """Adds files to the project. - - Args: - files: A list of Filter objects and/or relative paths to files. - - This makes a copy of the file/filter tree at the time of this call. If you - later add files to a Filter object which was passed into a previous call - to AddFiles(), it will not be reflected in this project. - """ - self.file_lists.append(self.args2nodes(files)) - - def _FilesToSourceFiles(self, files): - file_list = files[:] - result = [] - while file_list: - entry = file_list.pop(0) - if not isinstance(entry, (list, UserList.UserList)): - entry = [entry] - for f in entry: - if hasattr(f, 'entries'): - self._FilesToSourceFiles(f.entries) - result.append(f) - else: - if f.sources: - flist = f.sources - else: - flist = [f] - for x in flist: - result.append(x.srcnode()) - files[:] = result - - def _MergeFiles(self, dest_list, src_list): - for f in src_list: - if f not in dest_list: - dest_list.append(f) - continue - #if hasattr(f, 'entries'): - # self._FilesToSourceFiles(f.entries) - - def AddFileConfig(self, path, Name, tools=None, **attrs): - """Adds a configuration to a file. - - Args: - path: Relative path to the file. - Name: Name of configuration to add. - tools: List of tools (strings or MSVSTool objects); may be None. - **attrs: Configuration attributes. - - Raises: - ValueError: Relative path does not match any file added via AddFiles(). - """ - # Store as the VariantDir node, not as the source node. - node = self.env.File(path) - c = MSVSConfig(Name, 'FileConfiguration', tools=tools, **attrs) - config_list = self.file_configurations.get(node) - if config_list is None: - config_list = [] - self.file_configurations[node] = config_list - config_list.append(c) - - def AddToolFile(self, path): - """Adds a tool file to the project. - - Args: - path: Relative path from project to tool file. - """ - tf = MSVSToolFile(self.env.File(path)) - self.tool_files.append(tf) - - def Create(self): - """Creates the project document. - - Args: - name: Name of the project. - guid: GUID to use for project, if not None. - """ - # Create XML doc - xml_impl = xml.dom.getDOMImplementation() - self.doc = xml_impl.createDocument(None, 'VisualStudioProject', None) - - # Add attributes to root element - root = self.doc.documentElement - root.setAttribute('ProjectType', 'Visual C++') - root.setAttribute('Version', '8.00') - root.setAttribute('Name', self.msvs_name) - root.setAttribute('ProjectGUID', self.get_guid()) - root.setAttribute('RootNamespace', self.root_namespace) - if self.keyword: - root.setAttribute('Keyword', self.keyword) - - # Add platform list - platforms = self.doc.createElement('Platforms') - root.appendChild(platforms) - n = self.doc.createElement('Platform') - n.setAttribute('Name', 'Win32') - platforms.appendChild(n) - - # Add tool files section - tool_files = self.doc.createElement('ToolFiles') - root.appendChild(tool_files) - for tf in self.tool_files: - tool_files.appendChild(tf.CreateElement(self.doc, self)) - - # Add configurations section - configs = self.doc.createElement('Configurations') - root.appendChild(configs) - for c in self.configurations: - configs.appendChild(c.CreateElement(self.doc, self)) - - # Add empty References section - root.appendChild(self.doc.createElement('References')) - - # Add files section - root.appendChild(self.files.CreateElement(self.doc, self.CreateFileElement)) - - # Add empty Globals section - root.appendChild(self.doc.createElement('Globals')) - - def CreateFileElement(self, file): - """Create a DOM node for the specified file. - - Args: - file: The file Node being considered. - - Returns: - A DOM Node for the File, with a relative path to the current - project object, and any file configurations attached to the - project. - """ - - node = self.doc.createElement('File') - node.setAttribute('RelativePath', self.get_rel_path(file)) - for c in self.file_configurations.get(file, []): - node.appendChild(c.CreateElement(self.doc, self)) - return node - - def VCCLCompilerTool(self, args): - default_attrs = { - 'BufferSecurityCheck' : "false", - 'CompileAs' : 0, # default - 'DebugInformationFormat' : 0, # TODO(???) - 'DisableSpecificWarnings' : [], - 'EnableFiberSafeOptimizations' : "false", - 'EnableFunctionLevelLinking' : "false", - 'EnableIntrinsicFunctions' : "false", - 'FavorSizeOrSpeed' : 0, # favorNone - 'InlineFunctionExpansion' : 1, # expandDisable - 'MinimalRebuild' : "false", - 'OmitFramePointers' : "false", - 'Optimization' : 1, # optimizeDisabled TODO(???) - 'PreprocessorDefinitions' : [], - 'RuntimeLibrary' : TODO, - 'RuntimeTypeInfo' : "false", - 'StringPooling' : "false", - 'SuppressStartupBanner' : "false", - 'WarningAsError' : "false", - 'WarningLevel' : 1, # warningLevel_1 - 'WholeProgramOptimization' : "false", - } - - tool = MSVSTool('VCCLCompilerTool', **default_attrs) - attrs = tool.attrs - - for arg in args: - if arg in ('/c',): - continue - if arg.startswith('/Fo'): - continue - if arg.startswith('/D'): - attrs['PreprocessorDefinitions'].append(arg[2:]) - elif arg == '/EH': - attrs['ExceptionHandling'] = 0 - elif arg == '/GF': - attrs['StringPooling'] = "true" - elif arg == '/GL': - attrs['WholeProgramOptimization'] = "true" - elif arg == '/GM': - attrs['MinimalRebuild'] = "true" - elif arg == '/GR-': - attrs['RuntimeTypeInfo'] = "true" - elif arg == '/Gs': - attrs['BufferSecurityCheck'] = "true" - elif arg == '/Gs-': - attrs['BufferSecurityCheck'] = "false" - elif arg == '/GT': - attrs['EnableFiberSafeOptimizations'] = "true" - elif arg == '/Gy': - attrs['EnableFunctionLevelLinking'] = "true" - elif arg == '/MD': - attrs['RuntimeLibrary'] = 1 # rtMultiThreadedDebug - elif arg == '/MDd': - attrs['RuntimeLibrary'] = 2 # rtMultiThreadedDebugDLL - elif arg == '/MT': - attrs['RuntimeLibrary'] = 0 # rtMultiThreaded - elif arg == '/MTd': - attrs['RuntimeLibrary'] = 3 # rtMultiThreadedDLL - elif arg == '/nologo': - attrs['SuppressStartupBanner'] = "true" - elif arg == '/O1': - attrs['InlineFunctionExpansion'] = 4 # optimizeMinSpace - elif arg == '/O2': - attrs['InlineFunctionExpansion'] = 3 # optimizeMaxSpeed - elif arg == '/Ob1': - attrs['InlineFunctionExpansion'] = 2 # expandOnlyInline - elif arg == '/Ob2': - attrs['InlineFunctionExpansion'] = 0 # expandAnySuitable - elif arg == '/Od': - attrs['Optimization'] = 0 - elif arg == '/Oi': - attrs['EnableIntrinsicFunctions'] = "true" - elif arg == '/Os': - attrs['FavorSizeOrSpeed'] = 1 # favorSize - elif arg == '/Ot': - attrs['FavorSizeOrSpeed'] = 2 # favorSpeed - elif arg == '/Ox': - attrs['Optimization'] = 2 # optimizeFull - elif arg == '/Oy': - attrs['OmitFramePointers'] = "true" - elif arg == '/Oy-': - attrs['TODO'] = "true" - elif arg in ('/Tc', '/TC'): - attrs['CompileAs'] = 1 # compileAsC - elif arg in ('/Tp', '/TP'): - attrs['CompileAs'] = 2 # compileAsCPlusPlus - elif arg == '/WX': - attrs['WarnAsError'] = "true" - elif arg.startswith('/W'): - attrs['WarningLevel'] = int(arg[2:]) # 0 through 4 - elif arg.startswith('/wd'): - attrs['DisableSpecificWarnings'].append(str(arg[3:])) - elif arg == '/Z7': - attrs['DebugInformationFormat'] = 3 # debugOldSytleInfo TODO(???) - elif arg == '/Zd': - attrs['DebugInformationFormat'] = 0 # debugDisabled - elif arg == '/Zi': - attrs['DebugInformationFormat'] = 2 # debugEnabled TODO(???) - elif arg == '/ZI': - attrs['DebugInformationFormat'] = 1 # debugEditAndContinue TODO(???) - - cppdefines = attrs['PreprocessorDefinitions'] - if cppdefines: - attrs['PreprocessorDefinitions'] = ';'.join(cppdefines) - warnings = attrs['DisableSpecificWarnings'] - if warnings: - warnings = SCons.Util.uniquer(warnings) - attrs['DisableSpecificWarnings'] = ';'.join(warnings) - - return tool - - def VCLibrarianTool(self, args): - default_attrs = { - 'LinkTimeCodeGeneration' : "false", - 'SuppressStartupBanner' : "false", - } - - tool = MSVSTool('VCLibrarianTool', **default_attrs) - attrs = tool.attrs - - for arg in args: - if arg.startswith('/OUT'): - continue - if arg == '/ltcg': - attrs['LinkTimeCodeGeneration'] = "true" - elif arg == '/nologo': - attrs['SuppressStartupBanner'] = "true" - - return tool - - def VCLinkerTool(self, args): - default_attrs = { - 'LinkIncremental' : "false", - 'LinkTimeCodeGeneration' : "false", - 'EnableCOMDATFolding' : TODO, - 'OptimizeForWindows98' : TODO, - 'OptimizeReferences' : TODO, - 'Profile' : "false", - 'SuppressStartupBanner' : "false", - } - - tool = MSVSTool('VCLinkerTool', **default_attrs) - attrs = tool.attrs - - for arg in args: - if arg == '': - continue - if arg == '/INCREMENTAL': - attrs['LinkIncremental'] = "true" - elif arg == '/INCREMENTAL:NO': - attrs['LinkIncremental'] = "false" - elif arg == '/LTCG': - attrs['LinkTimeCodeGeneration'] = "true" - elif arg == '/nologo': - attrs['SuppressStartupBanner'] = "true" - elif arg == '/OPT:NOICF': - attrs['EnableCOMDATFolding'] = 2 # - elif arg == '/OPT:NOWIN98': - attrs['OptimizeForWindows98'] = 1 # - elif arg == '/OPT:REF': - attrs['OptimizeReferences'] = 2 # - elif arg == '/PROFILE': - attrs['Profile'] = "true" - - return tool - - command_to_tool_map = { - 'cl' : 'VCCLCompilerTool', - 'cl.exe' : 'VCCLCompilerTool', - 'lib' : 'VCLibrarianTool', - 'lib.exe' : 'VCLibrarianTool', - 'link' : 'VCLinkerTool', - 'link.exe' : 'VCLinkerTool', - } - - def cl_to_tool(self, args): - command = os.path.basename(args[0]) - method_name = self.command_to_tool_map.get(command) - if not method_name: - return None - return getattr(self, method_name)(args[1:]) - - def _AddFileConfigurationDifferences(self, target, source, base_env, file_env, name): - """Adds a per-file configuration. - - Args: - target: The target being built from the source. - source: The source to which the file configuration is being added. - base_env: The base construction environment for the project. - Differences from this will go into the FileConfiguration - in the project file. - file_env: The construction environment for the target, containing - the per-target settings. - """ - executor = target.get_executor() - base_cl = map(str, base_env.subst_list(executor)[0]) - file_cl = map(str, file_env.subst_list(executor)[0]) - if base_cl == file_cl: - return - - base_tool = self.cl_to_tool(base_cl) - file_tool = self.cl_to_tool(file_cl) - - if not base_tool or not_file_tool: - return - - file_tool.diff(base_tool) - - self.AddFileConfig(source, name, tools=[file_tool]) - - def _AddFileConfigurations(self, env): - """Adds per-file configurations for the buildtarget's sources. - - Args: - env: The base construction environment for the project. - """ - if not self.buildtargets: - return - - for bt in self.buildtargets: - executor = bt.get_executor() - build_env = bt.get_build_env() - bt_cl = map(str, build_env.subst_list(executor)[0]) - tool = self.cl_to_tool(bt_cl) - default_tool = self.cl_to_tool([bt_cl[0]]) - if default_tool: - tool.diff(default_tool) - else: - # TODO(sgk): print a message unconditionally is too - # verbose for things like Python function actions, - # but doing nothing runs the risk of burying problems. - # Work out a better solution. - #print "no tool for %r" % bt_cl[0] - pass - for t in bt.sources: - e = t.get_build_env() - additional_files = SCons.Util.UniqueList() - for s in t.sources: - s = env.arg2nodes([s])[0].srcnode() - if not self.FindFile(s): - additional_files.append(s) - if not build_env is e: - # TODO(sgk): This test may be bogus, but it works for now. - # We're trying to figure out if the file configuration - # differences need to be added one per build target, or one - # per configuration for the entire project. The assumption - # is that if the number of buildtargets configured matches - # the number of project configurations, that we use those - # in preference to the project configurations. - if len(self.buildtargets) == len(self.configurations): - self._AddFileConfigurationDifferences(t, s, build_env, e, e.subst('$MSVSCONFIGURATIONNAME')) - else: - for config in self.configurations: - self._AddFileConfigurationDifferences(t, s, build_env, e, config.Name) - self._MergeFiles(self.files, additional_files) - - def Write(self, env): - """Writes the project file.""" - for flist in self.file_lists: - self._FilesToSourceFiles(flist) - self._MergeFiles(self.files, flist) - for k, v in self.file_configurations.items(): - self.file_configurations[str(k)] = v - k = self.env.File(k).srcnode() - self.file_configurations[k] = v - self.file_configurations[str(k)] = v - self._AddFileConfigurations(env) - - self.Create() - - f = open(str(self), 'wt') - f.write(self.formatMSVSProjectXML(self.doc)) - f.close() - - # Methods for formatting XML as nearly identically to Microsoft's - # .vcproj output as we can practically make it. - # - # The general design here is copied from: - # - # Bruce Eckels' MindView, Inc: 12-09-04 XML Oddyssey - # http://www.mindview.net/WebLog/log-0068 - # - # Eckels' implementation broke up long tag definitions for readability, - # in much the same way that .vcproj does, but we've modified things - # for .vcproj quirks (like some tags *always* terminating with </Tag>, - # even when empty). - - encoding = 'Windows-1252' - - def formatMSVSProjectXML(self, xmldoc): - xmldoc = xmldoc.toprettyxml("", "\n", encoding=self.encoding) - # Remove trailing whitespace from each line: - xmldoc = "\n".join( - [line.rstrip() for line in xmldoc.split("\n")]) - # Remove all empty lines before opening '<': - while xmldoc.find("\n\n<") != -1: - xmldoc = xmldoc.replace("\n\n<", "\n<") - dom = xml.dom.minidom.parseString(xmldoc) - xmldoc = dom.toprettyxml("\t", "", encoding=self.encoding) - xmldoc = xmldoc.replace('?><', '?>\n<') - xmldoc = self.reformatLines(xmldoc) - return xmldoc - - def reformatLines(self, xmldoc): - result = [] - for line in [line.rstrip() for line in xmldoc.split("\n")]: - if line.lstrip().startswith("<"): - result.append(self.reformatLine(line) + "\n") - else: - result.append(line + "\n") - return ''.join(result) - - # Keyword order for specific tags. - # - # Listed keywords will come first and in the specified order. - # Any unlisted keywords come after, in whatever order they appear - # in the input config. In theory this means we would only *have* to - # list the keywords that we care about, but in practice we'll probably - # want to nail down Visual Studio's order to make sure we match them - # as nearly as possible. - - order = { - 'Configuration' : [ - 'Name', - 'ConfigurationType', - 'InheritedPropertySheets', - ], - 'FileConfiguration' : [ - 'Name', - 'ExcludedFromBuild', - ], - 'Tool' : [ - 'Name', - 'DisableSpecificWarnings', - - 'AdditionalIncludeDirectories', - 'Description', - 'CommandLine', - 'OutputFile', - 'ImportLibrary', - 'PreprocessorDefinitions', - 'UsePrecompiledHeader', - 'PrecompiledHeaderThrough', - 'ForcedIncludeFiles', - ], - 'VisualStudioProject' : [ - 'ProjectType', - 'Version', - 'Name', - 'ProjectGUID', - 'RootNamespace', - 'Keyword', - ], - } - - force_closing_tag = [ - 'File', - 'Globals', - 'References', - 'ToolFiles' - ] - - oneLiner = re.compile("(\s*)<(\w+)(.*)>") - keyValuePair = re.compile('\w+="[^"]*?"') - def reformatLine(self, line): - """Reformat an xml tag to put each key-value - element on a single indented line, for readability""" - matchobj = self.oneLiner.match(line.rstrip()) - if not matchobj: - return line - baseIndent, tag, rest = matchobj.groups() - slash = '' - if rest[-1:] == '/': - slash = '/' - rest = rest[:-1] - result = [baseIndent + '<' + tag] - indent = baseIndent + "\t" - pairs = self.keyValuePair.findall(rest) - for key in self.order.get(tag, []): - for p in [ p for p in pairs if p.startswith(key+'=') ]: - result.append("\n" + indent + p) - pairs.remove(p) - for pair in pairs: - result.append("\n" + indent + pair) - result = [''.join(result).rstrip()] - - if tag in self.force_closing_tag: - # These force termination with </Tag>, so translate slash. - if rest: - result.append("\n") - result.append(indent) - result.append(">") - if slash: - result.append("\n") - result.append(baseIndent + "</" + tag + ">") - else: - if rest: - result.append("\n") - if slash: - result.append(baseIndent) - else: - result.append(indent) - result.append(slash + ">") - - return ''.join(result) - -def MSVSProject(env, item, *args, **kw): - if not SCons.Util.is_String(item): - return item - item = env.subst(item) - result = env.fs._lookup(item, None, _MSVSProject, create=1) - result.initialize(env, item, *args, **kw) - LookupAdd(item, result) - return result - -#------------------------------------------------------------------------------ - -MSVSSolutionAction = SCons.Script.Action(MSVSAction, - "Generating Visual Studio solution `$TARGET' ...") - -class _MSVSSolution(SCons.Node.FS.File): - """Visual Studio solution.""" - - def initialize(self, env, path, entries=None, variants=None, websiteProperties=True): - """Initializes the solution. - - Args: - path: Path to solution file. - entries: List of entries in solution. May contain Folder or Project - objects. May be None, if the folder is empty. - variants: List of build variant strings. If none, a default list will - be used. - """ - self.msvs_path = path - self.websiteProperties = websiteProperties - - # Copy passed lists (or set to empty lists) - self.entries = list(entries or []) - - if variants: - # Copy passed list - self.variants = variants[:] - else: - # Use default - self.variants = ['Debug|Win32', 'Release|Win32'] - # TODO(rspangler): Need to be able to handle a mapping of solution config - # to project config. Should we be able to handle variants being a dict, - # or add a separate variant_map variable? If it's a dict, we can't - # guarantee the order of variants since dict keys aren't ordered. - - env.Command(self, [], MSVSSolutionAction) - - def Write(self, env): - """Writes the solution file to disk. - - Raises: - IndexError: An entry appears multiple times. - """ - r = [] - errors = [] - - def lookup_subst(item, env=env, errors=errors): - if SCons.Util.is_String(item): - lookup_item = env.subst(item) - else: - lookup_item = item - try: - return Lookup(lookup_item) - except SCons.Errors.UserError: - raise LookupError(item, lookup_item) - - # Walk the entry tree and collect all the folders and projects. - all_entries = [] - entries_to_check = self.entries[:] - while entries_to_check: - # Pop from the beginning of the list to preserve the user's order. - entry = entries_to_check.pop(0) - try: - entry = lookup_subst(entry) - except LookupError, e: - errors.append("Could not look up entry `%s'." % e) - continue - - # A project or folder can only appear once in the solution's folder tree. - # This also protects from cycles. - if entry in all_entries: - #raise IndexError('Entry "%s" appears more than once in solution' % - # e.name) - continue - - all_entries.append(entry) - - # If this is a folder, check its entries too. - if isinstance(entry, _MSVSFolder): - entries_to_check += entry.entries - - # Header - r.append('Microsoft Visual Studio Solution File, Format Version 9.00\n') - r.append('# Visual Studio 2005\n') - - # Project entries - for e in all_entries: - r.append('Project("%s") = "%s", "%s", "%s"\n' % ( - e.entry_type_guid, # Entry type GUID - e.msvs_name, # Folder name - e.get_msvs_path(self), # Folder name (again) - e.get_guid(), # Entry GUID - )) - - # TODO(rspangler): Need a way to configure this stuff - if self.websiteProperties: - r.append('\tProjectSection(WebsiteProperties) = preProject\n' - '\t\tDebug.AspNetCompiler.Debug = "True"\n' - '\t\tRelease.AspNetCompiler.Debug = "False"\n' - '\tEndProjectSection\n') - - if isinstance(e, _MSVSFolder): - if e.items: - r.append('\tProjectSection(SolutionItems) = preProject\n') - for i in e.items: - i = i.replace('/', '\\') - r.append('\t\t%s = %s\n' % (i, i)) - r.append('\tEndProjectSection\n') - - if isinstance(e, _MSVSProject): - if e.dependencies: - r.append('\tProjectSection(ProjectDependencies) = postProject\n') - for d in e.dependencies: - try: - d = lookup_subst(d) - except LookupError, e: - errors.append("Could not look up dependency `%s'." % e) - else: - r.append('\t\t%s = %s\n' % (d.get_guid(), d.get_guid())) - r.append('\tEndProjectSection\n') - - r.append('EndProject\n') - - # Global section - r.append('Global\n') - - # Configurations (variants) - r.append('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n') - for v in self.variants: - r.append('\t\t%s = %s\n' % (v, v)) - r.append('\tEndGlobalSection\n') - - # Sort config guids for easier diffing of solution changes. - config_guids = [] - for e in all_entries: - if isinstance(e, _MSVSProject): - config_guids.append(e.get_guid()) - config_guids.sort() - - r.append('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n') - for g in config_guids: - for v in self.variants: - r.append('\t\t%s.%s.ActiveCfg = %s\n' % ( - g, # Project GUID - v, # Solution build configuration - v, # Project build config for that solution config - )) - - # Enable project in this solution configuratation - r.append('\t\t%s.%s.Build.0 = %s\n' % ( - g, # Project GUID - v, # Solution build configuration - v, # Project build config for that solution config - )) - r.append('\tEndGlobalSection\n') - - # TODO(rspangler): Should be able to configure this stuff too (though I've - # never seen this be any different) - r.append('\tGlobalSection(SolutionProperties) = preSolution\n') - r.append('\t\tHideSolutionNode = FALSE\n') - r.append('\tEndGlobalSection\n') - - # Folder mappings - # TODO(rspangler): Should omit this section if there are no folders - folder_mappings = [] - for e in all_entries: - if not isinstance(e, _MSVSFolder): - continue # Does not apply to projects, only folders - for subentry in e.entries: - try: - subentry = lookup_subst(subentry) - except LookupError, e: - errors.append("Could not look up subentry `%s'." % subentry) - else: - folder_mappings.append((subentry.get_guid(), e.get_guid())) - folder_mappings.sort() - r.append('\tGlobalSection(NestedProjects) = preSolution\n') - for fm in folder_mappings: - r.append('\t\t%s = %s\n' % fm) - r.append('\tEndGlobalSection\n') - - r.append('EndGlobal\n') - - if errors: - errors = ['Errors while generating solution file:'] + errors - raise SCons.Errors.UserError, '\n\t'.join(errors) - - f = open(self.path, 'wt') - f.write(''.join(r)) - f.close() - -def MSVSSolution(env, item, *args, **kw): - if not SCons.Util.is_String(item): - return item - item = env.subst(item) - result = env.fs._lookup(item, None, _MSVSSolution, create=1) - result.initialize(env, item, *args, **kw) - LookupAdd(item, result) - return result - -class Derived(SCons.Util.Proxy): - def srcnode(self, *args, **kw): - return self - def __getattr__(self, name): - if name == 'sources': - return [] - return SCons.Util.Proxy.__getattr__(self, name) - def __hash__(self, *args, **kw): - return id(self) - -import __builtin__ - -__builtin__.Derived = Derived -__builtin__.MSVSConfig = MSVSConfig -__builtin__.MSVSFilter = MSVSFilter -__builtin__.MSVSProject = MSVSProject -__builtin__.MSVSSolution = MSVSSolution -__builtin__.MSVSTool = MSVSTool diff --git a/site_scons/site_tools/atlmfc_vc80.py b/site_scons/site_tools/atlmfc_vc80.py deleted file mode 100644 index 8d3d4b0..0000000 --- a/site_scons/site_tools/atlmfc_vc80.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Windows ATL MFC for VC80 (Visual Studio 2005) tool for SCons. - -Note that ATL MFC requires the commercial (non-free) version of Visual Studio -2005. Using this in an open-source project thus limits the size of the -developer community to those with the commercial version. -""" - -import os - - -def _FindLocalInstall(): - """Returns the directory containing the local install of the tool. - - Returns: - Path to tool (as a string), or None if not found. - """ - # TODO(rspangler): Should use a better search. Probably needs to be based on - # msvs tool, as msvc detection is. - default_dir = 'C:/Program Files/Microsoft Visual Studio 8/VC/atlmfc' - if os.path.exists(default_dir): - return default_dir - else: - return None - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - if not env.get('ATLMFC_VC80_DIR'): - env['ATLMFC_VC80_DIR'] = _FindLocalInstall() - - env.Append( - LIBPATH=['$ATLMFC_VC80_DIR/lib'], - RCFLAGS=['/I"$ATLMFC_VC80_DIR/include"'], - CCFLAGS=['/I"$ATLMFC_VC80_DIR/include"'], - ) - - -def exists(env): - """Returns true if tool exists.""" - # NOTE: SCons requires the use of this name, which fails gpylint. - - # If directory explicitly specified, we exist - if env.get('ATLMFC_VC80_DIR'): - return 1 - elif _FindLocalInstall(): - return 1 - else: - return 0 diff --git a/site_scons/site_tools/chromium_builders.py b/site_scons/site_tools/chromium_builders.py index c132465..d64e92f 100644 --- a/site_scons/site_tools/chromium_builders.py +++ b/site_scons/site_tools/chromium_builders.py @@ -4,7 +4,7 @@ """ Tool module for adding, to a construction environment, Chromium-specific -wrappers around Hammer builders. This gives us a central place for any +wrappers around SCons builders. This gives us a central place for any customization we need to make to the different things we build. """ @@ -13,7 +13,6 @@ import sys from SCons.Script import * import SCons.Node -import _Node_MSVS as MSVS class Null(object): def __new__(cls, *args, **kwargs): @@ -256,43 +255,6 @@ def ChromeObject(env, *args, **kw): result = env.ComponentObject(*args, **kw) return result -def ChromeMSVSFolder(env, *args, **kw): - if not env.Bit('msvs'): - return Null() - return env.MSVSFolder(*args, **kw) - -def ChromeMSVSProject(env, *args, **kw): - if not env.Bit('msvs'): - return Null() - try: - dest = kw['dest'] - except KeyError: - dest = None - else: - del kw['dest'] - result = env.MSVSProject(*args, **kw) - env.AlwaysBuild(result) - if dest: - i = env.Command(dest, result, Copy('$TARGET', '$SOURCE')) - Alias('msvs', i) - return result - -def ChromeMSVSSolution(env, *args, **kw): - if not env.Bit('msvs'): - return Null() - try: - dest = kw['dest'] - except KeyError: - dest = None - else: - del kw['dest'] - result = env.MSVSSolution(*args, **kw) - env.AlwaysBuild(result) - if dest: - i = env.Command(dest, result, Copy('$TARGET', '$SOURCE')) - Alias('msvs', i) - return result - def ChromeInstall(env, target, source): """ Replacement for the stock SCons Install() builder to use the @@ -313,9 +275,6 @@ def generate(env): env.AddMethod(ChromeStaticLibrary) env.AddMethod(ChromeSharedLibrary) env.AddMethod(ChromeObject) - env.AddMethod(ChromeMSVSFolder) - env.AddMethod(ChromeMSVSProject) - env.AddMethod(ChromeMSVSSolution) env.AddMethod(ChromeInstall) env.AddMethod(FilterOut) diff --git a/site_scons/site_tools/chromium_load_component.py b/site_scons/site_tools/chromium_load_component.py deleted file mode 100644 index 24c6e03..0000000 --- a/site_scons/site_tools/chromium_load_component.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -""" -Tool module for managing conditional loading of components in a -Chromium build (i.e., the LOAD= command-line argument). -""" - -from SCons.Script import * - -def generate(env): - - class LoadComponent: - """ - Class for deciding if a given component name is to be included - based on a list of included names, optionally prefixed with '-' - to exclude the name. - """ - def __init__(self, load=[], names=[]): - """ - Initialize a class with a list of names for possible loading. - - Arguments: - load: list of elements in the LOAD= specification - names: name(s) that represent this global collection - """ - self.included = set([c for c in load if not c.startswith('-')]) - self.excluded = set([c[1:] for c in load if c.startswith('-')]) - - # Remove the global collection name(s) from the included list. - # This supports (e.g.) specifying 'webkit' so the top-level of the - # hierarchy will read up the subsystem, and then 'test_shell' - # as one specific sub-component within 'webkit'. - self.included = self.included - set(names) - - if not self.included: - self.included = ['all'] - - def __call__(self, component): - """ - Returns True if the specified component should be loaded, - based on the initialized included and excluded lists. - """ - return (component in self.included or - ('all' in self.included and not component in self.excluded)) - - def ChromiumLoadComponentSConscripts(env, *args, **kw): - """ - Returns a list of SConscript files to load, based on LOAD=. - - SConscript files specified without keyword arguments are returned - unconditionally. SConscript files specified with a keyword arguments - (e.g. chrome = 'chrome.scons') are loaded only if the LOAD= line - indicates their keyword argument should be included in the load. - """ - try: - load = ARGUMENTS.get('LOAD').split(',') - except AttributeError: - load = [] - - try: - names = kw['LOAD_NAMES'] - except KeyError: - names = [] - else: - del kw['LOAD_NAMES'] - - load_component = LoadComponent(load, names) - - result = list(args) - for module, sconscript in kw.items(): - if load_component(module): - result.append(sconscript) - - return Flatten(result) - - env.AddMethod(ChromiumLoadComponentSConscripts) - -def exists(env): - return True diff --git a/site_scons/site_tools/code_coverage.py b/site_scons/site_tools/code_coverage.py deleted file mode 100644 index 6155cdf..0000000 --- a/site_scons/site_tools/code_coverage.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""SCons tool for generating code coverage. - -This module enhances a debug environment to add code coverage. -It is used as follows: - coverage_env = dbg_env.Clone(tools = ['code_coverage']) -""" - - -def AddCoverageSetup(env): - """Add coverage related build steps and dependency links. - - Args: - env: a leaf environment ready to have coverage steps added. - """ - # Add a step to start coverage (for instance windows needs this). - # This step should get run before and tests are run. - if env.get('COVERAGE_START_CMD', None): - start = env.Command('$COVERAGE_START_FILE', [], '$COVERAGE_START_CMD') - env.AlwaysBuild(start) - else: - start = [] - - # Add a step to end coverage (used on basically all platforms). - # This step should get after all the tests have run. - if env.get('COVERAGE_STOP_CMD', None): - stop = env.Command('$COVERAGE_OUTPUT_FILE', [], '$COVERAGE_STOP_CMD') - env.AlwaysBuild(stop) - else: - stop = [] - - # start must happen before tests run, stop must happen after. - for group in env.SubstList2('$COVERAGE_TARGETS'): - group_alias = env.Alias(group) - # Force each alias to happen after start but before stop. - env.Requires(group_alias, start) - env.Requires(stop, group_alias) - # Force each source of the aliases to happen after start but before stop. - # This is needed to work around non-standard aliases in some projects. - for test in group_alias: - for s in test.sources: - env.Requires(s, start) - env.Requires(stop, s) - - # Add an alias for coverage. - env.Alias('coverage', [start, stop]) - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - env['COVERAGE_ENABLED'] = True - - env.SetDefault( - # Setup up coverage related tool paths. - # These can be overridden elsewhere, if needed, to relocate the tools. - COVERAGE_MCOV='mcov', - COVERAGE_GENHTML='genhtml', - COVERAGE_ANALYZER='coverage_analyzer.exe', - COVERAGE_VSPERFCMD='VSPerfCmd.exe', - COVERAGE_VSINSTR='vsinstr.exe', - - # Setup coverage related locations. - COVERAGE_DIR='$TARGET_ROOT/coverage', - COVERAGE_HTML_DIR='$COVERAGE_DIR/html', - COVERAGE_START_FILE='$COVERAGE_DIR/start.junk', - COVERAGE_OUTPUT_FILE='$COVERAGE_DIR/coverage.lcov', - - # The list of aliases containing test execution targets. - COVERAGE_TARGETS=['run_all_tests'], - ) - - # Add in coverage flags. These come from target_platform_xxx. - env.Append( - CCFLAGS='$COVERAGE_CCFLAGS', - LIBS='$COVERAGE_LIBS', - LINKFLAGS='$COVERAGE_LINKFLAGS', - ) - - # Add on LINKCOM steps. - # TODO(bradnelson): Ideally this would just get appended, but that seems to - # cause it to blow up in the gather_inputs builder with a complaint about - # "Can't creation Action from None". Once that builder is gone, then this - # can change to be more general. - if env.get('COVERAGE_LINKCOM_EXTRAS'): - env['LINKCOM'] = env.Action([env['LINKCOM'], - env['COVERAGE_LINKCOM_EXTRAS']]) - - # Add any extra paths. - env.AppendENVPath('PATH', env.SubstList2('$COVERAGE_EXTRA_PATHS')) - - # Add coverage start/stop and processing in deferred steps. - env.Defer(AddCoverageSetup) diff --git a/site_scons/site_tools/code_signing.py b/site_scons/site_tools/code_signing.py deleted file mode 100644 index bf647c9..0000000 --- a/site_scons/site_tools/code_signing.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Code signing build tool. - -This module sets up code signing. -It is used as follows: - env = Environment(tools = ["code_signing"]) -To sign an EXE/DLL do: - env.SignedBinary('hello_signed.exe', 'hello.exe', - CERTIFICATE_FILE='bob.pfx', - CERTIFICATE_PASSWORD='123', - TIMESTAMP_SERVER='') -If no certificate file is specified, copying instead of signing will occur. -If an empty timestamp server string is specified, there will be no timestamp. -""" - -import SCons.Script - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - env.Replace( - # Path to Microsoft signtool.exe - SIGNTOOL='$VC80_DIR/common7/tools/bin/signtool.exe', - # No certificate by default. - CERTIFICATE_PATH='', - # No certificate password by default. - CERTIFICATE_PASSWORD='', - # The default timestamp server. - TIMESTAMP_SERVER='http://timestamp.verisign.com/scripts/timestamp.dll', - ) - - # Setup Builder for Signing - env['BUILDERS']['SignedBinary'] = SCons.Script.Builder( - generator=SignedBinaryGenerator, - emitter=SignedBinaryEmitter) - - -def SignedBinaryEmitter(target, source, env): - """Add the signing certificate (if any) to the source dependencies.""" - if env['CERTIFICATE_PATH']: - source.append(env['CERTIFICATE_PATH']) - return target, source - - -def SignedBinaryGenerator(source, target, env, for_signature): - """A builder generator for code signing.""" - source = source # Silence gpylint. - target = target # Silence gpylint. - for_signature = for_signature # Silence gpylint. - - # Alway copy and make writable. - commands = [ - SCons.Script.Copy('$TARGET', '$SOURCE'), - SCons.Script.Chmod('$TARGET', 0755), - ] - - # Only do signing if there is a certificate path. - if env['CERTIFICATE_PATH']: - # The command used to do signing (target added on below). - signing_cmd = '$SIGNTOOL sign /f "$CERTIFICATE_PATH"' - # Add certificate password if any. - if env['CERTIFICATE_PASSWORD']: - signing_cmd += ' /p "$CERTIFICATE_PASSWORD"' - # Add timestamp server if any. - if env['TIMESTAMP_SERVER']: - signing_cmd += ' /t "$TIMESTAMP_SERVER"' - # Add in target name - signing_cmd += ' $TARGET' - # Add the signing to the list of commands to perform. - commands.append(signing_cmd) - - return commands diff --git a/site_scons/site_tools/collada_dom.py b/site_scons/site_tools/collada_dom.py deleted file mode 100644 index 2373ea1..0000000 --- a/site_scons/site_tools/collada_dom.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Collada DOM 1.3.0 tool for SCons.""" - - -import sys - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # TODO(rspangler): Should this really be a bit, or should we have a - # COLLADA_DOM_VERSION variable - env['COLLADA_DOM_VERSION'] = '1.3.0' - - env.Append(CPPDEFINES=['COLLADA_DOM_130']) - - if sys.platform in ('win32', 'cygwin'): - # Use /I for collada includes, so SCons won't scan for their - # dependencies (as it would if they were added to CPPPATH). - env.Append(CCFLAGS=[ - '/I$COLLADA_DIR/include', - '/I$COLLADA_DIR/include/1.4', - ]) - else: - env.Append(CCFLAGS=[ - '-I$COLLADA_DIR/include', - '-I$COLLADA_DIR/include/1.4', - ]) - - -def exists(env): - """Returns true if tool exists.""" - # NOTE: SCons requires the use of this name, which fails gpylint. - - # If directory explicitly specified, we exist - if env.get('COLLADA_DIR'): - return 1 - else: - # TODO(rspangler): Don't know how to find it otherwise! - return 0 diff --git a/site_scons/site_tools/command_output.py b/site_scons/site_tools/command_output.py deleted file mode 100644 index 795f3eb..0000000 --- a/site_scons/site_tools/command_output.py +++ /dev/null @@ -1,234 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Command output builder for SCons.""" - - -import os -import signal -import subprocess -import sys -import threading -import time -import SCons.Script - - -# TODO(rspangler): Move KillProcessTree() and RunCommand() into their own -# module. - - -def KillProcessTree(pid): - """Kills the process and all of its child processes. - - Args: - pid: process to kill. - - Raises: - OSError: Unsupported OS. - """ - - if sys.platform in ('win32', 'cygwin'): - # Use Windows' taskkill utility - killproc_path = '%s;%s\\system32;%s\\system32\\wbem' % ( - (os.environ['SYSTEMROOT'],) * 3) - killproc_cmd = 'taskkill /F /T /PID %d' % pid - killproc_task = subprocess.Popen(killproc_cmd, shell=True, - stdout=subprocess.PIPE, - env={'PATH':killproc_path}) - killproc_task.communicate() - - elif sys.platform in ('linux', 'linux2', 'darwin'): - # Use ps to get a list of processes - ps_task = subprocess.Popen(['/bin/ps', 'x', '-o', 'pid,ppid'], stdout=subprocess.PIPE) - ps_out = ps_task.communicate()[0] - - # Parse out a dict of pid->ppid - ppid = {} - for ps_line in ps_out.split('\n'): - w = ps_line.strip().split() - if len(w) < 2: - continue # Not enough words in this line to be a process list - try: - ppid[int(w[0])] = int(w[1]) - except ValueError: - pass # Header or footer - - # For each process, kill it if it or any of its parents is our child - for p in ppid: - p2 = p - while p2: - if p2 == pid: - os.kill(p, signal.SIGKILL) - break - p2 = ppid.get(p2) - - else: - raise OSError('Unsupported OS for KillProcessTree()') - - -def RunCommand(cmdargs, cwdir=None, env=None, echo_output=True, timeout=None, - timeout_errorlevel=14): - """Runs an external command. - - Args: - cmdargs: A command string, or a tuple containing the command and its - arguments. - cwdir: Working directory for the command, if not None. - env: Environment variables dict, if not None. - echo_output: If True, output will be echoed to stdout. - timeout: If not None, timeout for command in seconds. If command times - out, it will be killed and timeout_errorlevel will be returned. - timeout_errorlevel: The value to return if the command times out. - - Returns: - The integer errorlevel from the command. - The combined stdout and stderr as a string. - """ - # Force unicode string in the environment to strings. - if env: - env = dict([(k, str(v)) for k, v in env.items()]) - start_time = time.time() - child = subprocess.Popen(cmdargs, cwd=cwdir, env=env, shell=True, - universal_newlines=True, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - child_out = [] - child_retcode = None - - def _ReadThread(): - """Thread worker function to read output from child process. - - Necessary since there is no cross-platform way of doing non-blocking - reads of the output pipe. - """ - read_run = True - while read_run: - # Need to have a delay of 1 cycle between child completing and - # thread exit, to pick up the final output from the child. - if child_retcode is not None: - read_run = False - new_out = child.stdout.read() - if new_out: - if echo_output: - print new_out, - child_out.append(new_out) - - read_thread = threading.Thread(target=_ReadThread) - read_thread.start() - - # Wait for child to exit or timeout - while child_retcode is None: - time.sleep(1) # So we don't poll too frequently - child_retcode = child.poll() - if timeout and child_retcode is None: - elapsed = time.time() - start_time - if elapsed > timeout: - print '*** RunCommand() timeout:', cmdargs - KillProcessTree(child.pid) - child_retcode = timeout_errorlevel - - # Wait for worker thread to pick up final output and die - read_thread.join(5) - if read_thread.isAlive(): - print '*** Error: RunCommand() read thread did not exit.' - sys.exit(1) - - if echo_output: - print # end last line of output - return child_retcode, ''.join(child_out) - - -def CommandOutputBuilder(target, source, env): - """Command output builder. - - Args: - self: Environment in which to build - target: List of target nodes - source: List of source nodes - - Returns: - None or 0 if successful; nonzero to indicate failure. - - Runs the command specified in the COMMAND_OUTPUT_CMDLINE environment variable - and stores its output in the first target file. Additional target files - should be specified if the command creates additional output files. - - Runs the command in the COMMAND_OUTPUT_RUN_DIR subdirectory. - """ - env = env.Clone() - - cmdline = env.subst('$COMMAND_OUTPUT_CMDLINE', target=target, source=source) - cwdir = env.subst('$COMMAND_OUTPUT_RUN_DIR', target=target, source=source) - if cwdir: - cwdir = os.path.normpath(cwdir) - env.AppendENVPath('PATH', cwdir) - env.AppendENVPath('LD_LIBRARY_PATH', cwdir) - else: - cwdir = None - cmdecho = env.get('COMMAND_OUTPUT_ECHO', True) - timeout = env.get('COMMAND_OUTPUT_TIMEOUT') - timeout_errorlevel = env.get('COMMAND_OUTPUT_TIMEOUT_ERRORLEVEL') - - retcode, output = RunCommand(cmdline, cwdir=cwdir, env=env['ENV'], - echo_output=cmdecho, timeout=timeout, - timeout_errorlevel=timeout_errorlevel) - - # Save command line output - output_file = open(str(target[0]), 'w') - output_file.write(output) - output_file.close() - - return retcode - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add the builder and tell it which build environment variables we use. - action = SCons.Script.Action( - CommandOutputBuilder, - 'Output "$COMMAND_OUTPUT_CMDLINE" to $TARGET', - varlist=[ - 'COMMAND_OUTPUT_CMDLINE', - 'COMMAND_OUTPUT_RUN_DIR', - 'COMMAND_OUTPUT_TIMEOUT', - 'COMMAND_OUTPUT_TIMEOUT_ERRORLEVEL', - # We use COMMAND_OUTPUT_ECHO also, but that doesn't change the - # command being run or its output. - ], ) - builder = SCons.Script.Builder(action = action) - env.Append(BUILDERS={'CommandOutput': builder}) - - # Default command line is to run the first input - env['COMMAND_OUTPUT_CMDLINE'] = '$SOURCE' - - # TODO(rspangler): add a pseudo-builder which takes an additional command - # line as an argument. diff --git a/site_scons/site_tools/component_bits.py b/site_scons/site_tools/component_bits.py deleted file mode 100644 index 53e6d88..0000000 --- a/site_scons/site_tools/component_bits.py +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Environment bit support for software construction toolkit. - -This module is automatically included by the component_setup tool. -""" - - -import __builtin__ -import types -import SCons - - -_bit_descriptions = {} -_bits_with_options = set() -_bit_exclusive_groups = {} - -#------------------------------------------------------------------------------ - - -def _CheckDeclared(bits): - """Checks each of the bits to make sure it's been declared. - - Args: - bits: List of bits to check. - - Raises: - ValueError: A bit has not been declared. - """ - for bit in bits: - if bit not in _bit_descriptions: - raise ValueError('Bit "%s" used before DeclareBit()' % - bit) - - -def _CheckExclusive(already_set, proposed): - """Checks if setting proposed bits would violate any exclusive groups. - - Args: - already_set: List of bits already set. - proposed: List of bits attempting to be set. - - Raises: - ValueError: A proposed bit belongs to an exclusive group which already has - a bit set. - """ - # Remove any already-set bits from proposed (note this makes a copy of - # proposed so we don't alter the passed list). - proposed = [bit for bit in proposed if bit not in already_set] - - for group_name, group_bits in _bit_exclusive_groups.items(): - set_match = group_bits.intersection(already_set) - proposed_match = group_bits.intersection(proposed) - if set_match and proposed_match: - raise ValueError('Unable to set bit "%s" because it belongs to the same ' - 'exclusive group "%s" as already-set bit "%s"' % ( - proposed_match.pop(), group_name, set_match.pop())) - - -#------------------------------------------------------------------------------ - - -def DeclareBit(bit_name, desc, exclusive_groups=None): - """Declares and describes the bit. - - Args: - bit_name: Name of the bit being described. - desc: Description of bit. - exclusive_groups: Bit groups which this bit belongs to. At most one bit - may be set in each exclusive group. May be a string, list of string, - or None. - - Raises: - ValueError: The bit has already been defined with a different description, - or the description is empty. - - Adds a description for the bit in the global dictionary of bit names. All - bits should be described before being used in Bit()/AllBits()/AnyBits(). - """ - - if not desc: - raise ValueError('Must supply a description for bit "%s"' % bit_name) - - existing_desc = _bit_descriptions.get(bit_name) - if existing_desc and desc != existing_desc: - raise ValueError('Cannot describe bit "%s" as "%s" because it has already' - 'been described as "%s".' % - (bit_name, desc, existing_desc)) - - _bit_descriptions[bit_name] = desc - - # Add bit to its exclusive groups - if exclusive_groups: - if type(exclusive_groups) == types.StringType: - exclusive_groups = [exclusive_groups] - for g in exclusive_groups: - if g not in _bit_exclusive_groups: - _bit_exclusive_groups[g] = set() - _bit_exclusive_groups[g].add(bit_name) - -#------------------------------------------------------------------------------ - -def Bit(env, bit_name): - """Checks if the environment has the bit. - - Args: - env: Environment to check. - bit_name: Name of the bit to check. - - Returns: - True if the bit is present in the environment. - """ - _CheckDeclared([bit_name]) - return bit_name in env['_BITS'] - -#------------------------------------------------------------------------------ - - -def AllBits(env, *args): - """Checks if the environment has all the bits. - - Args: - env: Environment to check. - args: List of bit names to check. - - Returns: - True if every bit listed is present in the environment. - """ - _CheckDeclared(args) - return set(args).issubset(env['_BITS']) - -#------------------------------------------------------------------------------ - - -def AnyBits(env, *args): - """Checks if the environment has at least one of the bits. - - Args: - env: Environment to check. - args: List of bit names to check. - - Returns: - True if at least one bit listed is present in the environment. - """ - _CheckDeclared(args) - return set(args).intersection(env['_BITS']) - -#------------------------------------------------------------------------------ - - -def SetBits(env, *args): - """Sets the bits in the environment. - - Args: - env: Environment to check. - args: List of bit names to set. - """ - _CheckDeclared(args) - _CheckExclusive(env['_BITS'], args) - env['_BITS'] = env['_BITS'].union(args) - -#------------------------------------------------------------------------------ - - -def ClearBits(env, *args): - """Clears the bits in the environment. - - Args: - env: Environment to check. - args: List of bit names to clear (remove). - """ - _CheckDeclared(args) - env['_BITS'] = env['_BITS'].difference(args) - -#------------------------------------------------------------------------------ - - -def SetBitFromOption(env, bit_name, default): - """Sets the bit in the environment from a command line option. - - Args: - env: Environment to check. - bit_name: Name of the bit to set from a command line option. - default: Default value for bit if command line option is not present. - """ - _CheckDeclared([bit_name]) - - # Add the command line option, if not already present - if bit_name not in _bits_with_options: - _bits_with_options.add(bit_name) - SCons.Script.AddOption('--' + bit_name, - dest=bit_name, - action='store_true', - help='set bit:' + _bit_descriptions[bit_name]) - SCons.Script.AddOption('--no-' + bit_name, - dest=bit_name, - action='store_false', - help='clear bit:' + _bit_descriptions[bit_name]) - - bit_set = env.GetOption(bit_name) - if bit_set is None: - # Not specified on command line, so use default - bit_set = default - - if bit_set: - env['_BITS'].add(bit_name) - elif bit_name in env['_BITS']: - env['_BITS'].remove(bit_name) - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add methods to builtin - # TODO(rspangler): These really belong in site_init.py - but if we do that, - # what's the right way to access the bit global variables? - __builtin__.DeclareBit = DeclareBit - - # Add methods to environment - env.AddMethod(AllBits) - env.AddMethod(AnyBits) - env.AddMethod(Bit) - env.AddMethod(ClearBits) - env.AddMethod(SetBitFromOption) - env.AddMethod(SetBits) - - env['_BITS'] = set() diff --git a/site_scons/site_tools/component_builders.py b/site_scons/site_tools/component_builders.py deleted file mode 100644 index 1fe638c..0000000 --- a/site_scons/site_tools/component_builders.py +++ /dev/null @@ -1,618 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Software construction toolkit builders for SCons.""" - - -import SCons - - -__component_list = {} - - -def _InitializeComponentBuilders(env): - """Re-initializes component builders module. - - Args: - env: Environment context - """ - env = env # Silence gpylint - - __component_list.clear() - - -def _RetrieveComponents(component_name, filter_components=None): - """Get the list of all components required by the specified component. - - Args: - component_name: Name of the base component. - filter_components: List of components NOT to include. - - Returns: - A list of the transitive closure of all components required by the base - component. That is, if A requires B and B requires C, this returns [B, C]. - - """ - if filter_components: - filter_components = set(filter_components) - else: - filter_components = set() - - components = set([component_name]) # Components always require themselves - new_components = set(components) - while new_components: - # Take next new component and add it to the list we've already scanned. - c = new_components.pop() - components.add(c) - # Add to the list of new components any of c's components that we haven't - # seen before. - new_components.update(__component_list.get(c, set()) - - components - filter_components) - - return list(components) - - -def _StoreComponents(self, component_name): - """Stores the list of child components for the specified component. - - Args: - self: Environment containing component. - component_name: Name of the component. - - Adds component references based on the LIBS and COMPONENTS variables in the - current environment. Should be called at primary SConscript execution time; - use _RetrieveComponents() to get the final components lists in a Defer()'d - function. - """ - - components = set() - for clist in ('LIBS', 'COMPONENTS'): - components.update(map(self.subst, self.Flatten(self[clist]))) - - if component_name not in __component_list: - __component_list[component_name] = set() - __component_list[component_name].update(components) - - -def _ComponentPlatformSetup(env, builder_name, **kwargs): - """Modify an environment to work with a component builder. - - Args: - env: Environment to clone. - builder_name: Name of the builder. - kwargs: Keyword arguments. - - Returns: - A modified clone of the environment. - """ - # Clone environment so we can modify it - env = env.Clone() - - # Add all keyword arguments to the environment - for k, v in kwargs.items(): - env[k] = v - - # Add compiler flags for included headers, if any - env['INCLUDES'] = env.Flatten(env.subst_list(['$INCLUDES'])) - for h in env['INCLUDES']: - env.Append(CCFLAGS = ['${CCFLAG_INCLUDE}%s' % h]) - - # Call platform-specific component setup function, if any - if env.get('COMPONENT_PLATFORM_SETUP'): - env['COMPONENT_PLATFORM_SETUP'](env, builder_name) - - # Return the modified environment - return env - -#------------------------------------------------------------------------------ - -# TODO(rspangler): Should be possible to refactor programs, test programs, -# libs to all publish as packages, for simplicity and code reuse. - - -def ComponentPackageDeferred(env): - """Deferred build steps for component package. - - Args: - env: Environment from ComponentPackage(). - - Sets up the aliases to build the package. - """ - package_name = env['PACKAGE_NAME'] - - # Install program and resources - all_outputs = [] - filter = env.Flatten(env.subst_list('$COMPONENT_PACKAGE_FILTER')) - components = _RetrieveComponents(package_name, filter) - for resource, dest_dir in env.get('COMPONENT_PACKAGE_RESOURCES').items(): - all_outputs += env.ReplicatePublished(dest_dir, components, resource) - - # Add installed program and resources to the alias - env.Alias(package_name, all_outputs) - - -def ComponentPackage(self, package_name, dest_dir, **kwargs): - """Pseudo-builder for package containing other components. - - Args: - self: Environment in which we were called. - package_name: Name of package. - dest_dir: Destination directory for package. - args: Positional arguments. - kwargs: Keyword arguments. - - Returns: - The alias node for the package. - """ - # Clone and modify environment - env = _ComponentPlatformSetup(self, 'ComponentPackage', **kwargs) - - env.Replace( - PACKAGE_NAME=package_name, - PACKAGE_DIR=dest_dir, - ) - - # Add an empty alias for the package and add it to the right groups - a = env.Alias(package_name, []) - for group in env['COMPONENT_PACKAGE_GROUPS']: - SCons.Script.Alias(group, a) - - # Store list of components for this program - env._StoreComponents(package_name) - - # Let component_targets know this target is available in the current mode - env.SetTargetProperty(package_name, TARGET_PATH=dest_dir) - - # Set up deferred call to replicate resources - env.Defer(ComponentPackageDeferred) - - # Return the alias, since it's the only node we have - return a - -#------------------------------------------------------------------------------ - - -def ComponentObject(self, *args, **kwargs): - """Pseudo-builder for object to handle platform-dependent type. - - Args: - self: Environment in which we were called. - args: Positional arguments. - kwargs: Keyword arguments. - - Returns: - Passthrough return code from env.StaticLibrary() or env.SharedLibrary(). - - TODO(rspangler): Perhaps this should be a generator builder, so it can take - a list of inputs and return a list of outputs? - """ - # Clone and modify environment - env = _ComponentPlatformSetup(self, 'ComponentObject', **kwargs) - - # Make appropriate object type - if env.get('COMPONENT_STATIC'): - o = env.StaticObject(*args, **kwargs) - else: - o = env.SharedObject(*args, **kwargs) - - # Add dependencies on includes - env.Depends(o, env['INCLUDES']) - - return o - -#------------------------------------------------------------------------------ - - -def ComponentLibrary(self, lib_name, *args, **kwargs): - """Pseudo-builder for library to handle platform-dependent type. - - Args: - self: Environment in which we were called. - lib_name: Library name. - args: Positional arguments. - kwargs: Keyword arguments. - - Returns: - Passthrough return code from env.StaticLibrary() or env.SharedLibrary(). - """ - # Clone and modify environment - env = _ComponentPlatformSetup(self, 'ComponentLibrary', **kwargs) - - # Make appropriate library type - if env.get('COMPONENT_STATIC'): - lib_outputs = env.StaticLibrary(lib_name, *args, **kwargs) - else: - lib_outputs = env.SharedLibrary(lib_name, *args, **kwargs) - - # Add dependencies on includes - env.Depends(lib_outputs, env['INCLUDES']) - - # Scan library outputs for files we need to link against this library, and - # files we need to run executables linked against this library. - need_for_link = [] - need_for_debug = [] - need_for_run = [] - for o in lib_outputs: - if o.suffix in env['COMPONENT_LIBRARY_LINK_SUFFIXES']: - need_for_link.append(o) - if o.suffix in env['COMPONENT_LIBRARY_DEBUG_SUFFIXES']: - need_for_debug.append(o) - if o.suffix == env['SHLIBSUFFIX']: - need_for_run.append(o) - all_outputs = lib_outputs - - # Install library in intermediate directory, so other libs and programs can - # link against it - all_outputs += env.Replicate('$LIB_DIR', need_for_link) - - # Publish output - env.Publish(lib_name, 'run', need_for_run) - env.Publish(lib_name, 'debug', need_for_debug) - - # Add an alias to build and copy the library, and add it to the right groups - a = self.Alias(lib_name, all_outputs) - for group in env['COMPONENT_LIBRARY_GROUPS']: - SCons.Script.Alias(group, a) - - # Store list of components for this library - env._StoreComponents(lib_name) - - # Let component_targets know this target is available in the current mode. - env.SetTargetProperty(lib_name, TARGET_PATH=lib_outputs[0]) - - # If library should publish itself, publish as if it was a program - if env.get('COMPONENT_LIBRARY_PUBLISH'): - env['PROGRAM_BASENAME'] = lib_name - env.Defer(ComponentProgramDeferred) - - # Return the library outputs - return lib_outputs - -#------------------------------------------------------------------------------ - - -def ComponentTestProgramDeferred(env): - """Deferred build steps for test program. - - Args: - env: Environment from ComponentTestProgram(). - - Sets up the aliases to compile and run the test program. - """ - prog_name = env['PROGRAM_BASENAME'] - - # Install program and resources - all_outputs = [] - components = _RetrieveComponents(prog_name) - for resource, dest_dir in env.get('COMPONENT_TEST_RESOURCES').items(): - all_outputs += env.ReplicatePublished(dest_dir, components, resource) - - # Add installed program and resources to the alias - env.Alias(prog_name, all_outputs) - - # Add target properties - env.SetTargetProperty( - prog_name, - # The copy of the program we care about is the one in the tests dir - EXE='$TESTS_DIR/$PROGRAM_NAME', - RUN_CMDLINE='$COMPONENT_TEST_CMDLINE', - RUN_DIR='$TESTS_DIR', - TARGET_PATH='$TESTS_DIR/$PROGRAM_NAME', - ) - - # Add an alias for running the test in the test directory, if the test is - # runnable and has a test command line. - if env.get('COMPONENT_TEST_RUNNABLE') and env.get('COMPONENT_TEST_CMDLINE'): - env.Replace( - COMMAND_OUTPUT_CMDLINE=env['COMPONENT_TEST_CMDLINE'], - COMMAND_OUTPUT_RUN_DIR='$TESTS_DIR', - ) - test_out_name = '$TEST_OUTPUT_DIR/${PROGRAM_BASENAME}.out.txt' - if (env.GetOption('component_test_retest') - and env.File(test_out_name).exists()): - # Delete old test results, so test will rerun. - env.Execute(SCons.Script.Delete(test_out_name)) - - # Set timeout based on test size - timeout = env.get('COMPONENT_TEST_TIMEOUT') - if type(timeout) is dict: - timeout = timeout.get(env.get('COMPONENT_TEST_SIZE')) - if timeout: - env['COMMAND_OUTPUT_TIMEOUT'] = timeout - - # Test program is the first run resource we replicated. (Duplicate - # replicate is not harmful, and is a handy way to pick out the correct - # file from all those we replicated above.) - test_program = env.ReplicatePublished('$TESTS_DIR', prog_name, 'run') - - # Run the test. Note that we need to refer to the file by name, so that - # SCons will recreate the file node after we've deleted it; if we used the - # env.File() we created in the if statement above, SCons would still think - # it exists and not rerun the test. - test_out = env.CommandOutput(test_out_name, test_program) - - # Running the test requires the test and its libs copied to the tests dir - env.Depends(test_out, all_outputs) - env.ComponentTestOutput('run_' + prog_name, test_out) - - # Add target properties - env.SetTargetProperty(prog_name, RUN_TARGET='run_' + prog_name) - -def ComponentTestProgram(self, prog_name, *args, **kwargs): - """Pseudo-builder for test program to handle platform-dependent type. - - Args: - self: Environment in which we were called. - prog_name: Test program name. - args: Positional arguments. - kwargs: Keyword arguments. - - Returns: - Output node list from env.Program(). - - TODO(rspangler): Should have some sort of support for S/M/L categorization - """ - # Clone and modify environment - env = _ComponentPlatformSetup(self, 'ComponentTestProgram', **kwargs) - - env['PROGRAM_BASENAME'] = prog_name - env['PROGRAM_NAME'] = '$PROGPREFIX$PROGRAM_BASENAME$PROGSUFFIX' - - # Call env.Program() - out_nodes = env.Program(prog_name, *args, **kwargs) - - # Add dependencies on includes - env.Depends(out_nodes, env['INCLUDES']) - - # Publish output - env.Publish(prog_name, 'run', out_nodes[0]) - env.Publish(prog_name, 'debug', out_nodes[1:]) - - # Add an alias to build the program to the right groups - a = env.Alias(prog_name, out_nodes) - for group in env['COMPONENT_TEST_PROGRAM_GROUPS']: - SCons.Script.Alias(group, a) - - # Store list of components for this program - env._StoreComponents(prog_name) - - # Let component_targets know this target is available in the current mode - env.SetTargetProperty(prog_name, TARGET_PATH=out_nodes[0]) - - # Set up deferred call to replicate resources and run test - env.Defer(ComponentTestProgramDeferred) - - # Return the output node - return out_nodes - -#------------------------------------------------------------------------------ - - -def ComponentProgramDeferred(env): - """Deferred build steps for program. - - Args: - env: Environment from ComponentProgram(). - - Sets up the aliases to compile the program. - """ - prog_name = env['PROGRAM_BASENAME'] - - # Install program and resources - all_outputs = [] - components = _RetrieveComponents(prog_name) - for resource, dest_dir in env.get('COMPONENT_PROGRAM_RESOURCES').items(): - all_outputs += env.ReplicatePublished(dest_dir, components, resource) - - # Add installed program and resources to the alias - env.Alias(prog_name, all_outputs) - - -def ComponentProgram(self, prog_name, *args, **kwargs): - """Pseudo-builder for program to handle platform-dependent type. - - Args: - self: Environment in which we were called. - prog_name: Test program name. - args: Positional arguments. - kwargs: Keyword arguments. - - Returns: - Output node list from env.Program(). - """ - # Clone and modify environment - env = _ComponentPlatformSetup(self, 'ComponentProgram', **kwargs) - - env['PROGRAM_BASENAME'] = prog_name - - # Call env.Program() - out_nodes = env.Program(prog_name, *args, **kwargs) - - # Add dependencies on includes - env.Depends(out_nodes, env['INCLUDES']) - - # Publish output - env.Publish(prog_name, 'run', out_nodes[0]) - env.Publish(prog_name, 'debug', out_nodes[1:]) - - # Add an alias to build the program to the right groups - a = env.Alias(prog_name, out_nodes) - for group in env['COMPONENT_PROGRAM_GROUPS']: - SCons.Script.Alias(group, a) - - # Store list of components for this program - env._StoreComponents(prog_name) - - # Let component_targets know this target is available in the current mode - env.SetTargetProperty(prog_name) - - # Set up deferred call to replicate resources - env.Defer(ComponentProgramDeferred) - - # Return the output nodes - return out_nodes - -#------------------------------------------------------------------------------ - - -def ComponentTestOutput(self, test_name, nodes): - """Pseudo-builder for test output. - - Args: - self: Environment in which we were called. - test_name: Test name. - nodes: List of files/Nodes output by the test. - - Returns: - Passthrough return code from env.Alias(). - """ - - # Add an alias for the test output - a = self.Alias(test_name, nodes) - - groups = self.get('COMPONENT_TEST_OUTPUT_GROUPS') - if not groups: - # Output group not explicitly specified, so automatically add to groups - if self.get('COMPONENT_TEST_ENABLED'): - # Enabled tests go in all tests, and their size category - groups = ['run_all_tests'] - if self.get('COMPONENT_TEST_SIZE'): - groups.append(self.subst('run_${COMPONENT_TEST_SIZE}_tests')) - else: - # Disabled tests only go in their group - groups = ['run_disabled_tests'] - - for group in groups: - SCons.Script.Alias(group, a) - - # Let component_targets know this target is available in the current mode - self.SetTargetProperty(test_name, TARGET_PATH=nodes[0]) - - # Return the output node - return a - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - env.Replace( - LIB_DIR='$TARGET_ROOT/lib', - # TODO(rspangler): Remove legacy COMPONENT_LIBRARY_DIR, once all users - # have transitioned to LIB_DIR - COMPONENT_LIBRARY_DIR='$LIB_DIR', - STAGING_DIR='$TARGET_ROOT/staging', - TESTS_DIR='$TARGET_ROOT/tests', - TEST_OUTPUT_DIR='$TARGET_ROOT/test_output', - # Default command line for a test is just the name of the file. - # TODO(rspangler): Why doesn't the following work: - # COMPONENT_TEST_CMDLINE='${SOURCE.abspath}', - # (it generates a SCons error) - COMPONENT_TEST_CMDLINE='${PROGRAM_NAME}', - # Component tests are runnable by default. - COMPONENT_TEST_RUNNABLE=True, - # Default test size is large - COMPONENT_TEST_SIZE='large', - # Default timeouts for component tests - COMPONENT_TEST_TIMEOUT={'large': 900, 'medium': 450, 'small': 180}, - # Tests are enabled by default - COMPONENT_TEST_ENABLED=True, - # Static linking is a sensible default - COMPONENT_STATIC=True, - # Don't publish libraries to the staging dir by themselves by default. - COMPONENT_LIBRARY_PUBLISH=False, - ) - env.Append( - LIBPATH=['$LIB_DIR'], - RPATH=['$LIB_DIR'], - - # Default alias groups for component builders - COMPONENT_PACKAGE_GROUPS=['all_packages'], - COMPONENT_LIBRARY_GROUPS=['all_libraries'], - COMPONENT_PROGRAM_GROUPS=['all_programs'], - COMPONENT_TEST_PROGRAM_GROUPS=['all_test_programs'], - - # Additional components whose resources should be copied into program - # directories, in addition to those from LIBS and the program itself. - LIBS=[], - COMPONENTS=[], - - # Dicts of what resources should go in each destination directory for - # programs and test programs. - COMPONENT_PACKAGE_RESOURCES={ - 'run': '$PACKAGE_DIR', - 'debug': '$PACKAGE_DIR', - }, - COMPONENT_PROGRAM_RESOURCES={ - 'run': '$STAGING_DIR', - 'debug': '$STAGING_DIR', - }, - COMPONENT_TEST_RESOURCES={ - 'run': '$TESTS_DIR', - 'debug': '$TESTS_DIR', - 'test_input': '$TESTS_DIR', - }, - ) - - # Add command line option for retest - SCons.Script.AddOption( - '--retest', - dest='component_test_retest', - action='store_true', - help='force all tests to rerun') - SCons.Script.Help(' --retest ' - 'Rerun specified tests, ignoring cached results.\n') - - # Defer per-environment initialization, but do before building SConscripts - env.Defer(_InitializeComponentBuilders) - env.Defer('BuildEnvironmentSConscripts', after=_InitializeComponentBuilders) - - # Add our pseudo-builder methods - env.AddMethod(_StoreComponents) - env.AddMethod(ComponentPackage) - env.AddMethod(ComponentObject) - env.AddMethod(ComponentLibrary) - env.AddMethod(ComponentProgram) - env.AddMethod(ComponentTestProgram) - env.AddMethod(ComponentTestOutput) - - # Add our target groups - AddTargetGroup('all_libraries', 'libraries can be built') - AddTargetGroup('all_programs', 'programs can be built') - AddTargetGroup('all_test_programs', 'tests can be built') - AddTargetGroup('all_packages', 'packages can be built') - AddTargetGroup('run_all_tests', 'tests can be run') - AddTargetGroup('run_disabled_tests', 'tests are disabled') - AddTargetGroup('run_small_tests', 'small tests can be run') - AddTargetGroup('run_medium_tests', 'medium tests can be run') - AddTargetGroup('run_large_tests', 'large tests can be run') - diff --git a/site_scons/site_tools/component_setup.py b/site_scons/site_tools/component_setup.py deleted file mode 100644 index 7155655..0000000 --- a/site_scons/site_tools/component_setup.py +++ /dev/null @@ -1,270 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Main setup for software construction toolkit. - -This module is a SCons tool which should be include in all environments. -It is used as follows: - env = Environment(tools = ['component_setup']) -and should be the first tool from this toolkit referenced by any environment. -""" - -import os -import sys -import SCons - - -#------------------------------------------------------------------------------ - - -def InstallUsingLink(target, source, env): - """Install function for environment which uses link in preference to copy. - - Args: - target: Destintion filename - source: Source filename - env: Environment - - Returns: - Return code from SCons Node link function. - """ - - # Use link function for Install() and InstallAs(), since it's much much - # faster than copying. This is ok for the way we build clients, where we're - # installing to a build output directory and not to a permanent location such - # as /usr/bin. - # Need to force the target and source to be lists of nodes - return SCons.Node.FS.LinkFunc([env.Entry(target)], [env.Entry(source)], env) - - -def PreEvaluateVariables(env): - """Deferred function to pre-evaluate SCons varables for each build mode. - - Args: - env: Environment for the current build mode. - """ - # Convert directory variables to strings. Must use .abspath not str(), since - # otherwise $OBJ_ROOT is converted to a relative path, which evaluates - # improperly in SConscripts not in $MAIN_DIR. - for var in env.SubstList2('$PRE_EVALUATE_DIRS'): - env[var] = env.Dir('$' + var).abspath - - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Use MD5 to tell when files differ, if the timestamps differ. This is - # better than pure MD5 (since if the timestamps are the same, we don't need - # to rescan the file), and also better than pure timestamp (since if a file - # is rebuilt to the same contents, we don't need to trigger the build steps - # which depend on it). - env.Decider('MD5-timestamp') - - # Use implicit-cache by default. This means that SCons doesn't scan all the - # directories looking for include files found in an earlier directory in the - # include path. For continuous builds, this is not an issue because they're - # usually clean builds (so there wouldn't be a cache to load anyway). - # - # If you're doing a continuous incremental build, just use the - # --implicit-deps-changed option to force SCons to ignore its implicit cache. - # - # Use SCons.Script.SetOption() rather than env.SetOption() to make it clear - # this is a global setting, not just a setting for the current environment. - SCons.Script.SetOption('implicit_cache', 1) - - # For duplication order, use hard links then fall back to copying. Don't use - # soft links, since those won't do the right thing if the output directory - # is tar'd up and moved elsewhere. - SCons.Script.SetOption('duplicate', 'hard-copy') - - # Remove the alias namespace lookup function from the list which SCons uses - # when coercing strings into nodes. This prevents SCons from looking up - # aliases in input/output lists if they're not explicitly coerced via - # Alias(), and removes a conflict where a program has the same shorthand - # alias as the program name itself. This conflict manifests itself as a - # python exception if you try to build a program in multiple modes on linux, - # for example: - # hammer --mode=dbg,opt port_test - new_lookup_list = [] - for func in env.lookup_list: - if func.im_class != SCons.Node.Alias.AliasNameSpace: - new_lookup_list.append(func) - env.lookup_list = new_lookup_list - - # Cover part of the environment - env.Replace( - # Add a reference to our python executable, so subprocesses can find and - # invoke python. - PYTHON = env.File(sys.executable), - - # Get the absolute path to the directory containing main.scons (or - # SConstruct). This should be used in place of the SCons variable '#', - # since '#' is not always replaced (for example, when being used to set - # an environment variable). - MAIN_DIR = env.Dir('#').abspath, - # Supply deprecated SCONSTRUCT_DIR for legacy suport - # TODO(rspangler): remove legacy support once everyone has switched over. - SCONSTRUCT_DIR = env.Dir('#').abspath, - - # Use install function above, which uses links in preference to copying. - INSTALL = InstallUsingLink, - ) - - # Specify defaults for variables where we don't need to force replacement - env.SetDefault( - # Environments are in the 'all' group by default - BUILD_GROUPS=['all'], - - # Directories - DESTINATION_ROOT='$MAIN_DIR/scons-out$HOST_PLATFORM_SUFFIX', - TARGET_ROOT='$DESTINATION_ROOT/$BUILD_TYPE', - OBJ_ROOT='$TARGET_ROOT/obj', - ARTIFACTS_DIR='$TARGET_ROOT/artifacts', - ) - - # Add default list of variables we should pre-evaluate for each build mode - env.Append(PRE_EVALUATE_DIRS = [ - 'ARTIFACTS_DIR', - 'DESTINATION_ROOT', - 'OBJ_ROOT', - 'SOURCE_ROOT', - 'TARGET_ROOT', - 'TOOL_ROOT', - ]) - - # If a host platform was specified, need to put the SCons output in its own - # destination directory. Different host platforms compile the same files - # different ways, so need their own .sconsign files. - force_host_platform = SCons.Script.GetOption('host_platform') - if force_host_platform: - env['HOST_PLATFORM_SUFFIX'] = '-' + force_host_platform - - # Put the .sconsign.dblite file in our destination root directory, so that we - # don't pollute the source tree. Use the '_' + sys.platform suffix to prevent - # the .sconsign.dblite from being shared between host platforms, even in the - # case where the --host_platform option is not used (for instance when the - # project has platform suffixes on all the build types). - # This will prevent host platforms from mistakenly using each others .sconsign - # databases and will allow two host platform builds to occur in the same - # shared tree simulataneously. - sconsign_dir = env.Dir('$DESTINATION_ROOT').abspath - sconsign_filename = '$DESTINATION_ROOT/.sconsign_%s' % sys.platform - sconsign_file = env.File(sconsign_filename).abspath - # TODO(sgk): SConsignFile() doesn't seem to like it if the destination - # directory doesn't already exists, so make sure it exists. - if not os.path.isdir(sconsign_dir): - os.makedirs(sconsign_dir) - SCons.Script.SConsignFile(sconsign_file) - - # Build all by default - # TODO(rspangler): This would be more nicely done by creating an 'all' - # alias and mapping that to $DESTINATION_ROOT (or the accumulation of all - # $TARGET_ROOT's for the environments which apply to the current host - # platform). Ideally, that would be done in site_init.py and not here. But - # since we can't do that, just set the default to be DESTINATION_ROOT here. - # Note that this currently forces projects which want to override the - # default to do so after including the component_setup tool. - env.Default('$DESTINATION_ROOT') - - # Use brief command line strings if necessary - SCons.Script.Help("""\ - --verbose Print verbose output while building, including - the full command lines for all commands. - --brief Print brief output while building (the default). - This and --verbose are opposites. Use --silent - to turn off all output. -""") - SCons.Script.AddOption( - '--brief', - dest='brief_comstr', - default=True, - action='store_true', - help='brief command line output') - SCons.Script.AddOption( - '--verbose', - dest='brief_comstr', - default=True, - action='store_false', - help='verbose command line output') - if env.GetOption('brief_comstr'): - env.SetDefault( - ARCOMSTR='________Creating library $TARGET', - ASCOMSTR='________Assembling $TARGET', - CCCOMSTR='________Compiling $TARGET', - CONCAT_SOURCE_COMSTR='________ConcatSource $TARGET', - CXXCOMSTR='________Compiling $TARGET', - LDMODULECOMSTR='________Building loadable module $TARGET', - LINKCOMSTR='________Linking $TARGET', - MANIFEST_COMSTR='________Updating manifest for $TARGET', - MIDLCOMSTR='________Compiling IDL $TARGET', - PCHCOMSTR='________Precompiling $TARGET', - RANLIBCOMSTR='________Indexing $TARGET', - RCCOMSTR='________Compiling resource $TARGET', - SHCCCOMSTR='________Compiling $TARGET', - SHCXXCOMSTR='________Compiling $TARGET', - SHLINKCOMSTR='________Linking $TARGET', - SHMANIFEST_COMSTR='________Updating manifest for $TARGET', - ) - - # Add other default tools from our toolkit - # TODO(rspangler): Currently this needs to be before SOURCE_ROOT in case a - # tool needs to redefine it. Need a better way to handle order-dependency - # in tool setup. - for t in component_setup_tools: - env.Tool(t) - - # The following environment replacements use env.Dir() to force immediate - # evaluation/substitution of SCons variables. They can't be part of the - # preceding env.Replace() since they they may rely indirectly on variables - # defined there, and the env.Dir() calls would be evaluated before the - # env.Replace(). - - # Set default SOURCE_ROOT if there is none, assuming we're in a local - # site_scons directory for the project. - source_root_relative = os.path.normpath( - os.path.join(os.path.dirname(__file__), '../..')) - source_root = env.get('SOURCE_ROOT', source_root_relative) - env['SOURCE_ROOT'] = env.Dir(source_root).abspath - - # Make tool root separate from source root so it can be overridden when we - # have a common location for tools outside of the current clientspec. Need - # to check if it's defined already, so it can be set prior to this tool - # being included. - tool_root = env.get('TOOL_ROOT', '$SOURCE_ROOT') - env['TOOL_ROOT'] = env.Dir(tool_root).abspath - - # Defer pre-evaluating some environment variables, but do before building - # SConscripts. - env.Defer(PreEvaluateVariables) - env.Defer('BuildEnvironmentSConscripts', after=PreEvaluateVariables) diff --git a/site_scons/site_tools/component_targets.py b/site_scons/site_tools/component_targets.py deleted file mode 100755 index 53a0b26..0000000 --- a/site_scons/site_tools/component_targets.py +++ /dev/null @@ -1,269 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Software construction toolkit target management for SCons.""" - - -import __builtin__ -import SCons.Script - - -# Dict of target groups (TargetGroup indexed by group name) -__target_groups = {} - -# Dict of targets (Target indexed by target name) -__targets = {} - -# Dict of target modes (TargetMode indexed by mode name) -__target_modes = {} - -#------------------------------------------------------------------------------ - - -class TargetGroup(object): - """Target group, as used by AddTargetGroup() and GetTargetGroups().""" - - def __init__(self, name, description): - """Initializes the target group. - - Args: - name: Name of the target group. - description: Description of group. - """ - self.name = name - self.description = description - - def GetTargetNames(self): - """Returns a list of target name strings for the group.""" - items = map(str, SCons.Script.Alias(self.name)[0].sources) - # Remove duplicates from multiple environments - return list(set(items)) - -#------------------------------------------------------------------------------ - - -class TargetMode(object): - """Target mode, as used by GetTargetModes().""" - - def __init__(self, name, description): - """Initializes the target mode. - - Args: - name: Name of the target mode. - description: Description of mode. - """ - self.name = name - self.description = description - - def GetTargetNames(self): - """Returns a list of target name strings for the group.""" - items = map(str, SCons.Script.Alias(self.name)[0].sources) - # Remove duplicates from multiple environments - return list(set(items)) - -#------------------------------------------------------------------------------ - - -class Target(object): - """Target object.""" - - def __init__(self, name): - """Initializes the target. - - Args: - name: Name of the target. - """ - self.name = name - self.properties = {} # Global properties - self.mode_properties = {} # Dict of modes to mode-specific properties - -#------------------------------------------------------------------------------ - - -def AddTargetGroup(name, description): - """Adds a target group, used for printing help. - - Args: - name: Name of target group. This should be the name of an alias which - points to other aliases for the specific targets. - description: Description of the target group. Should read properly when - appended to 'The following ' - for example, 'programs can be built'. - """ - - # Warn if the target group already exists with a different description - if (name in __target_groups - and __target_groups[name].description != description): - print ('Warning: Changing description of target group "%s" from "%s" to ' - '"%s"' % (name, __target_groups[name].description, description)) - __target_groups[name].description = description - else: - __target_groups[name] = TargetGroup(name, description) - - -def GetTargetGroups(): - """Gets the dict of target groups. - - Returns: - The dict of target groups, indexed by group name. - - This dict is not fully populated until after BuildEnvironments() has been - called. - """ - return __target_groups - - -def GetTargetModes(): - """Gets the dict of target modes. - - Returns: - The dict of target modes, indexed by mode name. - - This dict is not fully populated until after BuildEnvironments() has been - called. - """ - # TODO(rspangler): Better to rename this to # GetTargetBuildEnvironments()? - # That's a more description name. - return __target_modes - - -def GetTargets(): - """Gets the dict of targets. - - Returns: - The dict of targets, indexed by target name. - - This dict is not fully populated until after BuildEnvironments() has been - called. - """ - return __targets - - -def SetTargetProperty(self, target_name, all_modes=False, **kwargs): - """Sets one or more properties for a target. - - Args: - self: Environment context. - target_name: Name of the target. - all_modes: If True, property applies to all modes. If false, it applies - only to the current mode (determined by self['BUILD_TYPE']). - kwargs: Keyword args are used to set properties. Properties will be - converted to strings via env.subst(). - - For example: - foo_test = env.Program(...)[0] - env.SetTargetProperty('foo_test', global=True, DESCRIPTION='Foo test') - env.SetTargetProperty('foo_test', EXE=foo_test) - """ - # Get the target - if target_name not in __targets: - __targets[target_name] = Target(target_name) - target = __targets[target_name] - - if all_modes: - add_to_dict = target.properties - else: - mode = self.get('BUILD_TYPE') - if mode not in target.mode_properties: - target.mode_properties[mode] = {} - add_to_dict = target.mode_properties[mode] - - # Add values - for k, v in kwargs.items(): - add_to_dict[k] = self.subst(str(v)) - - -def AddTargetHelp(): - """Adds SCons help for the targets, groups, and modes. - - This is called automatically by BuildEnvironments().""" - help_text = '' - - for group in GetTargetGroups().values(): - items = group.GetTargetNames() - items.sort() - if items: - help_text += '\nThe following %s:' % group.description - colwidth = max(map(len, items)) + 2 - cols = 77 / colwidth - if cols < 1: - cols = 1 # If target names are really long, one per line - rows = (len(items) + cols - 1) / cols - for row in range(0, rows): - help_text += '\n ' - for i in range(row, len(items), rows): - help_text += '%-*s' % (colwidth, items[i]) - help_text += '\n %s (do all of the above)\n' % group.name - - SCons.Script.Help(help_text) - - -def SetTargetDescription(self, target_name, description): - """Convenience function to set a target's global DESCRIPTION property. - - Args: - self: Environment context. - target_name: Name of the target. - description: Description of the target. - """ - self.SetTargetProperty(target_name, all_modes=True, DESCRIPTION=description) - - -def AddTargetMode(env): - """Adds the environment as a target mode. - - Args: - env: Environment context. - - Called via env.Defer() for each build mode. - """ - # Save the build mode and description - mode = env.get('BUILD_TYPE') - __target_modes[mode] = TargetMode(mode, env.get('BUILD_TYPE_DESCRIPTION')) - - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - env = env # Silence gpylint - - __builtin__.AddTargetGroup = AddTargetGroup - __builtin__.AddTargetHelp = AddTargetHelp - __builtin__.GetTargetGroups = GetTargetGroups - __builtin__.GetTargetModes = GetTargetModes - __builtin__.GetTargets = GetTargets - - env.AddMethod(SetTargetDescription) - env.AddMethod(SetTargetProperty) - - # Defer per-mode setup - env.Defer(AddTargetMode) diff --git a/site_scons/site_tools/component_targets_msvs.py b/site_scons/site_tools/component_targets_msvs.py deleted file mode 100755 index 6afc7fe..0000000 --- a/site_scons/site_tools/component_targets_msvs.py +++ /dev/null @@ -1,997 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Visual Studio solution output of component targets for SCons.""" - -import copy -import md5 -import os -import sys -import xml.dom -import xml.dom.minidom -import SCons - - -#------------------------------------------------------------------------------ - - -def MakeGuid(name, seed='component_targets_msvs'): - """Returns a GUID for the specified target name. - - Args: - name: Target name. - seed: Seed for MD5 hash. - Returns: - A GUID-line string calculated from the name and seed. - - This generates something which looks like a GUID, but depends only on the - name and seed. This means the same name/seed will always generate the same - GUID, so that projects and solutions which refer to each other can explicitly - determine the GUID to refer to explicitly. It also means that the GUID will - not change when the project for a target is rebuilt. - """ - # Calculate a MD5 signature for the seed and name. - d = md5.new(str(seed) + str(name)).hexdigest().upper() - # Convert most of the signature to GUID form (discard the rest) - guid = ('{' + d[:8] + '-' + d[8:12] + '-' + d[12:16] + '-' + d[16:20] - + '-' + d[20:32] + '}') - return guid - -#------------------------------------------------------------------------------ - - -def GetGuidAndNameFromVSProject(project_path): - """Reads the GUID from a Visual Studio project file. - - Args: - project_path: Path to the Visual Studio project file. - - Returns: - The GUID string from the file. - The project name from the file. - """ - doc = xml.dom.minidom.parse(project_path) - try: - n_root = doc.documentElement - if n_root.nodeName != 'VisualStudioProject': - raise SCons.Errors.UserError('%s is not a Visual Studio project.' % - project_path) - return ( - str(n_root.attributes['ProjectGUID'].nodeValue), - str(n_root.attributes['Name'].nodeValue), - ) - finally: - # Clean up doc - doc.unlink() - -#------------------------------------------------------------------------------ - - -class VSProjectWriter(object): - """Visual Studio XML project writer.""" - - def __init__(self, project_path): - """Initializes the project. - - Args: - project_path: Path to the project file. - """ - self.project_path = project_path - self.doc = None - - def Create(self, name): - """Creates the project document. - - Args: - name: Name of the project. - """ - self.name = name - self.guid = MakeGuid(name) - - # Create XML doc - xml_impl = xml.dom.getDOMImplementation() - self.doc = xml_impl.createDocument(None, 'VisualStudioProject', None) - - # Add attributes to root element - self.n_root = self.doc.documentElement - self.n_root.setAttribute('ProjectType', 'Visual C++') - self.n_root.setAttribute('Version', '8.00') - self.n_root.setAttribute('Name', self.name) - self.n_root.setAttribute('ProjectGUID', self.guid) - self.n_root.setAttribute('RootNamespace', self.name) - self.n_root.setAttribute('Keyword', 'MakeFileProj') - - # Add platform list - n_platform = self.doc.createElement('Platforms') - self.n_root.appendChild(n_platform) - n = self.doc.createElement('Platform') - n.setAttribute('Name', 'Win32') - n_platform.appendChild(n) - - # Add empty ToolFiles section - self.n_root.appendChild(self.doc.createElement('ToolFiles')) - - # Add configurations section - self.n_configs = self.doc.createElement('Configurations') - self.n_root.appendChild(self.n_configs) - - # Add files section - self.n_files = self.doc.createElement('Files') - self.n_root.appendChild(self.n_files) - - # Add empty Globals section - self.n_root.appendChild(self.doc.createElement('Globals')) - - def AddConfig(self, name, attrs, tool_attrs): - """Adds a configuration to the project. - - Args: - name: Configuration name. - attrs: Dict of configuration attributes. - tool_attrs: Dict of tool attributes. - """ - # Add configuration node - n_config = self.doc.createElement('Configuration') - n_config.setAttribute('Name', '%s|Win32' % name) - n_config.setAttribute('ConfigurationType', '0') - for k, v in attrs.items(): - n_config.setAttribute(k, v) - self.n_configs.appendChild(n_config) - - # Add tool node - n_tool = self.doc.createElement('Tool') - n_tool.setAttribute('Name', 'VCNMakeTool') - n_tool.setAttribute('IncludeSearchPath', '') - n_tool.setAttribute('ForcedIncludes', '') - n_tool.setAttribute('AssemblySearchPath', '') - n_tool.setAttribute('ForcedUsingAssemblies', '') - n_tool.setAttribute('CompileAsManaged', '') - n_tool.setAttribute('PreprocessorDefinitions', '') - for k, v in tool_attrs.items(): - n_tool.setAttribute(k, v) - n_config.appendChild(n_tool) - - def _WalkFolders(self, folder_dict, parent): - """Recursively walks the folder tree. - - Args: - folder_dict: Dict of folder entries. Entry is - either subdir_name:subdir_dict or relative_path_to_file:None. - parent: Parent node (folder node for that dict) - """ - entries = folder_dict.keys() - entries.sort() - for e in entries: - if folder_dict[e]: - # Folder - n_subfolder = self.doc.createElement('Filter') - n_subfolder.setAttribute('Name', e) - parent.appendChild(n_subfolder) - self._WalkFolders(folder_dict[e], n_subfolder) - else: - # File - n_file = self.doc.createElement('File') - n_file.setAttribute('RelativePath', e) - parent.appendChild(n_file) - - def AddFiles(self, name, files_dict): - """Adds files to the project. - - Args: - name: Name of the folder. If None, files/folders will be added directly - to the files list. - files_dict: A dict of files / folders. - - Within the files_dict: - * A file entry is relative_path:None - * A folder entry is folder_name:files_dict, where files_dict is another - dict of this form. - """ - # Create subfolder if necessary - if name: - n_folder = self.doc.createElement('Filter') - n_folder.setAttribute('Name', name) - self.n_files.appendChild(n_folder) - else: - n_folder = self.n_files - - # Recursively add files to the folder - self._WalkFolders(files_dict, n_folder) - - def Write(self): - """Writes the project file.""" - f = open(self.project_path, 'wt') - self.doc.writexml(f, encoding='Windows-1252', addindent=' ', newl='\n') - f.close() - -#------------------------------------------------------------------------------ - - -def ComponentVSProjectBuilder(target, source, env): - """Visual Studio project builder. - - Args: - target: Destination file. - source: List of sources to be added to the target. - env: Environment context. - - Returns: - Zero if successful. - """ - source = source # Silence gpylint - - target_name = env['TARGET_NAME'] - project_file = target[0].path - project_to_main = env.RelativePath(target[0].dir, env.Dir('$MAIN_DIR'), - sep='/') - - env_hammer_bat = env.Clone(VS_PROJECT_TO_MAIN_DIR=project_to_main) - hammer_bat = env_hammer_bat.subst('$COMPONENT_VS_PROJECT_SCRIPT_PATH', raw=1) - - vsp = VSProjectWriter(project_file) - vsp.Create(target_name) - - # Add configuration per build mode supported by this target - target_path = env['TARGET_PATH'] - for mode, path in target_path.items(): - attrs = {} - attrs['OutputDirectory'] = '$(ProjectDir)/%s/%s/out' % (mode, target_name) - attrs['IntermediateDirectory'] = ('$(ProjectDir)/%s/%s/tmp' % - (mode, target_name)) - - tool_attrs = {} - if path: - tool_attrs['Output'] = env.RelativePath(target[0].dir, - env.Entry(path), sep='/') - build_cmd = '%s --mode=%s %s' % (hammer_bat, mode, target_name) - clean_cmd = '%s --mode=%s -c %s' % (hammer_bat, mode, target_name) - tool_attrs['BuildCommandLine'] = build_cmd - tool_attrs['CleanCommandLine'] = clean_cmd - tool_attrs['ReBuildCommandLine'] = clean_cmd + ' && ' + build_cmd - - vsp.AddConfig(mode, attrs, tool_attrs) - - # TODO(rspangler): Fill in files - at least, the .scons file invoking the - # target. - - # Write project - vsp.Write() - return 0 - - -def ComponentVSProject(self, target_name, **kwargs): - """Visual Studio project pseudo-builder for the specified target. - - Args: - self: Environment context. - target_name: Name of the target. - kwargs: Optional keyword arguments override environment variables in the - derived environment used to create the project. - - Returns: - A list of output nodes. - """ - # Builder only works on Windows - if sys.platform not in ('win32', 'cygwin'): - return [] - - # Clone environment and add keyword args - env = self.Clone() - for k, v in kwargs.items(): - env[k] = v - - # Save the target name - env['TARGET_NAME'] = target_name - - # Extract the target properties and save in the environment for use by the - # real builder. - t = GetTargets().get(target_name) - env['TARGET_PATH'] = {} - if t: - for mode, mode_properties in t.mode_properties.items(): - # Since the target path is what Visual Studio will run, use the EXE - # property in preference to TARGET_PATH. - target_path = mode_properties.get('EXE', - mode_properties.get('TARGET_PATH')) - env.Append(TARGET_PATH={mode: target_path}) - else: - # No modes declared for this target. Could be a custom alias created by - # a SConscript, rather than a component builder. Assume it can be built in - # all modes, but produces no output. - for mode in GetTargetModes(): - env.Append(TARGET_PATH={mode: None}) - - # Call the real builder - return env.ComponentVSProjectBuilder( - '$COMPONENT_VS_PROJECT_DIR/${TARGET_NAME}', []) - -#------------------------------------------------------------------------------ - - -class SourceWalker(object): - """Iterator for walking a node tree and collecting sources. - - This is depth-first, children are visited before the parent. The object - can be initialized with any node, and returns the next node on the descent - with each Next() call. - - This class does not get caught in node cycles caused, for example, by C - header file include loops. - - Based on SCons.Node.Walker. - """ - - def __init__(self, node, seen, print_interval = 1000): - """Initializes the source walker. - - Args: - node: Node to start walk from. - seen: Set to add seen nodes to, if not None. - print_interval: Interval in nodes examined at which to print a progress - indicator. - """ - self.interval = print_interval - # Put node on stack - self.stack = [node] - # Scan for node's children, then copy them to node.wkids - node.wkids = copy.copy(node.children(scan=1)) - # Keep track of nodes we've seen (returned) - if seen is None: - seen = set() - self.seen = seen - # Add node to history for cycle detection - self.history = set() - self.history.add(node) - # We've seen one node now - self.nodes_examined = 1 - self.unique_nodes = 1 - - - def Next(self): - """Get the next node for this walk of the tree. - - Returns: - The next node, or None if no more nodes. - - This function is intentionally iterative, not recursive, to sidestep any - issues of stack size limitations. - """ - while self.stack: - if self.stack[-1].wkids: - # Node has children we haven't examined, so iterate into the first - # child - node = self.stack[-1].wkids.pop(0) - if not self.stack[-1].wkids: - # No more children of this node - self.stack[-1].wkids = None - self.nodes_examined += 1 - if self.interval and not self.nodes_examined % self.interval: - self.PrintProgress() - if (node not in self.history) and (node not in self.seen): - # Haven't hit a cycle or a node we've already seen - node.wkids = copy.copy(node.children(scan=1)) - self.stack.append(node) - self.history.add(node) - else: - # Coming back from iterating, so return the next node on the stack. - node = self.stack.pop() - self.history.remove(node) - self.seen.add(node) - self.unique_nodes += 1 - return node - return None - - def PrintProgress(self): - """Prints a progress indicator.""" - print ' Examined %d nodes, found %d unique...' % ( - self.nodes_examined, self.unique_nodes) - - def WalkAll(self): - """Walks all nodes in the the tree.""" - while self.Next(): - pass - if self.interval: - self.PrintProgress() - - -def ComponentVSSourceProjectBuilder(target, source, env): - """Visual Studio source project builder. - - Args: - target: Destination file. - source: List of sources to be added to the target. - env: Environment context. - - Returns: - Zero if successful. - """ - source = source # Silence gpylint - - target_name = env['PROJECT_NAME'] - project_file = target[0].path - project_dir = target[0].dir - - # Get list of suffixes to include - suffixes = env.SubstList2('$COMPONENT_VS_SOURCE_SUFFIXES') - - # Convert source folders to absolute paths - folders = [] - for f in env['COMPONENT_VS_SOURCE_FOLDERS']: - # (folder name, folder abspath, dict of contents) - folders.append((f[0], env.Dir(f[1]).abspath, {})) - - # TODO(rspangler): Additional enhancements: - # * Should be able to specify paths in folder name (i.e., foo/bar) and - # create the nested folder nodes ('foo' and 'bar') - # * Should be tolerant of a folder being specified more than once with - # the same name (probably necessary to support nested folder nodes anyway) - # Can probably accomplish both of those by creating a parent fodler dict and - # calling WalkFolders() only once. - # Create a temporary solution alias to point to all the targets, so we can - # make a single call to SourceWalker() - tmp_alias = env.Alias('vs_source_project_' + target_name, - map(env.Alias, env['COMPONENT_VS_SOURCE_TARGETS'])) - - # Scan all targets and add unique nodes to set of sources - print ' Scanning dependency tree ...' - all_srcs = set() - walker = SourceWalker(tmp_alias[0], all_srcs) - walker.WalkAll() - - # Walk all sources and build directory trees - print ' Building source tree...' - for n in all_srcs: - if not hasattr(n, 'isfile') or not n.isfile(): - continue # Not a file - if n.has_builder(): - continue # Not a leaf node - if n.suffix not in suffixes: - continue # Not a file type we include - - path = n.rfile().abspath - for f in folders: - if path.startswith(f[1]): - if f[0] is None: - # Folder name of None is a filter - break - relpath = path[len(f[1]) + 1:].split(os.sep) - folder_dict = f[2] - # Recursively add subdirs - for pathseg in relpath[:-1]: - if pathseg not in folder_dict: - folder_dict[pathseg] = {} - folder_dict = folder_dict[pathseg] - # Add file to last subdir. No dict, since this isn't a subdir - folder_dict[env.RelativePath(project_dir, path)] = None - break - - print ' Writing project file...' - - vsp = VSProjectWriter(project_file) - vsp.Create(target_name) - - # One configuration for all build modes - vsp.AddConfig('all', {}, {}) - - # Add files - for f in folders: - if f[0] is None: - continue # Skip filters - vsp.AddFiles(f[0], f[2]) - - vsp.Write() - return 0 - - -def ComponentVSSourceProject(self, project_name, target_names, **kwargs): - """Visual Studio source project pseudo-builder. - - Args: - self: Environment context. - project_name: Name of the project. - target_names: List of target names to include source for. - kwargs: Optional keyword arguments override environment variables in the - derived environment used to create the project. - - Returns: - A list of output nodes. - """ - # Builder only works on Windows - if sys.platform not in ('win32', 'cygwin'): - return [] - - # Clone environment and add keyword args - env = self.Clone() - for k, v in kwargs.items(): - env[k] = v - - # Save the project name and targets - env['PROJECT_NAME'] = project_name - env['COMPONENT_VS_SOURCE_TARGETS'] = target_names - - # Call the real builder - return env.ComponentVSSourceProjectBuilder( - '$COMPONENT_VS_PROJECT_DIR/${PROJECT_NAME}', []) - -#------------------------------------------------------------------------------ - - -def FindSources(env, dest, source, suffixes=None): - """Recursively finds sources and adds them to the destination set. - - Args: - env: Environment context. - dest: Set to add source nodes to. - source: Source file(s) to find. May be a string, Node, or a list of - mixed strings or Nodes. Strings will be passed through env.Glob() to - evaluate wildcards. If a source evaluates to a directory, the entire - directory will be recursively added. - suffixes: List of suffixes to include. If not None, only files with these - suffixes will be added to dest. - """ - for source_entry in env.Flatten(source): - if type(source_entry) == str: - # Search for matches for each source entry - source_nodes = env.Glob(source_entry) - else: - # Source entry is already a file or directory node; no need to glob it - source_nodes = [source_entry] - for s in source_nodes: - if str(s.__class__) == 'SCons.Node.FS.Dir': - # Recursively search subdir. Since glob('*') doesn't match dot files, - # also glob('.*'). - FindSources(env, dest, [s.abspath + '/*', s.abspath + '/.*'], suffixes) - elif suffixes and s.suffix in suffixes: - dest.add(s) - - -def ComponentVSDirProjectBuilder(target, source, env): - """Visual Studio directory project builder. - - Args: - target: Destination file. - source: List of sources to be added to the target. - env: Environment context. - - Returns: - Zero if successful. - """ - source = source # Silence gpylint - - target_name = env['PROJECT_NAME'] - project_file = target[0].path - project_dir = target[0].dir - - # Convert source folders to absolute paths - folders = [] - for f in env['COMPONENT_VS_SOURCE_FOLDERS']: - # (folder name, folder abspath, dict of contents) - folders.append((f[0], env.Dir(f[1]).abspath, {})) - - # Recursively scan source directories - print ' Scanning directories for source...' - all_srcs = set() - FindSources(env, all_srcs, env['PROJECT_SOURCES'], - suffixes=env.SubstList2('$COMPONENT_VS_SOURCE_SUFFIXES')) - - # Walk all sources and build directory trees - print ' Building source tree...' - for n in all_srcs: - # Map addRepository'd source to its real location. - path = n.rfile().abspath - for f in folders: - if path.startswith(f[1]): - if f[0] is None: - # Folder name of None is a filter - break - relpath = path[len(f[1]) + 1:].split(os.sep) - folder_dict = f[2] - # Recursively add subdirs - for pathseg in relpath[:-1]: - if pathseg not in folder_dict: - folder_dict[pathseg] = {} - folder_dict = folder_dict[pathseg] - # Add file to last subdir. No dict, since this isn't a subdir - folder_dict[env.RelativePath(project_dir, path)] = None - break - - print ' Writing project file...' - - vsp = VSProjectWriter(project_file) - vsp.Create(target_name) - - # One configuration for all build modes - vsp.AddConfig('all', {}, {}) - - # Add files - for f in folders: - if f[0] is None: - continue # Skip filters - vsp.AddFiles(f[0], f[2]) - - vsp.Write() - return 0 - - -def ComponentVSDirProject(self, project_name, source, **kwargs): - """Visual Studio directory project pseudo-builder. - - Args: - self: Environment context. - project_name: Name of the project. - source: List of source files and/or directories. - kwargs: Optional keyword arguments override environment variables in the - derived environment used to create the project. - - Returns: - A list of output nodes. - """ - # Builder only works on Windows - if sys.platform not in ('win32', 'cygwin'): - return [] - - # Clone environment and add keyword args - env = self.Clone() - for k, v in kwargs.items(): - env[k] = v - - # Save the project name and sources - env['PROJECT_NAME'] = project_name - env['PROJECT_SOURCES'] = source - - # Call the real builder - return env.ComponentVSDirProjectBuilder( - '$COMPONENT_VS_PROJECT_DIR/${PROJECT_NAME}', []) - -#------------------------------------------------------------------------------ - - -def ComponentVSSolutionBuilder(target, source, env): - """Visual Studio solution builder. - - Args: - target: Destination file. - source: List of sources to be added to the target. - env: Environment context. - - Returns: - Zero if successful. - """ - source = source # Silence gpylint - - solution_file = target[0].path - projects = env['SOLUTION_PROJECTS'] - folders = env['SOLUTION_FOLDERS'] - - # Scan externally-generated projects - external_projects = [] - for p in source: - guid, name = GetGuidAndNameFromVSProject(p.abspath) - external_projects.append((p, name, guid)) - - f = open(solution_file, 'wt') - f.write('Microsoft Visual Studio Solution File, Format Version 9.00\n') - f.write('# Visual Studio 2005\n') - - # Projects generated by ComponentVSSolution() - for p in projects: - project_file = env.File( - '$COMPONENT_VS_PROJECT_DIR/%s$COMPONENT_VS_PROJECT_SUFFIX' % p) - f.write('Project("%s") = "%s", "%s", "%s"\nEndProject\n' % ( - '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}', # External makefile GUID - p, # Project name - env.RelativePath(target[0].dir, project_file), # Path to project file - MakeGuid(p), # Project GUID - )) - - # Projects generated elsewhere - for p, name, guid in external_projects: - f.write('Project("%s") = "%s", "%s", "%s"\nEndProject\n' % ( - # TODO(rspangler): What if this project isn't type external makefile? - # How to tell what type it is? - '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}', # External makefile GUID - name, # Project name - env.RelativePath(target[0].dir, p), # Path to project file - guid, # Project GUID - )) - - # Folders from build groups - # TODO(rspangler): Currently no way to add external project (specified in - # sources) to a solution folder. - for folder in folders: - f.write('Project("%s") = "%s", "%s", "%s"\nEndProject\n' % ( - '{2150E333-8FDC-42A3-9474-1A3956D46DE8}', # Solution folder GUID - folder, # Folder name - folder, # Folder name (again) - # Use a different seed so the folder won't get the same GUID as a - # project. - MakeGuid(folder, seed='folder'), # Project GUID - )) - - f.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n') - for mode in GetTargetModes(): - f.write('\t\t%s|Win32 = %s|Win32\n' % (mode, mode)) - f.write('\tEndGlobalSection\n') - - # Determine which projects should be enabled - # TODO(rspangler): This is somewhat clunky. DEFAULT_TARGETS is global, and - # what we really need is something mode-specific. In theory we could make - # this a mode-specific dict rather than a list, but that'd also be a pain to - # populate. - # These variable names are also getting REALLY long. Perhaps we should - # define shorter ones (with the default value redirecting to the longer - # ones for legacy compatibility). - enable_projects = env.SubstList2('$COMPONENT_VS_ENABLED_PROJECTS') - - f.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n') - - # Projects generated by ComponentVSSolution() - for p in projects: - for mode in GetTargetModes(): - f.write('\t\t%s.%s|Win32.ActiveCfg = %s|Win32\n' % ( - MakeGuid(p), # Project GUID - mode, # Solution build configuration - mode, # Project build config for that solution config - )) - - t = GetTargets().get(p) - - # Determine if project should be enabled in this mode - enabled = t and mode in t.mode_properties - if enable_projects and p not in enable_projects: - # Enable list specified, but target isn't in it - # TODO(rspangler): Since we env.Default(scons-out) elsewhere, this - # likely causes all projects to be disabled by default. But that's - # realistically better than enabling them all... - enabled = False - - if enabled: - # Target can be built in this mode - f.write('\t\t%s.%s|Win32.Build.0 = %s|Win32\n' % ( - MakeGuid(p), # Project GUID - mode, # Solution build configuration - mode, # Project build config for that solution config - )) - - # Projects generated elsewhere - for p, name, guid in external_projects: - for mode in GetTargetModes(): - f.write('\t\t%s.%s|Win32.ActiveCfg = %s|Win32\n' % ( - guid, # Project GUID - mode, # Solution build configuration - mode, # Project build config for that solution config - )) - - if name in enable_projects or not enable_projects: - # Build target in this mode - f.write('\t\t%s.%s|Win32.Build.0 = %s|Win32\n' % ( - guid, # Project GUID - mode, # Solution build configuration - mode, # Project build config for that solution config - )) - - f.write('\tEndGlobalSection\n') - - f.write('\tGlobalSection(SolutionProperties) = preSolution\n') - f.write('\t\tHideSolutionNode = FALSE\n') - f.write('\tEndGlobalSection\n') - - if folders: - f.write('\tGlobalSection(NestedProjects) = preSolution\n') - for p, folder in projects.items(): - f.write('\t\t%s = %s\n' % (MakeGuid(p), MakeGuid(folder, seed='folder'))) - f.write('\tEndGlobalSection\n') - - f.write('EndGlobal\n') - f.close() - - return 0 - - -def ComponentVSSolution(self, solution_name, target_names, projects=None, - **kwargs): - """Visual Studio solution pseudo-builder. - - Args: - self: Environment context. - solution_name: Name of the solution. - target_names: Names of targets or target groups to include in the solution. - This will automatically build projects for them. - projects: List of aditional projects not generated by this solution to - include in the solution. - kwargs: Optional keyword arguments override environment variables in the - derived environment used to create the solution. - - Returns: - The list of output nodes. - """ - # TODO(rspangler): Should have option to build source project also. Perhaps - # select using a --source_project option, since it needs to use gather_inputs - # to scan the DAG and will blow up the null build time. - # TODO(rspangler): Should also have autobuild_projects option. If false, - # don't build them. - # TODO(rspangler): Should also be able to specify a target group directly - # (i.e. 'run_all_tests') - - # Builder only works on Windows - if sys.platform not in ('win32', 'cygwin'): - return [] - - # Clone environment and add keyword args - env = self.Clone() - for k, v in kwargs.items(): - env[k] = v - - # Save the target name - env['SOLUTION_NAME'] = solution_name - - # Get list of targets to make projects for. At this point we haven't - # determined whether they're groups or targets. - target_names = env.SubstList2(target_names) - env['SOLUTION_TARGETS'] = target_names - - # Save the default targets list as an environment variable - env['COMPONENT_VS_SCONS_DEFAULT_TARGETS'] = SCons.Script.DEFAULT_TARGETS - - # Expand target_names into project names, and create project-to-folder - # mappings - project_names = {} - folders = [] - if target_names: - # Expand target_names into project names - for target in target_names: - if target in GetTargetGroups(): - # Add target to folders - folders.append(target) - # Add all project_names in the group - for t in GetTargetGroups()[target].GetTargetNames(): - project_names[t] = target - elif target in GetTargets(): - # Just a target name - project_names[target] = None - else: - print 'Warning: ignoring unknown target "%s"' % target - else: - # No target names specified, so use all projects - for t in GetTargets(): - project_names[t] = None - - env['SOLUTION_FOLDERS'] = folders - env['SOLUTION_PROJECTS'] = project_names - - # Call the real builder - out_nodes = env.ComponentVSSolutionBuilder( - '$COMPONENT_VS_SOLUTION_DIR/${SOLUTION_NAME}', projects or []) - - # Call the real builder for the projects we generate - for p in project_names: - out_nodes += env.ComponentVSProject(p) - - # Add the solution target - # TODO(rspangler): Should really defer the rest of the work above, since - # otherwise we can't build a solution which has a target to rebuild itself. - env.Alias('all_solutions', env.Alias(solution_name, out_nodes)) - - # TODO(rspangler): To rebuild the solution properly, need to override its - # project configuration so it only has '--mode=all' (or some other way of - # setting the subset of modes which it should use to rebuild itself). - # Rebuilding with the property below will strip it down to just the current - # build mode, which isn't what we want. - # Let component_targets know this target is available in the current mode - #self.SetTargetProperty(solution_name, TARGET_PATH=out_nodes[0]) - - return out_nodes - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add pseudo-builders to set up the project and solution builders. These - # need to be available on all platforms so that SConscripts which reference - # them will work. - env.AddMethod(ComponentVSDirProject) - env.AddMethod(ComponentVSProject) - env.AddMethod(ComponentVSSolution) - env.AddMethod(ComponentVSSourceProject) - - # If not on Windows, don't do anything else - if sys.platform not in ('win32', 'cygwin'): - return - - # Include tools we need - env.Tool('gather_inputs') - - env.SetDefault( - COMPONENT_VS_PROJECT_DIR='$COMPONENT_VS_SOLUTION_DIR/projects', - COMPONENT_VS_PROJECT_SCRIPT_NAME = 'hammer.bat', - COMPONENT_VS_PROJECT_SCRIPT_PATH = ( - '$$(ProjectDir)/$VS_PROJECT_TO_MAIN_DIR/' - '$COMPONENT_VS_PROJECT_SCRIPT_NAME'), - COMPONENT_VS_PROJECT_SUFFIX='.vcproj', - - COMPONENT_VS_SOLUTION_DIR='$DESTINATION_ROOT/solution', - COMPONENT_VS_SOLUTION_SUFFIX='.sln', - COMPONENT_VS_ENABLED_PROJECTS=['$COMPONENT_VS_SCONS_DEFAULT_TARGETS'], - - COMPONENT_VS_SOURCE_SUFFIXES=['$CPPSUFFIXES', '.rc', '.scons'], - COMPONENT_VS_SOURCE_FOLDERS=[('source', '$MAIN_DIR')], - ) - - AddTargetGroup('all_solutions', 'solutions can be built') - - # Add builders - vcprojaction = SCons.Script.Action(ComponentVSProjectBuilder, varlist=[ - 'COMPONENT_VS_PROJECT_SCRIPT_PATH', - 'TARGET_NAME', - 'TARGET_PATH', - ]) - vcprojbuilder = SCons.Script.Builder( - action=vcprojaction, - suffix='$COMPONENT_VS_PROJECT_SUFFIX') - - source_vcproj_action = SCons.Script.Action( - ComponentVSSourceProjectBuilder, varlist=[ - 'COMPONENT_VS_SOURCE_FOLDERS', - 'COMPONENT_VS_SOURCE_SUFFIXES', - 'COMPONENT_VS_SOURCE_TARGETS', - ]) - source_vcproj_builder = SCons.Script.Builder( - action=source_vcproj_action, - suffix='$COMPONENT_VS_PROJECT_SUFFIX') - - dir_vcproj_action = SCons.Script.Action( - ComponentVSDirProjectBuilder, varlist=[ - 'COMPONENT_VS_SOURCE_FOLDERS', - 'COMPONENT_VS_SOURCE_SUFFIXES', - 'PROJECT_SOURCES', - ]) - dir_vcproj_builder = SCons.Script.Builder( - action=dir_vcproj_action, - suffix='$COMPONENT_VS_PROJECT_SUFFIX') - - slnaction = SCons.Script.Action(ComponentVSSolutionBuilder, varlist=[ - 'COMPONENT_VS_ENABLED_PROJECTS', - 'SOLUTION_FOLDERS', - 'SOLUTION_PROJECTS', - 'SOLUTION_TARGETS', - ]) - slnbuilder = SCons.Script.Builder( - action=slnaction, - suffix='$COMPONENT_VS_SOLUTION_SUFFIX') - - env.Append(BUILDERS={ - 'ComponentVSDirProjectBuilder': dir_vcproj_builder, - 'ComponentVSProjectBuilder': vcprojbuilder, - 'ComponentVSSolutionBuilder': slnbuilder, - 'ComponentVSSourceProjectBuilder': source_vcproj_builder, - }) diff --git a/site_scons/site_tools/component_targets_xml.py b/site_scons/site_tools/component_targets_xml.py deleted file mode 100755 index 9162d97..0000000 --- a/site_scons/site_tools/component_targets_xml.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""XML output of component targets for SCons.""" - - -import xml.dom -import SCons.Script - - -def TargetXMLHelp(target, source, env): - """Generates target information in XML format. - - Args: - target: Destination file. - source: List of sources. Should be empty, otherwise this will actually - require the sources to be built first. - env: Environment context. - """ - env = env - source = source # Silence gpylint - - target_path = target[0].abspath - - xml_impl = xml.dom.getDOMImplementation() - doc = xml_impl.createDocument(None, 'help', None) - - mode_list = doc.createElement('mode_list') - doc.documentElement.appendChild(mode_list) - for mode in GetTargetModes().values(): - n = doc.createElement('build_mode') - n.setAttribute('name', mode.name) - n.setAttribute('description', mode.description) - mode_list.appendChild(n) - - group_list = doc.createElement('target_groups') - doc.documentElement.appendChild(group_list) - for group in GetTargetGroups().values(): - items = group.GetTargetNames() - if not items: - continue - - ngroup = doc.createElement('target_group') - ngroup.setAttribute('name', group.name) - group_list.appendChild(ngroup) - - for i in items: - ntarget = doc.createElement('build_target') - ntarget.setAttribute('name', i) - ngroup.appendChild(ntarget) - - # Get properties for target, if any - target = GetTargets().get(i) - if target: - # All modes - for k, v in target.properties.items(): - n = doc.createElement('target_property') - n.setAttribute('name', k) - n.setAttribute('value', v) - ntarget.appendChild(n) - - # Mode-specific - for mode, mode_properties in target.mode_properties.items(): - nmode = doc.createElement('target_mode') - nmode.setAttribute('name', mode) - ntarget.appendChild(nmode) - - for k, v in mode_properties.items(): - n = doc.createElement('target_property') - n.setAttribute('name', k) - n.setAttribute('value', v) - nmode.appendChild(n) - - f = open(target_path, 'wt') - doc.writexml(f, encoding='UTF-8', addindent=' ', newl='\n') - f.close() - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - env = env # Silence gpylint - - SCons.Script.Help('''\ - targets_xml Write information on the build mode's targets to - targets.xml. Most useful with --mode=all. -''') - - # Add build target to generate help - p = env.Command('$DESTINATION_ROOT/targets.xml', [], - env.Action(TargetXMLHelp)) - - # Always build xml info if requested. - # TODO(rspangler): Is there a better way to determine the xml info is up to - # date? - env.AlwaysBuild(p) - env.Alias('targets_xml', p) diff --git a/site_scons/site_tools/concat_source.py b/site_scons/site_tools/concat_source.py deleted file mode 100644 index 8d0fd89..0000000 --- a/site_scons/site_tools/concat_source.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Source concatenation builder for SCons.""" - - -import SCons.Script - - -def ConcatSourceBuilder(target, source, env): - """ConcatSource builder. - - Args: - target: List of target nodes - source: List of source nodes - env: Environment in which to build - - Returns: - None if successful; 1 if error. - """ - if len(target) != 1: - print 'ERROR: multiple ConcatSource targets when 1 expected' - return 1 - - output_lines = [ - '// This file is auto-generated by the ConcatSource builder.'] - - for source_path in map(str, source): - if env.get('CC') == 'cl': - # Add message pragma for nicer progress indication when building with - # MSVC. - output_lines.append('#pragma message("--%s")' % ( - source_path.replace("\\", "/"))) - - output_lines.append('#include "%s"' % source_path) - - output_file = open(str(target[0]), 'w') - # Need an EOL at the end of the file for more finicky build tools - output_file.write('\n'.join(output_lines) + '\n') - output_file.close() - - -def ConcatSourcePseudoBuilder(self, target, source): - """ConcatSource pseudo-builder; calls builder or passes through source nodes. - - Args: - self: Environment in which to build - target: List of target nodes - source: List of source nodes - - Returns: - If self['CONCAT_SOURCE_ENABLE'], calls self.ConcatSource and returns - the list of target nodes. Otherwise, returns the list of source nodes. - Source nodes which are not CPP files are passed through unchanged to the - list of output nodes. - """ - if self.get('CONCAT_SOURCE_ENABLE', True): - # Scan down source list and separate CPP sources (which we concatenate) - # from other files (which we pass through). - cppsource = [] - outputs = [] - suffixes = self.Flatten(self.subst_list('$CONCAT_SOURCE_SUFFIXES')) - for source_file in self.arg2nodes(source): - if source_file.suffix in suffixes: - cppsource.append(source_file) - else: - outputs.append(source_file) - - if len(cppsource) > 1: - # More than one file, so concatenate them together - outputs += self.ConcatSourceBuilder(target, cppsource) - else: - # <2 files, so pass them through; no need for a ConcatSource target - outputs += cppsource - return outputs - else: - # ConcatSource is disabled, so pass through the list of source nodes. - return source - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add the builder - action = SCons.Script.Action(ConcatSourceBuilder, '$CONCAT_SOURCE_COMSTR', - varlist = ['CONCAT_SOURCE_SUFFIXES']) - builder = SCons.Script.Builder(action = action, suffix = '$CXXFILESUFFIX') - env.Append(BUILDERS={'ConcatSourceBuilder': builder}) - - env.SetDefault( - CONCAT_SOURCE_COMSTR = 'Creating ConcatSource $TARGET from $SOURCES', - # Suffixes of sources we can concatenate. Files not in this list will be - # passed through untouched. (Note that on Mac, Objective C/C++ files - # cannot be concatenated with regular C/C++ files.) - # TODO(rspangler): Probably shouldn't mix C, C++ either... - CONCAT_SOURCE_SUFFIXES = ['.c', '.C', '.cxx', '.cpp', '.c++', '.cc', - '.h', '.H', '.hxx', '.hpp', '.hh'], - ) - - # Add a psuedo-builder method which can look at the environment to determine - # whether to call the ConcatSource builder or not - env.AddMethod(ConcatSourcePseudoBuilder, 'ConcatSource') diff --git a/site_scons/site_tools/defer.py b/site_scons/site_tools/defer.py deleted file mode 100644 index 3da09ea..0000000 --- a/site_scons/site_tools/defer.py +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Defer tool for SCons.""" - - -import os -import sys -import types -import SCons.Errors - - -# Current group name being executed by ExecuteDefer(). Set to None outside -# of ExecuteDefer(). -_execute_defer_context = None - - -class DeferGroup: - """Named list of functions to be deferred.""" - # If we derive DeferGroup from object, instances of it return type - # <class 'defer.DeferGroup'>, which prevents SCons.Util.semi_deepcopy() - # from calling its __semi_deepcopy__ function. - # TODO(sgk): Make semi_deepcopy() capable of handling classes derived from - # object. - - def __init__(self): - """Initialize deferred function object.""" - self.func_env_cwd = [] - self.after = set() - - def __semi_deepcopy__(self): - """Makes a semi-deep-copy of this object. - - Returns: - A semi-deep-copy of this object. - - This means it copies the sets and lists contained by this object, but - doesn't make copies of the function pointers and environments pointed to by - those lists. - - Needed so env.Clone() makes a copy of the defer list, so that functions - and after-relationships subsequently added to the clone are not added to - the parent. - """ - c = DeferGroup() - c.func_env_cwd = self.func_env_cwd[:] - c.after = self.after.copy() - return c - - -def SetDeferRoot(self): - """Sets the current environment as the root environment for defer. - - Args: - self: Current environment context. - - Functions deferred by environments cloned from the root environment (that is, - function deferred by children of the root environment) will be executed when - ExecuteDefer() is called from the root environment. - - Functions deferred by environments from which the root environment was cloned - (that is, functions deferred by parents of the root environment) will be - passed the root environment instead of the original parent environment. - (Otherwise, they would have no way to determine the root environment.) - """ - # Set the current environment as the root for holding defer groups - self['_DEFER_ROOT_ENV'] = self - - # Deferred functions this environment got from its parents will be run in the - # new root context. - for group in GetDeferGroups(self).values(): - new_list = [(func, self, cwd) for (func, env, cwd) in group.func_env_cwd] - group.func_env_cwd = new_list - - -def GetDeferRoot(self): - """Returns the root environment for defer. - - Args: - self: Current environment context. - - Returns: - The root environment for defer. If one of this environment's parents - called SetDeferRoot(), returns that environment. Otherwise returns the - current environment. - """ - return self.get('_DEFER_ROOT_ENV', self) - - -def GetDeferGroups(env): - """Returns the dict of defer groups from the root defer environment. - - Args: - env: Environment context. - - Returns: - The dict of defer groups from the root defer environment. - """ - return env.GetDeferRoot()['_DEFER_GROUPS'] - - -def ExecuteDefer(self): - """Executes deferred functions. - - Args: - self: Current environment context. - """ - # Check for re-entrancy - global _execute_defer_context - if _execute_defer_context: - raise SCons.Errors.UserError('Re-entrant call to ExecuteDefer().') - - # Save directory, so SConscript functions can occur in the right subdirs - oldcwd = os.getcwd() - - # If defer root is set and isn't this environment, we're being called from a - # sub-environment. That's not where we should be called. - if self.GetDeferRoot() != self: - print ('Warning: Ignoring call to ExecuteDefer() from child of the ' - 'environment passed to SetDeferRoot().') - return - - # Get list of defer groups from ourselves. - defer_groups = GetDeferGroups(self) - - # Loop through deferred functions - try: - while defer_groups: - did_work = False - for name, group in defer_groups.items(): - if group.after.intersection(defer_groups.keys()): - continue # Still have dependencies - - # Set defer context - _execute_defer_context = name - - # Remove this group from the list of defer groups now, in case one of - # the functions it calls adds back a function into that defer group. - del defer_groups[name] - - if group.func_env_cwd: - # Run all the functions in our named group - for func, env, cwd in group.func_env_cwd: - os.chdir(cwd) - func(env) - - # The defer groups have been altered, so restart the search for - # functions that can be executed. - did_work = True - break - - if not did_work: - errmsg = 'Error in ExecuteDefer: dependency cycle detected.\n' - for name, group in defer_groups.items(): - errmsg += ' %s after: %s\n' % (name, group.after) - raise SCons.Errors.UserError(errmsg) - finally: - # No longer in a defer context - _execute_defer_context = None - - # Restore directory - os.chdir(oldcwd) - - -def PrintDefer(self, print_functions=True): - """Prints the current defer dependency graph. - - Args: - self: Environment in which PrintDefer() was called. - print_functions: Print individual functions in defer groups. - """ - # Get the defer dict - # Get list of defer groups from ourselves. - defer_groups = GetDeferGroups(self) - dgkeys = defer_groups.keys() - dgkeys.sort() - for k in dgkeys: - print ' +- %s' % k - group = defer_groups[k] - after = list(group.after) - if after: - print ' | after' - after.sort() - for a in after: - print ' | +- %s' % a - if print_functions and group.func_env_cwd: - print ' functions' - for func, env, cwd in group.func_env_cwd: - print ' | +- %s %s' % (func.__name__, cwd) - - -def Defer(self, *args, **kwargs): - """Adds a deferred function or modifies defer dependencies. - - Args: - self: Environment in which Defer() was called - args: Positional arguments - kwargs: Named arguments - - The deferred function will be passed the environment used to call Defer(), - and will be executed in the same working directory as the calling SConscript. - (Exception: if this environment is cloned and the clone calls SetDeferRoot() - and then ExecuteDefer(), the function will be passed the root environment, - instead of the environment used to call Defer().) - - All deferred functions run after all SConscripts. Additional dependencies - may be specified with the after= keyword. - - Usage: - - env.Defer(func) - # Defer func() until after all SConscripts - - env.Defer(func, after=otherfunc) - # Defer func() until otherfunc() runs - - env.Defer(func, 'bob') - # Defer func() until after SConscripts, put in group 'bob' - - env.Defer(func2, after='bob') - # Defer func2() until after all funcs in 'bob' group have run - - env.Defer(func3, 'sam') - # Defer func3() until after SConscripts, put in group 'sam' - - env.Defer('bob', after='sam') - # Defer all functions in group 'bob' until after all functions in group - # 'sam' have run. - - env.Defer(func4, after=['bob', 'sam']) - # Defer func4() until after all functions in groups 'bob' and 'sam' have - # run. - """ - # Get name of group to defer and/or the a function - name = None - func = None - for a in args: - if isinstance(a, str): - name = a - elif isinstance(a, types.FunctionType): - func = a - if func and not name: - name = func.__name__ - - # TODO(rspangler): Why not allow multiple functions? Should be ok - - # Get list of names and/or functions this function should defer until after - after = [] - for a in self.Flatten(kwargs.get('after')): - if isinstance(a, str): - # TODO(rspangler): Should check if '$' in a, and if so, subst() it and - # recurse into it. - after.append(a) - elif isinstance(a, types.FunctionType): - after.append(a.__name__) - elif a is not None: - # Deferring - raise ValueError('Defer after=%r is not a function or name' % a) - - # Find the deferred function - defer_groups = GetDeferGroups(self) - if name not in defer_groups: - defer_groups[name] = DeferGroup() - group = defer_groups[name] - - # If we were given a function, also save environment and current directory - if func: - group.func_env_cwd.append((func, self, os.getcwd())) - - # Add dependencies for the function - group.after.update(after) - - # If we are already inside a call to ExecuteDefer(), any functions which are - # deferring until after the current function must also be deferred until - # after this new function. In short, this means that if b() defers until - # after a() and a() calls Defer() to defer c(), then b() must also defer - # until after c(). - if _execute_defer_context and name != _execute_defer_context: - for other_name, other_group in GetDeferGroups(self).items(): - if other_name == name: - continue # Don't defer after ourselves - if _execute_defer_context in other_group.after: - other_group.after.add(name) - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - env.Append(_DEFER_GROUPS={}) - - env.AddMethod(Defer) - env.AddMethod(ExecuteDefer) - env.AddMethod(GetDeferRoot) - env.AddMethod(PrintDefer) - env.AddMethod(SetDeferRoot) diff --git a/site_scons/site_tools/directx_9_0_c.py b/site_scons/site_tools/directx_9_0_c.py deleted file mode 100644 index a8f45bb..0000000 --- a/site_scons/site_tools/directx_9_0_c.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Windows DirectX 9.0c tool for SCons.""" - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - env['DIRECTX9_DIR'] = '$DIRECTX9_0_C_DIR' - env.Append( - LIBPATH=['$DIRECTX9_DIR/lib'], - CCFLAGS=['/I$DIRECTX9_DIR/include'], - ) - - -def exists(env): - """Returns true if tool exists.""" - # NOTE: SCons requires the use of this name, which fails gpylint. - - # If directory explicitly specified, we exist - if env.get('DIRECTX9_0_C_DIR'): - return 1 - else: - # TODO(rspangler): Don't know how to find it otherwise! - return 0 diff --git a/site_scons/site_tools/directx_9_18_944_0_partial.py b/site_scons/site_tools/directx_9_18_944_0_partial.py deleted file mode 100644 index f520a71..0000000 --- a/site_scons/site_tools/directx_9_18_944_0_partial.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Windows DirectX 9.18.944.0 tool for SCons.""" - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - env['DIRECTX9_DIR'] = '$DIRECTX9_18_944_0_PARTIAL_DIR' - env.AppendENVPath('INCLUDE', env.Dir('$DIRECTX9_DIR/include').abspath) - env.AppendENVPath('LIB', env.Dir('$DIRECTX9_DIR/lib/x86').abspath) - - -def exists(env): - """Returns true if tool exists.""" - # NOTE: SCons requires the use of this name, which fails gpylint. - - # If directory explicitly specified, we exist - if env.get('DIRECTX9_18_944_0_PARTIAL_DIR'): - return 1 - else: - # TODO(rspangler): Don't know how to find it otherwise! - return 0 diff --git a/site_scons/site_tools/distcc.py b/site_scons/site_tools/distcc.py deleted file mode 100644 index 6f4b9fc..0000000 --- a/site_scons/site_tools/distcc.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Distcc support for SCons. - -Since this modifies the C compiler strings, it must be specified after the -compiler tool in the tool list. - -Distcc support can be enabled by specifying --distcc on the SCons command -line. -""" - - -import optparse -import os -import sys -from SCons.compat._scons_optparse import OptionConflictError -import SCons.Script - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - if not env.Detect('distcc'): - return - - try: - SCons.Script.AddOption( - '--distcc', - dest='distcc', - action='store_true', - help='enable distcc support') - SCons.Script.Help(' --distcc Enable distcc suport.\n') - - except (OptionConflictError, optparse.OptionConflictError): - # The distcc tool can be specified for multiple platforms, but the - # --distcc option can only be added once. Ignore the error which - # results from trying to add it a second time. - pass - - # If distcc isn't enabled, stop now - if not env.GetOption('distcc'): - return - - # Copy DISTCC_HOSTS and HOME environment variables from system environment - for envvar in ('DISTCC_HOSTS', 'HOME'): - value = env.get(envvar, os.environ.get(envvar)) - if not value: - print 'Warning: %s not set in environment; disabling distcc.' % envvar - return - env['ENV'][envvar] = value - - # Set name of distcc tool - env['DISTCC'] = 'distcc' - - # Modify compilers we support - distcc_compilers = env.get('DISTCC_COMPILERS', ['cc', 'gcc', 'c++', 'g++']) - for compiler_var in ('CC', 'CXX'): - compiler = env.get(compiler_var) - if compiler in distcc_compilers: - if sys.platform == 'darwin': - # On Mac, distcc requires the full path to the compiler - compiler = env.WhereIs(compiler) - env[compiler_var] = '$DISTCC ' + compiler - - -def exists(env): - """Returns true if tool exists.""" - # NOTE: SCons requires the use of this name, which fails gpylint. - return env.Detect('distcc') diff --git a/site_scons/site_tools/environment_tools.py b/site_scons/site_tools/environment_tools.py deleted file mode 100644 index 7672ca1..0000000 --- a/site_scons/site_tools/environment_tools.py +++ /dev/null @@ -1,284 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Set up tools for environments for for software construction toolkit. - -This module is a SCons tool which should be include in all environments. It -will automatically be included by the component_setup tool. -""" - - -import os -import SCons - - -#------------------------------------------------------------------------------ - - -def FilterOut(self, **kw): - """Removes values from existing construction variables in an Environment. - - The values to remove should be a list. For example: - - self.FilterOut(CPPDEFINES=['REMOVE_ME', 'ME_TOO']) - - Args: - self: Environment to alter. - kw: (Any other named arguments are values to remove). - """ - - kw = SCons.Environment.copy_non_reserved_keywords(kw) - for key, val in kw.items(): - envval = self.get(key, None) - if envval is None: - # No existing variable in the environment, so nothing to delete. - continue - - for vremove in val: - # Use while not if, so we can handle duplicates. - while vremove in envval: - envval.remove(vremove) - - self[key] = envval - - # TODO(sgk): SCons.Environment.Append() has much more logic to deal - # with various types of values. We should handle all those cases in here - # too. (If variable is a dict, etc.) - -#------------------------------------------------------------------------------ - - -def Overlap(self, values1, values2): - """Checks for overlap between the values. - - Args: - self: Environment to use for variable substitution. - values1: First value(s) to compare. May be a string or list of strings. - values2: Second value(s) to compare. May be a string or list of strings. - - Returns: - The list of values in common after substitution, or an empty list if - the values do not overlap. - - Converts the values to a set of plain strings via self.SubstList2() before - comparison, so SCons $ variables are evaluated. - """ - set1 = set(self.SubstList2(values1)) - set2 = set(self.SubstList2(values2)) - return list(set1.intersection(set2)) - -#------------------------------------------------------------------------------ - - -def ApplySConscript(self, sconscript_file): - """Applies a SConscript to the current environment. - - Args: - self: Environment to modify. - sconscript_file: Name of SConscript file to apply. - - Returns: - The return value from the call to SConscript(). - - ApplySConscript() should be used when an existing SConscript which sets up an - environment gets too large, or when there is common setup between multiple - environments which can't be reduced into a parent environment which the - multiple child environments Clone() from. The latter case is necessary - because env.Clone() only enables single inheritance for environments. - - ApplySConscript() is NOT intended to replace the Tool() method. If you need - to add methods or builders to one or more environments, do that as a tool - (and write unit tests for them). - - ApplySConscript() is equivalent to the following SCons call: - SConscript(sconscript_file, exports={'env':self}) - - The called SConscript should import the 'env' variable to get access to the - calling environment: - Import('env') - - Changes made to env in the called SConscript will be applied to the - environment calling ApplySConscript() - that is, env in the called SConscript - is a reference to the calling environment. - - If you need to export multiple variables to the called SConscript, or return - variables from it, use the existing SConscript() function. - """ - return self.SConscript(sconscript_file, exports={'env': self}) - -#------------------------------------------------------------------------------ - - -def BuildSConscript(self, sconscript_file): - """Builds a SConscript based on the current environment. - - Args: - self: Environment to clone and pass to the called SConscript. - sconscript_file: Name of SConscript file to build. If this is a directory, - this method will look for sconscript_file+'/build.scons', and if that - is not found, sconscript_file+'/SConscript'. - - Returns: - The return value from the call to SConscript(). - - BuildSConscript() should be used when an existing SConscript which builds a - project gets too large, or when a group of SConscripts are logically related - but should not directly affect each others' environments (for example, a - library might want to build a number of unit tests which exist in - subdirectories, but not allow those tests' SConscripts to affect/pollute the - library's environment. - - BuildSConscript() is NOT intended to replace the Tool() method. If you need - to add methods or builders to one or more environments, do that as a tool - (and write unit tests for them). - - BuildSConscript() is equivalent to the following SCons call: - SConscript(sconscript_file, exports={'env':self.Clone()}) - or if sconscript_file is a directory: - SConscript(sconscript_file+'/build.scons', exports={'env':self.Clone()}) - - The called SConscript should import the 'env' variable to get access to the - calling environment: - Import('env') - - Changes made to env in the called SConscript will NOT be applied to the - environment calling BuildSConscript() - that is, env in the called SConscript - is a clone/copy of the calling environment, not a reference to that - environment. - - If you need to export multiple variables to the called SConscript, or return - variables from it, use the existing SConscript() function. - """ - # Need to look for the source node, since by default SCons will look for the - # entry in the variant_dir, which won't exist (and thus won't be a directory - # or a file). This isn't a problem in BuildComponents(), since the variant - # dir is only set inside its call to SConscript(). - if self.Entry(sconscript_file).srcnode().isdir(): - # Building a subdirectory, so look for build.scons or SConscript - script_file = sconscript_file + '/build.scons' - if not self.File(script_file).srcnode().exists(): - script_file = sconscript_file + '/SConscript' - else: - script_file = sconscript_file - - self.SConscript(script_file, exports={'env': self.Clone()}) - -#------------------------------------------------------------------------------ - - -def SubstList2(self, *args): - """Replacement subst_list designed for flags/parameters, not command lines. - - Args: - self: Environment context. - args: One or more strings or lists of strings. - - Returns: - A flattened, substituted list of strings. - - SCons's built-in subst_list evaluates (substitutes) variables in its - arguments, and returns a list of lists (one per positional argument). Since - it is designed for use in command line expansion, the list items are - SCons.Subst.CmdStringHolder instances. These instances can't be passed into - env.File() (or subsequent calls to env.subst(), either). The returned - nested lists also need to be flattened via env.Flatten() before the caller - can iterate over the contents. - - SubstList2() does a subst_list, flattens the result, then maps the flattened - list to strings. - - It is better to do: - for x in env.SubstList2('$MYPARAMS'): - than to do: - for x in env.get('MYPARAMS', []): - and definitely better than: - for x in env['MYPARAMS']: - which will throw an exception if MYPARAMS isn't defined. - """ - return map(str, self.Flatten(self.subst_list(args))) - - -#------------------------------------------------------------------------------ - - -def RelativePath(self, source, target, sep=os.sep, source_is_file=False): - """Calculates the relative path from source to target. - - Args: - self: Environment context. - source: Source path or node. - target: Target path or node. - sep: Path separator to use in returned relative path. - source_is_file: If true, calculates the relative path from the directory - containing the source, rather than the source itself. Note that if - source is a node, you can pass in source.dir instead, which is shorter. - - Returns: - The relative path from source to target. - """ - # Split source and target into list of directories - source = self.Entry(str(source)) - if source_is_file: - source = source.dir - source = source.abspath.split(os.sep) - target = self.Entry(str(target)).abspath.split(os.sep) - - # Handle source and target identical - if source == target: - if source_is_file: - return source[-1] # Bare filename - else: - return '.' # Directory pointing to itself - - # TODO(rspangler): Handle UNC paths and drive letters (fine if they're the - # same, but if they're different, there IS no relative path) - - # Remove common elements - while source and target and source[0] == target[0]: - source.pop(0) - target.pop(0) - # Join the remaining elements - return sep.join(['..'] * len(source) + target) - - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add methods to environment - env.AddMethod(ApplySConscript) - env.AddMethod(BuildSConscript) - env.AddMethod(FilterOut) - env.AddMethod(Overlap) - env.AddMethod(RelativePath) - env.AddMethod(SubstList2) diff --git a/site_scons/site_tools/gather_inputs.py b/site_scons/site_tools/gather_inputs.py deleted file mode 100644 index 6964bee..0000000 --- a/site_scons/site_tools/gather_inputs.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Input gathering tool for SCons.""" - - -import re -import SCons.Script - - -def GatherInputs(env, target, groups=['.*'], exclude_pattern=None): - """Find all (non-generated) input files used for a target. - - Args: - target: a target node to find source files for - For example: File('bob.exe') - groups: a list of patterns to use as categories - For example: ['.*\\.c$', '.*\\.h$'] - exclude_pattern: a pattern to exclude from the search - For example: '.*third_party.*' - Returns: - A list of lists of files for each category. - Each file will be placed in the first category which matches, - even if categories overlap. - For example: - [['bob.c', 'jim.c'], ['bob.h', 'jim.h']] - """ - - # Compile exclude pattern if any - if exclude_pattern: - exclude_pattern = re.compile(exclude_pattern) - - def _FindSources(ptrns, tgt, all): - """Internal Recursive function to find all pattern matches.""" - # Recursively process lists - if SCons.Util.is_List(tgt): - for t in tgt: - _FindSources(ptrns, t, all) - else: - # Get key to use for tracking whether we've seen this node - target_abspath = None - if hasattr(tgt, 'abspath'): - # Use target's absolute path as the key - target_abspath = tgt.abspath - target_key = target_abspath - else: - # Hope node's representation is unique enough (the default repr - # contains a pointer to the target as a string). This works for - # Alias() nodes. - target_key = repr(tgt) - - # Skip if we have been here before - if target_key in all: return - # Note that we have been here - all[target_key] = True - # Skip ones that match an exclude pattern, if we have one. - if (exclude_pattern and target_abspath - and exclude_pattern.match(target_abspath)): - return - - # Handle non-leaf nodes recursively - lst = tgt.children(scan=1) - if lst: - _FindSources(ptrns, lst, all) - return - - # Get real file (backed by repositories). - rfile = tgt.rfile() - rfile_is_file = rfile.isfile() - # See who it matches - for pattern, lst in ptrns.items(): - # Add files to the list for the first pattern that matches (implicitly, - # don't add directories). - if rfile_is_file and pattern.match(rfile.path): - lst.append(rfile.abspath) - break - - # Prepare a group for each pattern. - patterns = {} - for g in groups: - patterns[re.compile(g, re.IGNORECASE)] = [] - - # Do the search. - _FindSources(patterns, target, {}) - - return patterns.values() - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add a method to gather all inputs needed by a target. - env.AddMethod(GatherInputs, 'GatherInputs') diff --git a/site_scons/site_tools/publish.py b/site_scons/site_tools/publish.py deleted file mode 100644 index bf6a737..0000000 --- a/site_scons/site_tools/publish.py +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Publish tool for SCons.""" - - -# List of published resources. This is a dict indexed by group name. Each -# item in this dict is a dict indexed by resource type. Items in that dict -# are lists of files for that resource. -__published = {} - -#------------------------------------------------------------------------------ - - -class PublishItem(object): - """Item to be published.""" - - def __init__(self, source, subdir): - """Initialize object. - - Args: - source: Source node. - subdir: If not None, subdirectory to copy node into in - ReplicatePublished(). - """ - object.__init__(self) - self.source = source - self.subdir = subdir - -#------------------------------------------------------------------------------ - - -def _InitializePublish(env): - """Re-initializes published resources. - - Args: - env: Parent environment - """ - env=env # Silence gpylint - - # Clear the dict of published resources - __published.clear() - - -def ReplicatePublished(self, target, group_name, resource_type): - """Replicate published resources for the group to the target directory. - - Args: - self: Environment in which this function was called. - target: Target directory for resources. - group_name: Name of resource group, or a list of names of resource groups. - resource_type: Type of resources (string), or a list of resource types. - - Uses the subdir parameter passed to Publish() when replicating source nodes - to the target. - - Returns: - The list of target nodes from the calls to Replicate(). - - Since this is based on Replicate(), it will also use the REPLICATE_REPLACE - variable, if it's set in the calling environment. - """ - target_path = self.Dir(target).abspath - - dest_nodes = [] - for group in self.SubstList2(group_name): - for resource in self.SubstList2(resource_type): - # Get items for publish group and resource type - items = __published.get(group, {}).get(resource, []) - for i in items: - if i.subdir: - dest_nodes += self.Replicate(target_path + '/' + i.subdir, i.source) - else: - dest_nodes += self.Replicate(target_path, i.source) - return dest_nodes - - -def GetPublished(self, group_name, resource_type): - """Returns a list of the published resources of the specified type. - - Args: - self: Environment in which this function was called. - group_name: Name of resource group, or a list of names of resource groups. - resource_type: Type of resources (string), or a list of resource types. - - Returns: - A flattened list of the source nodes from calls to Publish() for the - specified group and resource type. Returns an empty list if there are - no matching resources. - """ - source_list = [] - for group in self.SubstList2(group_name): - # Get items for publish group and resource type - for resource in self.SubstList2(resource_type): - items = __published.get(group, {}).get(resource, []) - for i in items: - source_list.append(i.source) - - return source_list - - -def Publish(self, group_name, resource_type, source, subdir=None): - """Publishes resources for use by other scripts. - - Args: - self: Environment in which this function was called. - group_name: Name of resource group. - resource_type: Type of resources (string). - source: Source file(s) to copy. May be a string, Node, or a list of - mixed strings or Nodes. Strings will be passed through env.Glob() to - evaluate wildcards. If a source evaluates to a directory, the entire - directory will be recursively copied. - subdir: Subdirectory to which the resources should be copied, relative to - the primary directory for that resource type, if not None. - """ - if subdir is None: - subdir = '' # Make string so we can append to it - - # Evaluate SCons variables in group name - # TODO(rspangler): Should Publish() be able to take a list of group names - # and publish the resource to all of them? - group_name = self.subst(group_name) - - # Get list of sources - items = [] - for source_entry in self.Flatten(source): - if isinstance(source_entry, str): - # Search for matches for each source entry - # TODO(rspangler): If there are no wildcard chars in the source entry, - # should generate an error if there were no matches? - source_nodes = self.Glob(source_entry) - else: - # Source entry is already a file or directory node; no need to glob it - source_nodes = [source_entry] - for s in source_nodes: - if str(s.__class__) == 'SCons.Node.FS.Dir': - # Recursively publish all files in subdirectory. Since glob('*') - # doesn't match dot files, also glob('.*'). - self.Publish(group_name, resource_type, - [s.abspath + '/*', s.abspath + '/.*'], - subdir=subdir + '/' + s.name) - else: - items.append(PublishItem(s, subdir)) - - # Publish items, if any - if items: - # Get publish group - if group_name not in __published: - __published[group_name] = {} - group = __published[group_name] - if resource_type not in group: - group[resource_type] = [] - - # Publish items into group - group[resource_type] += items - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Defer initializing publish, but do before building SConscripts - env.Defer(_InitializePublish) - env.Defer('BuildEnvironmentSConscripts', after=_InitializePublish) - - env.AddMethod(GetPublished) - env.AddMethod(Publish) - env.AddMethod(ReplicatePublished) diff --git a/site_scons/site_tools/replace_strings.py b/site_scons/site_tools/replace_strings.py deleted file mode 100644 index 1c92772..0000000 --- a/site_scons/site_tools/replace_strings.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Search and replace builder for SCons.""" - - -import re -import SCons.Script - - -def ReplaceStrings(target, source, env): - """Replace Strings builder, does regex substitution on files. - - Args: - target: A single target file node. - source: A single input file node. - env: Environment in which to build. - - From env: - REPLACE_STRINGS: A list of pairs of regex search and replacement strings. - The body of the source file has substitution performed on each - pair (search_regex, replacement) in order. SCons variables in the - replacement strings will be evaluated. - - Returns: - The target node, a file with contents from source, with the substitutions - from REPLACE_STRINGS performed on it. - - For example: - env.ReplaceStrings('out', 'in', - REPLACE_STRINGS = [('a*', 'b'), ('b', 'CCC')]) - With 'in' having contents: Haaapy. - Outputs: HCCCpy. - """ - # Load text. - fh = open(source[0].abspath, 'rb') - text = fh.read() - fh.close() - # Do replacements. - for r in env['REPLACE_STRINGS']: - text = re.sub(r[0], env.subst(r[1]), text) - # Write it out. - fh = open(target[0].abspath, 'wb') - fh.write(text) - fh.close() - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add the builder - act = SCons.Script.Action(ReplaceStrings, varlist=['REPLACE_STRINGS']) - bld = SCons.Script.Builder(action=act, single_source=True) - env.Append(BUILDERS={'ReplaceStrings': bld}) diff --git a/site_scons/site_tools/replicate.py b/site_scons/site_tools/replicate.py deleted file mode 100644 index e64ec36..0000000 --- a/site_scons/site_tools/replicate.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Replicate tool for SCons.""" - - -import re - - -def Replicate(env, target, source, **kw): - """Replicates (copies) source files/directories to the target directory. - - Much like env.Install(), with the following differences: - * If the source is a directory, recurses through it and calls - env.Install() on each source file, rather than copying the entire - directory at once. This provides more opportunity for hard linking, and - also makes the destination files/directories all writable. - * Can take sources which contain env.Glob()-style wildcards. - * Can take multiple target directories; will copy to all of them. - * Handles duplicate requests. - - Args: - env: Environment in which to operate. - target: Destination(s) for copy. Must evaluate to a directory via - env.Dir(), or a list of directories. If more than one directory is - passed, the entire source list will be copied to each target - directory. - source: Source file(s) to copy. May be a string, Node, or a list of - mixed strings or Nodes. Strings will be passed through env.Glob() to - evaluate wildcards. If a source evaluates to a directory, the entire - directory will be recursively copied. - - From env: - REPLICATE_REPLACE: A list of pairs of regex search and replacement strings. - Each full destination path has substitution performed on each pair - (search_regex, replacement) in order. - - env.Replicate('destdir', ['footxt.txt'], REPLICATE_REPLACE = [ - ('\\.txt', '.bar'), ('est', 'ist')]) - will copy to 'distdir/footxt.bar' - - In the example above, note the use of \\ to escape the '.' character, - so that it doesn't act like the regexp '.' and match any character. - - Returns: - A list of the destination nodes from the calls to env.Install(). - """ - replace_list = kw.get('REPLICATE_REPLACE', env.get('REPLICATE_REPLACE', [])) - - dest_nodes = [] - for target_entry in env.Flatten(target): - for source_entry in env.Flatten(source): - if type(source_entry) == str: - # Search for matches for each source entry - source_nodes = env.Glob(source_entry) - else: - # Source entry is already a file or directory node; no need to glob it - source_nodes = [source_entry] - for s in source_nodes: - target_name = env.Dir(target_entry).abspath + '/' + s.name - # We need to use the following incantation rather than s.isdir() in - # order to handle chained replicates (A -> B -> C). The isdir() - # function is not properly defined in all of the Node type classes in - # SCons. This change is particularly crucial if hardlinks are present, - # in which case using isdir() can cause files to be unintentionally - # deleted. - # TODO(bradnelson): Look into fixing the innards of SCons so this isn't - # needed. - if str(s.__class__) == 'SCons.Node.FS.Dir': - # Recursively copy all files in subdir. Since glob('*') doesn't - # match dot files, also glob('.*'). - dest_nodes += env.Replicate( - target_name, [s.abspath + '/*', s.abspath + '/.*'], - REPLICATE_REPLACE=replace_list) - else: - # Apply replacement strings, if any - for r in replace_list: - target_name = re.sub(r[0], r[1], target_name) - target = env.File(target_name) - if (target.has_builder() - and hasattr(target.get_builder(), 'name') - and target.get_builder().name == 'InstallBuilder' - and target.sources == [s]): - # Already installed that file, so pass through the destination node - # TODO(rspangler): Is there a better way to determine if this is a - # duplicate install? - dest_nodes += [target] - else: - dest_nodes += env.InstallAs(target_name, s) - - # Return list of destination nodes - return dest_nodes - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - env.AddMethod(Replicate) diff --git a/site_scons/site_tools/sdl.py b/site_scons/site_tools/sdl.py deleted file mode 100755 index bc02ad7..0000000 --- a/site_scons/site_tools/sdl.py +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Simple DirectMedia Layer tool for SCons. - -This tool sets up an environment to use the SDL library. -""" - -import os -import sys -import SCons.Script - - -def _HermeticSDL(env): - """Set things up if sdl is hermetically setup somewhere.""" - - if sys.platform in ['win32', 'cygwin']: - env.SetDefault( - SDL_DIR='$SDL_HERMETIC_WINDOWS_DIR', - SDL_CPPPATH=['$SDL_DIR/include'], - SDL_LIBPATH=['$SDL_DIR/lib'], - SDL_LIBS=['SDL', 'SDLmain'], - SDL_FRAMEWORKPATH=[], - SDL_FRAMEWORKS=[], - ) - elif sys.platform in ['darwin']: - env.SetDefault( - SDL_DIR='$SDL_HERMETIC_MAC_DIR', - SDL_CPPPATH=[ - '$SDL_DIR/SDL.framework/Headers', - ], - SDL_LIBPATH=[], - SDL_LIBS=[], - SDL_FRAMEWORKPATH=['$SDL_DIR'], - SDL_FRAMEWORKS=['SDL', 'Cocoa'], - ) - elif sys.platform in ['linux', 'linux2', 'posix']: - env.SetDefault( - SDL_DIR='$SDL_HERMETIC_LINUX_DIR', - SDL_CPPPATH='$SDL_DIR/include', - SDL_LIBPATH='$SDL_DIR/lib', - SDL_LIBS=['SDL', 'SDLmain'], - SDL_FRAMEWORKPATH=[], - SDL_FRAMEWORKS=[], - ) - else: - env.SetDefault( - SDL_VALIDATE_PATHS=[ - ('unsupported_platform', - ('Not supported on this platform.')), - ], - SDL_IS_MISSING=True, - ) - - if not env.get('SDL_IS_MISSING', False): - env.SetDefault( - SDL_VALIDATE_PATHS=[ - ('$SDL_DIR', - ('You are missing a hermetic copy of SDL...')), - ], - ) - - -def _LocalSDL(env): - """Set things up if sdl is locally installed.""" - - if sys.platform in ['win32', 'cygwin']: - env.SetDefault( - SDL_DIR='c:/SDL-1.2.13', - SDL_CPPPATH='$SDL_DIR/include', - SDL_LIBPATH='$SDL_DIR/lib', - SDL_LIBS=['SDL', 'SDLmain'], - SDL_FRAMEWORKPATH=[], - SDL_FRAMEWORKS=[], - SDL_VALIDATE_PATHS=[ - ('$SDL_DIR', - ('You are missing SDL-1.2.13 on your system.', - 'It was supposed to be in: ${SDL_DIR}', - 'You can download it from:', - ' http://www.libsdl.org/download-1.2.php')), - ], - ) - elif sys.platform in ['darwin']: - env.SetDefault( - SDL_CPPPATH=['/Library/Frameworks/SDL.framework/Headers'], - SDL_LIBPATH=[], - SDL_LIBS=[], - SDL_FRAMEWORKPATH=[], - SDL_FRAMEWORKS=['SDL', 'Cocoa'], - SDL_VALIDATE_PATHS=[ - ('/Library/Frameworks/SDL.framework/SDL', - ('You are missing the SDL framework on your system.', - 'You can download it from:', - 'http://www.libsdl.org/download-1.2.php')), - ], - ) - elif sys.platform in ['linux', 'linux2', 'posix']: - env.SetDefault( - SDL_CPPPATH='/usr/include/SDL', - SDL_LIBPATH='/usr/lib', - SDL_LIBS=['SDL', 'SDLmain'], - SDL_FRAMEWORKPATH=[], - SDL_FRAMEWORKS=[], - SDL_VALIDATE_PATHS=[ - ('/usr/lib/libSDL.so', - ('You are missing SDL on your system.', - 'Run sudo apt-get install libsdl1.2-dev.')), - ], - ) - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Allow the hermetic copy to be disabled on the command line. - sdl_mode = SCons.Script.ARGUMENTS.get('sdl', 'hermetic') - if sdl_mode == 'local': - _LocalSDL(env) - elif sdl_mode == 'hermetic': - _HermeticSDL(env) - elif sdl_mode == 'none': - return - else: - assert False - - validate_paths = env['SDL_VALIDATE_PATHS'] - - if not validate_paths: - sys.stderr.write('*' * 77 + '\n') - sys.stderr.write('ERROR - SDL not supported on this platform.\n') - sys.stderr.write('*' * 77 + '\n') - sys.exit(-1) - - for i in validate_paths: - if not os.path.exists(env.subst(i[0])): - sys.stderr.write('*' * 77 + '\n') - for j in i[1]: - sys.stderr.write(env.subst(j) + '\n') - sys.stderr.write('*' * 77 + '\n') - sys.exit(-1) - - env.Append( - CPPPATH=['$SDL_CPPPATH'], - LIBPATH=['$SDL_LIBPATH'], - LIBS=['$SDL_LIBS'], - FRAMEWORKPATH=['$SDL_FRAMEWORKPATH'], - FRAMEWORKS=['$SDL_FRAMEWORKS'], - ) diff --git a/site_scons/site_tools/seven_zip.py b/site_scons/site_tools/seven_zip.py deleted file mode 100644 index 94d807f..0000000 --- a/site_scons/site_tools/seven_zip.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -"""SCons tool for 7zip.""" - - -import os -import shutil -import subprocess -import tempfile -import SCons.Script - - -def SevenZipGetFiles(env, source): - """SCons emitter for 7zip extract. - - Examines the source 7z archive to determine the list of files which will be - created by extract/unzip operation. - Args: - env: The SCons environment to get the 7zip command line from. - source: The 7zip archive to examine. - Returns: - The list of filenames in the archive. - """ - # Expand the command to list archive contents. - cmd = env.subst('$SEVEN_ZIP l "%s"' % source) - # Run it and capture output. - output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0] - # Strip off 7-line header and 3-line trailer from 7zip output. - lines = output.split('\r\n')[7:-3] - # Trim out just the files and their names. - files = [i[53:] for i in lines if i[20] != 'D'] - return files - - -def SevenZipEmitter(target, source, env): - """An emitter that decides what nodes are vented from a 7zip archive. - - Args: - target: The target directory node. - source: The source archive node. - env: The environment in which the emit takes place. - Returns: - The pair (target, source) which lists the emitted targets and sources. - """ - # Remember out dir for later. - env['SEVEN_ZIP_OUT_DIR'] = target[0].dir - # Get out contents - files = SevenZipGetFiles(env, env.subst('$SOURCE', source=source)) - # Extract a layer deeper if there is only one, and it extension is 7z. - if env.get('SEVEN_ZIP_PEEL_LAYERS', False): - assert len(files) == 1 and os.path.splitext(files[0])[1] == '.7z' - # Create a temporary directory. - tmp_dir = tempfile.mkdtemp() - # Expand the command to extract the archive to a temporary location. - cmd = env.subst('$SEVEN_ZIP x $SOURCE -o"%s"' % tmp_dir, source=source[0]) - # Run it and swallow output. - subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate() - # Get contents. - inner_files = SevenZipGetFiles(env, os.path.join(tmp_dir, files[0])) - # Make into file nodes. - inner_files = [target[0].dir.File(i) for i in inner_files] - # Delete temp_dir. - shutil.rmtree(tmp_dir) - # Decide where to extra working file to. - working_file = env.Dir(target[0].dir.abspath + - '.7zip_extract').File(files[0]) - # Combine everything. - files = [working_file] + inner_files - else: - # Make into file nodes. - files = [target[0].dir.File(i) for i in files] - # Return files as actual target. - return (files, source) - - -def SevenZipGenerator(source, target, env, for_signature): - """The generator function which decides how to extract a file.""" - - # Silence lint. - source = source - target = target - for_signature = for_signature - - if env.get('SEVEN_ZIP_PEEL_LAYERS', False): - return [SCons.Script.Delete('$SEVEN_ZIP_OUT_DIR'), - '$SEVEN_ZIP x $SOURCE -o"${TARGET.dir}"', - '$SEVEN_ZIP x $TARGET -o"$SEVEN_ZIP_OUT_DIR"'] - else: - return [SCons.Script.Delete('$SEVEN_ZIP_OUT_DIR'), - '$SEVEN_ZIP x $SOURCE -o"$SEVEN_ZIP_OUT_DIR"'] - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - env.Replace( - SEVEN_ZIP='$SEVEN_ZIP_DIR/7za.exe', - SEVEN_ZIP_ARCHIVE_OPTIONS = ['-t7z', '-mx0'], - SEVEN_ZIP_COMPRESS_OPTIONS = ['-t7z', '-mx9'], - ) - - b = SCons.Script.Builder(generator=SevenZipGenerator, - emitter=SevenZipEmitter) - env['BUILDERS']['Extract7zip'] = b - - b = SCons.Script.Builder( - action=('cd $SOURCE && ' - '$SEVEN_ZIP a $SEVEN_ZIP_ARCHIVE_OPTIONS ${TARGET.abspath} ./')) - env['BUILDERS']['Archive7zip'] = b - - b = SCons.Script.Builder( - action=('cd ${SOURCE.dir} && ' - '$SEVEN_ZIP a $SEVEN_ZIP_COMPRESS_OPTIONS ' - '${TARGET.abspath} ${SOURCE.file}')) - env['BUILDERS']['Compress7zip'] = b diff --git a/site_scons/site_tools/target_debug.py b/site_scons/site_tools/target_debug.py deleted file mode 100644 index 4c7c0f1..0000000 --- a/site_scons/site_tools/target_debug.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Build tool setup for debug environments. - -This module is a SCons tool which setups environments for debugging. -It is used as follows: - debug_env = env.Clone(tools = ['target_debug']) -""" - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add in general settings. - DeclareBit('debug', 'Build is debug, not optimized.') - env.SetBits('debug') - - env['TARGET_DEBUG'] = True - - env.Append( - CPPDEFINES=['_DEBUG'] + env.get('CPPDEFINES_DEBUG', []), - CCFLAGS=env.get('CCFLAGS_DEBUG', []), - LINKFLAGS=env.get('LINKFLAGS_DEBUG', []), - ) diff --git a/site_scons/site_tools/target_optimized.py b/site_scons/site_tools/target_optimized.py deleted file mode 100644 index 10b819d..0000000 --- a/site_scons/site_tools/target_optimized.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Build tool setup for optimized environments. - -This module is a SCons tool which setups environments for optimized builds. -It is used as follows: - optimized_env = env.Clone(tools = ['target_optimized']) -""" - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add in general options. - env['TARGET_DEBUG'] = False - - env.Append( - CPPDEFINES=['NDEBUG'] + env.get('CPPDEFINES_OPTIMIZED', []), - CCFLAGS=env.get('CCFLAGS_OPTIMIZED', []), - LINKFLAGS=env.get('LINKFLAGS_OPTIMIZED', []), - ) diff --git a/site_scons/site_tools/target_platform_linux.py b/site_scons/site_tools/target_platform_linux.py deleted file mode 100644 index 83b37b0..0000000 --- a/site_scons/site_tools/target_platform_linux.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Build tool setup for Linux. - -This module is a SCons tool which should be include in the topmost windows -environment. -It is used as follows: - env = base_env.Clone(tools = ['component_setup']) - linux_env = base_env.Clone(tools = ['target_platform_linux']) -""" - - -def ComponentPlatformSetup(env, builder_name): - """Hook to allow platform to modify environment inside a component builder. - - Args: - env: Environment to modify - builder_name: Name of the builder - """ - if env.get('ENABLE_EXCEPTIONS'): - env.FilterOut(CCFLAGS=['-fno-exceptions']) - env.Append(CCFLAGS=['-fexceptions']) - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Use g++ - env.Tool('g++') - env.Tool('gcc') - env.Tool('gnulink') - env.Tool('ar') - env.Tool('as') - - # Declare bits - DeclareBit('linux', 'Target platform is linux.', - exclusive_groups=('target_platform')) - DeclareBit('posix', 'Target platform is posix.') - env.SetBits('linux', 'posix') - - env.Replace( - TARGET_PLATFORM='LINUX', - COMPONENT_PLATFORM_SETUP=ComponentPlatformSetup, - CCFLAG_INCLUDE='-include', # Command line option to include a header - - # Code coverage related. - COVERAGE_CCFLAGS=['-ftest-coverage', '-fprofile-arcs'], - COVERAGE_LIBS='gcov', - COVERAGE_STOP_CMD=[ - '$COVERAGE_MCOV --directory "$TARGET_ROOT" --output "$TARGET"', - ('$COVERAGE_GENHTML --output-directory $COVERAGE_HTML_DIR ' - '$COVERAGE_OUTPUT_FILE'), - ], - ) - - env.Append( - HOST_PLATFORMS=['LINUX'], - CPPDEFINES=['OS_LINUX=OS_LINUX'], - - # Settings for debug - CCFLAGS_DEBUG=[ - '-O0', # turn off optimizations - '-g', # turn on debugging info - ], - - # Settings for optimized - CCFLAGS_OPTIMIZED=['-O2'], - - # Settings for component_builders - COMPONENT_LIBRARY_LINK_SUFFIXES=['.so', '.a'], - COMPONENT_LIBRARY_DEBUG_SUFFIXES=[], - ) diff --git a/site_scons/site_tools/target_platform_mac.py b/site_scons/site_tools/target_platform_mac.py deleted file mode 100644 index 2d5e419..0000000 --- a/site_scons/site_tools/target_platform_mac.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Build tool setup for MacOS. - -This module is a SCons tool which should be include in the topmost mac -environment. -It is used as follows: - env = base_env.Clone(tools = ['component_setup']) - mac_env = base_env.Clone(tools = ['target_platform_mac']) -""" - - -import SCons.Script - - -def ComponentPlatformSetup(env, builder_name): - """Hook to allow platform to modify environment inside a component builder. - - Args: - env: Environment to modify - builder_name: Name of the builder - """ - if env.get('ENABLE_EXCEPTIONS'): - env.FilterOut(CCFLAGS=['-fno-exceptions']) - env.Append(CCFLAGS=['-fexceptions']) - -#------------------------------------------------------------------------------ - - -def BundlePseudoBuilder(env, target, **kwargs): - """MacOS Bundle PseudoBuilder. - - Args: - env: Environment in which to build - target: Name of the bundle to build - kwargs: Additional parameters to set in the environment - - Returns: - The target is returned. - """ - # Don't change the environment passed into the pseudo-builder - env = env.Clone() - - # Bring keywords args into the environment. - for k, v in kwargs.items(): - env[k] = v - # Make sure BUNDLE_RESOURCES is set and not empty; force it to be a list - bundle_resources = env.Flatten(env.get('BUNDLE_RESOURCES', [])) - if not bundle_resources: - raise ValueError('BUNDLE_RESOURCES must be set and non-empty') - - # Make each resource into a directory node. - # TODO(jrg): this seems a little too restrictive. - # bundle_resources = [env.Dir(i) for i in bundle_resources] - bundle_resources = [i for i in bundle_resources] - - # Create a PkgInfo file only if BUNDLE_PKGINFO_FILENAME is useful. - # (NPAPI bundles are unhappy with PkgInfo files.) - # TODO(jrg): discuss method with Bradley - if env.get('BUNDLE_PKGINFO_FILENAME'): - pkginfo_create_command = ('$BUNDLE_GENERATE_PKGINFO ' - '>$TARGET/$BUNDLE_PKGINFO_FILENAME') - else: - pkginfo_create_command = '/bin/echo no PkgInfo will be created' # noop - - # Add the build step for the bundle. - p = env.Command(env.Dir(target), - [env.File('$BUNDLE_EXE'), - env.File('$BUNDLE_INFO_PLIST')] + - bundle_resources, - [SCons.Script.Delete('$TARGET'), - SCons.Script.Mkdir('$TARGET/Contents'), - SCons.Script.Mkdir('$TARGET/Contents/MacOS'), - SCons.Script.Mkdir('$TARGET/Contents/Resources'), - 'cp -f $SOURCE $TARGET/Contents/MacOS', - 'cp -f ${SOURCES[1]} $TARGET/Contents', - pkginfo_create_command, - 'cp -rf ${SOURCES[2:]} $TARGET/Contents/Resources']) - - # Add an alias for this target. - # This also allows the 'all_bundles' target to build me. - a = env.Alias(target, p) - for group in env['COMPONENT_BUNDLE_GROUPS']: - SCons.Script.Alias(group, a) - - return env.Dir(target) - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Use g++ - env.Tool('g++') - env.Tool('gcc') - env.Tool('gnulink') - env.Tool('ar') - env.Tool('as') - env.Tool('applelink') - - # Declare bits - DeclareBit('mac', 'Target platform is mac.', - exclusive_groups=('target_platform')) - DeclareBit('posix', 'Target platform is posix.') - env.SetBits('mac', 'posix') - - env.Replace( - TARGET_PLATFORM='MAC', - COMPONENT_PLATFORM_SETUP=ComponentPlatformSetup, - CCFLAG_INCLUDE='-include', # Command line option to include a header - - # Code coverage related. - COVERAGE_CCFLAGS=['-ftest-coverage', '-fprofile-arcs'], - COVERAGE_LIBS='gcov', - COVERAGE_STOP_CMD=[ - '$COVERAGE_MCOV --directory "$TARGET_ROOT" --output "$TARGET"', - ('$COVERAGE_GENHTML --output-directory $COVERAGE_HTML_DIR ' - '$COVERAGE_OUTPUT_FILE'), - ], - ) - - env.Append( - HOST_PLATFORMS=['MAC'], - CPPDEFINES=['OS_MACOSX=OS_MACOSX'], - - # Settings for debug - CCFLAGS_DEBUG=['-g'], - LINKFLAGS_DEBUG=['-g'], - - # Settings for optimized - CCFLAGS_OPTIMIZED=['-O2'], - - # Settings for component_builders - COMPONENT_LIBRARY_LINK_SUFFIXES=['.dylib', '.a'], - COMPONENT_LIBRARY_DEBUG_SUFFIXES=[], - - # New 'all' target. Helpful: "hammer -h" now lists it! - COMPONENT_BUNDLE_GROUPS=['all_bundles'], - ) - - - # Set default values used by the Bundle pseudobuilder. - env.Replace( - BUNDLE_TYPE='APPL', - BUNDLE_STRING='${BUNDLE_TYPE}????', - BUNDLE_GENERATE_PKGINFO='echo "${BUNDLE_STRING}"', - BUNDLE_PKGINFO_FILENAME='PkgInfo', - BUNDLE_INFO_PLIST='Info.plist', - ) - - # Add the Bundle pseudobuilder. - env.AddMethod(BundlePseudoBuilder, 'Bundle') - - # Add our target groups - AddTargetGroup('all_bundles', 'bundles can be built') diff --git a/site_scons/site_tools/target_platform_windows.py b/site_scons/site_tools/target_platform_windows.py deleted file mode 100644 index a0a70e8..0000000 --- a/site_scons/site_tools/target_platform_windows.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Build tool setup for Windows. - -This module is a SCons tool which should be include in the topmost windows -environment. -It is used as follows: - env = base_env.Clone(tools = ['component_setup']) - win_env = base_env.Clone(tools = ['target_platform_windows']) -""" - - -import os -import time -import command_output -import SCons.Script - - -def WaitForWritable(target, source, env): - """Waits for the target to become writable. - - Args: - target: List of target nodes. - source: List of source nodes. - env: Environment context. - - Returns: - Zero if success, nonzero if error. - - This is a necessary hack on Windows, where antivirus software can lock exe - files briefly after they're written. This can cause subsequent reads of the - file by env.Install() to fail. To prevent these failures, wait for the file - to be writable. - """ - target_path = target[0].abspath - if not os.path.exists(target_path): - return 0 # Nothing to wait for - - for retries in range(10): - try: - f = open(target_path, 'a+b') - f.close() - return 0 # Successfully opened file for write, so we're done - except (IOError, OSError): - print 'Waiting for access to %s...' % target_path - time.sleep(1) - - # If we're still here, fail - print 'Timeout waiting for access to %s.' % target_path - return 1 - - -def RunManifest(target, source, env, cmd): - """Run the Microsoft Visual Studio manifest tool (mt.exe). - - Args: - target: List of target nodes. - source: List of source nodes. - env: Environment context. - cmd: Command to run. - - Returns: - Zero if success, nonzero if error. - - The mt.exe tool seems to experience intermittent failures trying to write to - .exe or .dll files. Antivirus software makes this worse, but the problem - can still occur even if antivirus software is disabled. The failures look - like: - - mt.exe : general error c101008d: Failed to write the updated manifest to - the resource of file "(name of exe)". Access is denied. - - with mt.exe returning an errorlevel (return code) of 31. The workaround is - to retry running mt.exe after a short delay. - """ - cmdline = env.subst(cmd, target=target, source=source) - - for retry in range(5): - # If this is a retry, print a message and delay first - if retry: - # mt.exe failed to write to the target file. Print a warning message, - # delay 3 seconds, and retry. - print 'Warning: mt.exe failed to write to %s; retrying.' % target[0] - time.sleep(3) - - return_code, output = command_output.RunCommand( - cmdline, env=env['ENV'], echo_output=False) - if return_code != 31: # Something other than the intermittent error - break - - # Pass through output (if any) and return code from manifest - if output: - print output - return return_code - - -def RunManifestExe(target, source, env): - """Calls RunManifest for updating an executable (resource_num=1).""" - return RunManifest(target, source, env, cmd='$MANIFEST_COM') - - -def RunManifestDll(target, source, env): - """Calls RunManifest for updating a dll (resource_num=2).""" - return RunManifest(target, source, env, cmd='$SHMANIFEST_COM') - - -def ComponentPlatformSetup(env, builder_name): - """Hook to allow platform to modify environment inside a component builder. - - This is called on a clone of the environment passed into the component - builder, and is the last modification done to that environment before using - it to call the underlying SCons builder (env.Program(), env.Library(), etc.) - - Args: - env: Environment to modify - builder_name: Name of the builder - """ - if env.get('ENABLE_EXCEPTIONS'): - env.FilterOut( - CPPDEFINES=['_HAS_EXCEPTIONS=0'], - # There are problems with LTCG when some files are compiled with - # exceptions and some aren't (the v-tables for STL and BOOST classes - # don't match). Therefore, turn off LTCG when exceptions are enabled. - CCFLAGS=['/GL'], - LINKFLAGS=['/LTCG'], - ARFLAGS=['/LTCG'], - ) - env.Append(CCFLAGS=['/EHsc']) - - if builder_name in ('ComponentObject', 'ComponentLibrary'): - if env.get('COMPONENT_STATIC'): - env.Append(CPPDEFINES=['_LIB']) - else: - env.Append(CPPDEFINES=['_USRDLL', '_WINDLL']) - - if builder_name == 'ComponentTestProgram': - env.FilterOut( - CPPDEFINES=['_WINDOWS'], - LINKFLAGS=['/SUBSYSTEM:WINDOWS'], - ) - env.Append( - CPPDEFINES=['_CONSOLE'], - LINKFLAGS=['/SUBSYSTEM:CONSOLE'], - ) - - # Make sure link methods are lists, so we can append to them below - env['LINKCOM'] = [env['LINKCOM']] - env['SHLINKCOM'] = [env['SHLINKCOM']] - - # Support manifest file generation and consumption - if env.get('MANIFEST_FILE'): - env.Append( - LINKCOM=[SCons.Script.Action(RunManifestExe, '$MANIFEST_COMSTR')], - SHLINKCOM=[SCons.Script.Action(RunManifestDll, '$SHMANIFEST_COMSTR')], - ) - - # If manifest file should be autogenerated, add the -manifest link line and - # delete the generated manfest after running mt.exe. - if env.get('MANFEST_FILE_GENERATED_BY_LINK'): - env.Append( - LINKFLAGS=['-manifest'], - LINKCOM=[SCons.Script.Delete('$MANFEST_FILE_GENERATED_BY_LINK')], - SHLINKCOM=[SCons.Script.Delete('$MANFEST_FILE_GENERATED_BY_LINK')], - ) - - # Wait for the output file to be writable before releasing control to - # SCons. Windows virus scanners temporarily lock modified executable files - # for scanning, which causes SCons's env.Install() to fail intermittently. - env.Append( - LINKCOM=[SCons.Script.Action(WaitForWritable, None)], - SHLINKCOM=[SCons.Script.Action(WaitForWritable, None)], - ) - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Bring in the outside PATH, INCLUDE, and LIB if not blocked. - if not env.get('MSVC_BLOCK_ENVIRONMENT_CHANGES'): - env.AppendENVPath('PATH', os.environ.get('PATH', '[]')) - env.AppendENVPath('INCLUDE', os.environ.get('INCLUDE', '[]')) - env.AppendENVPath('LIB', os.environ.get('LIB', '[]')) - - # Load various Visual Studio related tools. - env.Tool('as') - env.Tool('msvs') - env.Tool('windows_hard_link') - - pre_msvc_env = env['ENV'].copy() - - env.Tool('msvc') - env.Tool('mslib') - env.Tool('mslink') - - # Find VC80_DIR if it isn't already set. - if not env.get('VC80_DIR'): - # Look in each directory in the path for cl.exe. - for p in env['ENV']['PATH'].split(os.pathsep): - # Use the directory two layers up if it exists. - if os.path.exists(os.path.join(p, 'cl.exe')): - env['VC80_DIR'] = os.path.dirname(os.path.dirname(p)) - - # The msvc, mslink, and mslib tools search the registry for installed copies - # of Visual Studio and prepends them to the PATH, INCLUDE, and LIB - # environment variables. Block these changes if necessary. - if env.get('MSVC_BLOCK_ENVIRONMENT_CHANGES'): - env['ENV'] = pre_msvc_env - - # Declare bits - DeclareBit('windows', 'Target platform is windows.', - exclusive_groups=('target_platform')) - env.SetBits('windows') - - env.Replace( - TARGET_PLATFORM='WINDOWS', - COMPONENT_PLATFORM_SETUP=ComponentPlatformSetup, - - # A better rebuild command (actually cleans, then rebuild) - MSVSREBUILDCOM=''.join(['$MSVSSCONSCOM -c "$MSVSBUILDTARGET" && ', - '$MSVSSCONSCOM "$MSVSBUILDTARGET"']), - ) - - env.SetDefault( - # Command line option to include a header - CCFLAG_INCLUDE='/FI', - - # Generate PDBs matching target name by default. - PDB='${TARGET.base}.pdb', - - # Code coverage related. - COVERAGE_LINKFLAGS='/PROFILE', # Requires vc_80 or higher. - COVERAGE_LINKCOM_EXTRAS='$COVERAGE_VSINSTR /COVERAGE $TARGET', - # NOTE: need to ignore error in return type here, the tool has issues. - # Thus a - is added. - COVERAGE_START_CMD=[ - # If a previous build was cancelled or crashed, VSPerfCmd may still - # be running, which causes future coverage runs to fail. Make sure - # it's shut down before starting coverage up again. - '-$COVERAGE_VSPERFCMD -shutdown', - '$COVERAGE_VSPERFCMD -start:coverage ' - '-output:${COVERAGE_OUTPUT_FILE}.pre'], - COVERAGE_STOP_CMD=[ - '-$COVERAGE_VSPERFCMD -shutdown', - '$COVERAGE_ANALYZER -sym_path=. ${COVERAGE_OUTPUT_FILE}.pre.coverage', - SCons.Script.Copy('$COVERAGE_OUTPUT_FILE', - '${COVERAGE_OUTPUT_FILE}.pre.coverage.lcov'), - ], - COVERAGE_EXTRA_PATHS=['$COVERAGE_ANALYZER_DIR'], - - # Manifest options - # When link.exe is run with '-manifest', it always generated a manifest - # with this name. - MANFEST_FILE_GENERATED_BY_LINK='${TARGET}.manifest', - # Manifest file to use as input to mt.exe. Can be overridden to pass in - # a pregenerated manifest file. - MANIFEST_FILE='$MANFEST_FILE_GENERATED_BY_LINK', - MANIFEST_COM=('mt.exe -nologo -manifest "$MANIFEST_FILE" ' - '-outputresource:"$TARGET";1'), - MANIFEST_COMSTR='$MANIFEST_COM', - SHMANIFEST_COM=('mt.exe -nologo -manifest "$MANIFEST_FILE" ' - '-outputresource:"$TARGET";2'), - SHMANIFEST_COMSTR='$SHMANIFEST_COM', - ) - - env.Append( - HOST_PLATFORMS=['WINDOWS'], - CPPDEFINES=['OS_WINDOWS=OS_WINDOWS'], - - # Turn up the warning level - CCFLAGS=['/W3'], - - # Force x86 platform, generate manifests - LINKFLAGS=['/MACHINE:X86'], - ARFLAGS=['/MACHINE:X86'], - - # Settings for debug - CCFLAGS_DEBUG=[ - '/Od', # disable optimizations - '/RTC1', # enable fast checks - '/MTd', # link with LIBCMTD.LIB debug lib - ], - LINKFLAGS_DEBUG=['/DEBUG'], - - # Settings for optimized - CCFLAGS_OPTIMIZED=[ - '/O1', # optimize for size - '/MT', # link with LIBCMT.LIB (multi-threaded, static linked crt) - '/GS', # enable security checks - ], - LINKFLAGS_OPTIMIZED=['/PDBPATH:none'], - - # Settings for component_builders - COMPONENT_LIBRARY_LINK_SUFFIXES=['.lib'], - COMPONENT_LIBRARY_DEBUG_SUFFIXES=['.pdb'], - ) - - # TODO(sgk): mslink.py creates a shlibLinkAction which doesn't specify - # '$SHLINKCOMSTR' as its command string. This breaks --brief. For now, - # hack into the existing action and override its command string. - env['SHLINKCOM'].list[0].cmdstr = '$SHLINKCOMSTR' diff --git a/site_scons/site_tools/visual_studio_solution.py b/site_scons/site_tools/visual_studio_solution.py deleted file mode 100644 index 597b19c..0000000 --- a/site_scons/site_tools/visual_studio_solution.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Visual Studio solution file generation tool for SCons.""" - - -import sys -import SCons.Script - - -def Solution(env, solution_name, - environments, - exclude_pattern=None, - extra_build_targets=None): - """Builds an MSVS solution containing all projects underneath build/win. - - Args: - solution_name: Name of the solution. - environments: List of environments for variants. Only the first one - will be used to build the solutions/projects. - exclude_pattern: Files matching this pattern will not be added to the - projects and solution. - extra_build_targets: Dict of extra build targets, indexed by target - name. Each extra build target will be given - its own empty project. - """ - - # Provide an empty dict for the set of extra targets, by default. - if extra_build_targets is None: - extra_build_targets = dict() - - # Fail if not on windows for now. - if sys.platform not in ['win32', 'cygwin']: - print ('*** Solution file generation skipped ' - '(not supported on this platform).') - return - - # Add in the msvs tool. - env.Tool('msvs') - - # Pick out variants - variants = [e['BUILD_TYPE'] for e in environments] - # Pick out build targets - build_targets = [e.subst('$TARGET_ROOT') for e in environments] - # pick out sources, headers, and resources - sources, headers, resources, others = env.GatherInputs( - [env.Dir('$DESTINATION_ROOT')], - ['.+\\.(c|cc|m|mm|cpp)$', # source files - '.+\\.(h|hh|hpp)$', # header files - '.+\\.(rc)$', # resource files - '.*'], # all other files - exclude_pattern=exclude_pattern, - ) - # Build main Visual Studio Project file - project_list = env.MSVSProject(target=solution_name + - env['MSVSPROJECTSUFFIX'], - srcs=sources + headers + others + resources, - incs=[], - misc=[], - resources=[], - auto_build_solution=0, - MSVSCLEANCOM='hammer.bat -c MODE=all', - MSVSBUILDCOM='hammer.bat MODE=all', - MSVSREBUILD='hammer.bat -c MODE=all;' - 'hammer.bat MODE=all', - buildtarget=build_targets, - variant=variants) - # Collect other projects - for e in extra_build_targets: - # Explicitly create a node for target, so SCons will expand env variables. - build_target = env.File(extra_build_targets[e]) - # Create an empty project that only has a build target. - project_list += env.MSVSProject(target='projects/' + e + '/' + e + - env['MSVSPROJECTSUFFIX'], - srcs=[], - incs=[], - resources=[], - misc=[], - auto_build_solution=0, - MSVSCLEANCOM='rem', - MSVSBUILDCOM='rem', - MSVSREBUILD='rem', - buildtarget=build_target, - variant=variants[0]) - - # Build Visual Studio Solution file. - solution = env.MSVSSolution(target=solution_name + env['MSVSSOLUTIONSUFFIX'], - projects=project_list, - variant=variants) - # Explicitly add dependencies. - env.Depends(solution, project_list) - - return solution - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - - # Add in the gather_inputs tool. - env.Tool('gather_inputs') - - # Add a method to generate a combined solution file. - env.AddMethod(Solution, 'Solution') diff --git a/site_scons/site_tools/windows_hard_link.py b/site_scons/site_tools/windows_hard_link.py deleted file mode 100644 index 9fae120..0000000 --- a/site_scons/site_tools/windows_hard_link.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/python2.4 -# Copyright 2008, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Hard link support for Windows. - -This module is a SCons tool which should be include in the topmost windows -environment. It is usually included by the target_platform_windows tool. -""" - - -import os -import stat -import sys -import SCons - -if sys.platform == 'win32': - # Only attempt to load pywin32 on Windows systems - try: - import win32file - except ImportError: - print ('Warning: Unable to load win32file module; using copy instead of' - ' hard linking for env.Install(). Is pywin32 present?') - -#------------------------------------------------------------------------------ -# Python 2.4 and 2.5's os module doesn't support os.link on Windows, even -# though Windows does have hard-link capability on NTFS filesystems. So by -# default, SCons will insist on copying files instead of linking them as it -# does on other (linux,mac) OS's. -# -# Use the CreateHardLink() functionality from pywin32 to provide hard link -# capability on Windows also. - - -def _HardLink(fs, src, dst): - """Hard link function for hooking into SCons.Node.FS. - - Args: - fs: Filesystem class to use. - src: Source filename to link to. - dst: Destination link name to create. - - Raises: - OSError: The link could not be created. - """ - # A hard link shares file permissions from the source. On Windows, the write - # access of the file itself determines whether the file can be deleted - # (unlike Linux/Mac, where it's the write access of the containing - # directory). So if we made a link from a read-only file, the only way to - # delete it would be to make the link writable, which would have the - # unintended effect of making the source writable too. - # - # So if the source is read-only, we can't hard link from it. - if not stat.S_IMODE(fs.stat(src)[stat.ST_MODE]) & stat.S_IWRITE: - raise OSError('Unsafe to hard-link read-only file: %s' % src) - - # If the file is writable, only hard-link from it if it was build by SCons. - # Those files shouldn't later become read-only. We don't hard-link from - # writable files which SCons didn't create, because those could become - # read-only (for example, following a 'p4 submit'), which as indicated above - # would make our link read-only too. - if not fs.File(src).has_builder(): - raise OSError('Unsafe to hard-link file not built by SCons: %s' % src) - - try: - win32file.CreateHardLink(dst, src) - except win32file.error, msg: - # Translate errors into standard OSError which SCons expects. - raise OSError(msg) - - -#------------------------------------------------------------------------------ - - -def generate(env): - # NOTE: SCons requires the use of this name, which fails gpylint. - """SCons entry point for this tool.""" - env = env # Silence gpylint - - # Patch in our hard link function, if we were able to load pywin32 - if 'win32file' in globals(): - SCons.Node.FS._hardlink_func = _HardLink |