install.py
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:8k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. """SCons.Tool.install
  2. Tool-specific initialization for the install tool.
  3. There normally shouldn't be any need to import this module directly.
  4. It will usually be imported through the generic SCons.Tool.Tool()
  5. selection method.
  6. """
  7. #
  8. # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
  9. #
  10. # Permission is hereby granted, free of charge, to any person obtaining
  11. # a copy of this software and associated documentation files (the
  12. # "Software"), to deal in the Software without restriction, including
  13. # without limitation the rights to use, copy, modify, merge, publish,
  14. # distribute, sublicense, and/or sell copies of the Software, and to
  15. # permit persons to whom the Software is furnished to do so, subject to
  16. # the following conditions:
  17. #
  18. # The above copyright notice and this permission notice shall be included
  19. # in all copies or substantial portions of the Software.
  20. #
  21. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  22. # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  23. # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. #
  29. __revision__ = "src/engine/SCons/Tool/install.py 3057 2008/06/09 22:21:00 knight"
  30. import os
  31. import shutil
  32. import stat
  33. import SCons.Action
  34. from SCons.Util import make_path_relative
  35. #
  36. # We keep track of *all* installed files.
  37. _INSTALLED_FILES = []
  38. _UNIQUE_INSTALLED_FILES = None
  39. #
  40. # Functions doing the actual work of the Install Builder.
  41. #
  42. def copyFunc(dest, source, env):
  43.     """Install a source file or directory into a destination by copying,
  44.     (including copying permission/mode bits)."""
  45.     if os.path.isdir(source):
  46.         if os.path.exists(dest):
  47.             if not os.path.isdir(dest):
  48.                 raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source))
  49.         else:
  50.             parent = os.path.split(dest)[0]
  51.             if not os.path.exists(parent):
  52.                 os.makedirs(parent)
  53.         shutil.copytree(source, dest)
  54.     else:
  55.         shutil.copy2(source, dest)
  56.         st = os.stat(source)
  57.         os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
  58.     return 0
  59. def installFunc(target, source, env):
  60.     """Install a source file into a target using the function specified
  61.     as the INSTALL construction variable."""
  62.     try:
  63.         install = env['INSTALL']
  64.     except KeyError:
  65.         raise SCons.Errors.UserError('Missing INSTALL construction variable.')
  66.     assert len(target)==len(source), 
  67.            "Installing source %s into target %s: target and source lists must have same length."%(map(str, source), map(str, target))
  68.     for t,s in zip(target,source):
  69.         if install(t.get_path(),s.get_path(),env):
  70.             return 1
  71.     return 0
  72. def stringFunc(target, source, env):
  73.     installstr = env.get('INSTALLSTR')
  74.     if installstr:
  75.         return env.subst_target_source(installstr, 0, target, source)
  76.     target = str(target[0])
  77.     source = str(source[0])
  78.     if os.path.isdir(source):
  79.         type = 'directory'
  80.     else:
  81.         type = 'file'
  82.     return 'Install %s: "%s" as "%s"' % (type, source, target)
  83. #
  84. # Emitter functions
  85. #
  86. def add_targets_to_INSTALLED_FILES(target, source, env):
  87.     """ an emitter that adds all target files to the list stored in the
  88.     _INSTALLED_FILES global variable. This way all installed files of one
  89.     scons call will be collected.
  90.     """
  91.     global _INSTALLED_FILES, _UNIQUE_INSTALLED_FILES
  92.     _INSTALLED_FILES.extend(target)
  93.     _UNIQUE_INSTALLED_FILES = None
  94.     return (target, source)
  95. class DESTDIR_factory:
  96.     """ a node factory, where all files will be relative to the dir supplied
  97.     in the constructor.
  98.     """
  99.     def __init__(self, env, dir):
  100.         self.env = env
  101.         self.dir = env.arg2nodes( dir, env.fs.Dir )[0]
  102.     def Entry(self, name):
  103.         name = make_path_relative(name)
  104.         return self.dir.Entry(name)
  105.     def Dir(self, name):
  106.         name = make_path_relative(name)
  107.         return self.dir.Dir(name)
  108. #
  109. # The Builder Definition
  110. #
  111. install_action   = SCons.Action.Action(installFunc, stringFunc)
  112. installas_action = SCons.Action.Action(installFunc, stringFunc)
  113. BaseInstallBuilder               = None
  114. def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw):
  115.     if target and dir:
  116.         import SCons.Errors
  117.         raise SCons.Errors.UserError, "Both target and dir defined for Install(), only one may be defined."
  118.     if not dir:
  119.         dir=target
  120.     import SCons.Script
  121.     install_sandbox = SCons.Script.GetOption('install_sandbox')
  122.     if install_sandbox:
  123.         target_factory = DESTDIR_factory(env, install_sandbox)
  124.     else:
  125.         target_factory = env.fs
  126.     try:
  127.         dnodes = env.arg2nodes(dir, target_factory.Dir)
  128.     except TypeError:
  129.         raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory.  Perhaps you have the Install() arguments backwards?" % str(dir)
  130.     sources = env.arg2nodes(source, env.fs.Entry)
  131.     tgt = []
  132.     for dnode in dnodes:
  133.         for src in sources:
  134.             # Prepend './' so the lookup doesn't interpret an initial
  135.             # '#' on the file name portion as meaning the Node should
  136.             # be relative to the top-level SConstruct directory.
  137.             target = env.fs.Entry('.'+os.sep+src.name, dnode)
  138.             #tgt.extend(BaseInstallBuilder(env, target, src, **kw))
  139.             tgt.extend(apply(BaseInstallBuilder, (env, target, src), kw))
  140.     return tgt
  141. def InstallAsBuilderWrapper(env, target=None, source=None, **kw):
  142.     result = []
  143.     for src, tgt in map(lambda x, y: (x, y), source, target):
  144.         #result.extend(BaseInstallBuilder(env, tgt, src, **kw))
  145.         result.extend(apply(BaseInstallBuilder, (env, tgt, src), kw))
  146.     return result
  147. added = None
  148. def generate(env):
  149.     from SCons.Script import AddOption, GetOption
  150.     global added
  151.     if not added:
  152.         added = 1
  153.         AddOption('--install-sandbox',
  154.                   dest='install_sandbox',
  155.                   type="string",
  156.                   action="store",
  157.                   help='A directory under which all installed files will be placed.')
  158.     global BaseInstallBuilder
  159.     if BaseInstallBuilder is None:
  160.         install_sandbox = GetOption('install_sandbox')
  161.         if install_sandbox:
  162.             target_factory = DESTDIR_factory(env, install_sandbox)
  163.         else:
  164.             target_factory = env.fs
  165.         BaseInstallBuilder = SCons.Builder.Builder(
  166.                               action         = install_action,
  167.                               target_factory = target_factory.Entry,
  168.                               source_factory = env.fs.Entry,
  169.                               multi          = 1,
  170.                               emitter        = [ add_targets_to_INSTALLED_FILES, ],
  171.                               name           = 'InstallBuilder')
  172.     env['BUILDERS']['_InternalInstall'] = InstallBuilderWrapper
  173.     env['BUILDERS']['_InternalInstallAs'] = InstallAsBuilderWrapper
  174.     # We'd like to initialize this doing something like the following,
  175.     # but there isn't yet support for a ${SOURCE.type} expansion that
  176.     # will print "file" or "directory" depending on what's being
  177.     # installed.  For now we punt by not initializing it, and letting
  178.     # the stringFunc() that we put in the action fall back to the
  179.     # hand-crafted default string if it's not set.
  180.     #
  181.     #try:
  182.     #    env['INSTALLSTR']
  183.     #except KeyError:
  184.     #    env['INSTALLSTR'] = 'Install ${SOURCE.type}: "$SOURCES" as "$TARGETS"'
  185.     try:
  186.         env['INSTALL']
  187.     except KeyError:
  188.         env['INSTALL']    = copyFunc
  189. def exists(env):
  190.     return 1