summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Tool/install.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons/Tool/install.py')
-rw-r--r--src/engine/SCons/Tool/install.py102
1 files changed, 100 insertions, 2 deletions
diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py
index eb50405..9aa9d46 100644
--- a/src/engine/SCons/Tool/install.py
+++ b/src/engine/SCons/Tool/install.py
@@ -119,6 +119,23 @@ def copyFunc(dest, source, env):
shutil.copy2(source, dest)
st = os.stat(source)
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+
+ return 0
+
+#
+# Functions doing the actual work of the InstallVersionedLib Builder.
+#
+def copyFuncVersionedLib(dest, source, env):
+ """Install a versioned library into a destination by copying,
+ (including copying permission/mode bits) and then creating
+ required symlinks."""
+
+ if os.path.isdir(source):
+ raise SCons.Errors.UserError("cannot install directory `%s' as a version library" % str(source) )
+ else:
+ shutil.copy2(source, dest)
+ st = os.stat(source)
+ os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
versionedLibLinks(dest, source, env)
return 0
@@ -202,6 +219,22 @@ def installFunc(target, source, env):
return 0
+def installFuncVersionedLib(target, source, env):
+ """Install a versioned library into a target using the function specified
+ as the INSTALLVERSIONEDLIB construction variable."""
+ try:
+ install = env['INSTALLVERSIONEDLIB']
+ except KeyError:
+ raise SCons.Errors.UserError('Missing INSTALLVERSIONEDLIB construction variable.')
+
+ assert len(target)==len(source), \
+ "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target)))
+ for t,s in zip(target,source):
+ if install(t.get_path(),s.get_path(),env):
+ return 1
+
+ return 0
+
def stringFunc(target, source, env):
installstr = env.get('INSTALLSTR')
if installstr:
@@ -223,6 +256,17 @@ def add_targets_to_INSTALLED_FILES(target, source, env):
scons call will be collected.
"""
global _INSTALLED_FILES, _UNIQUE_INSTALLED_FILES
+ _INSTALLED_FILES.extend(target)
+
+ _UNIQUE_INSTALLED_FILES = None
+ return (target, source)
+
+def add_versioned_targets_to_INSTALLED_FILES(target, source, env):
+ """ an emitter that adds all target files to the list stored in the
+ _INSTALLED_FILES global variable. This way all installed files of one
+ scons call will be collected.
+ """
+ global _INSTALLED_FILES, _UNIQUE_INSTALLED_FILES
Verbose = False
_INSTALLED_FILES.extend(target)
@@ -260,8 +304,9 @@ class DESTDIR_factory(object):
#
# The Builder Definition
#
-install_action = SCons.Action.Action(installFunc, stringFunc)
-installas_action = SCons.Action.Action(installFunc, stringFunc)
+install_action = SCons.Action.Action(installFunc, stringFunc)
+installas_action = SCons.Action.Action(installFunc, stringFunc)
+installVerLib_action = SCons.Action.Action(installFuncVersionedLib, stringFunc)
BaseInstallBuilder = None
@@ -302,6 +347,37 @@ def InstallAsBuilderWrapper(env, target=None, source=None, **kw):
result.extend(BaseInstallBuilder(env, tgt, src, **kw))
return result
+BaseVersionedInstallBuilder = None
+
+def InstallVersionedBuilderWrapper(env, target=None, source=None, dir=None, **kw):
+ if target and dir:
+ import SCons.Errors
+ raise SCons.Errors.UserError("Both target and dir defined for Install(), only one may be defined.")
+ if not dir:
+ dir=target
+
+ import SCons.Script
+ install_sandbox = SCons.Script.GetOption('install_sandbox')
+ if install_sandbox:
+ target_factory = DESTDIR_factory(env, install_sandbox)
+ else:
+ target_factory = env.fs
+
+ try:
+ dnodes = env.arg2nodes(dir, target_factory.Dir)
+ except TypeError:
+ raise SCons.Errors.UserError("Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir))
+ sources = env.arg2nodes(source, env.fs.Entry)
+ tgt = []
+ for dnode in dnodes:
+ for src in sources:
+ # Prepend './' so the lookup doesn't interpret an initial
+ # '#' on the file name portion as meaning the Node should
+ # be relative to the top-level SConstruct directory.
+ target = env.fs.Entry('.'+os.sep+src.name, dnode)
+ tgt.extend(BaseVersionedInstallBuilder(env, target, src, **kw))
+ return tgt
+
added = None
def generate(env):
@@ -332,8 +408,25 @@ def generate(env):
emitter = [ add_targets_to_INSTALLED_FILES, ],
name = 'InstallBuilder')
+ global BaseVersionedInstallBuilder
+ if BaseVersionedInstallBuilder is None:
+ install_sandbox = GetOption('install_sandbox')
+ if install_sandbox:
+ target_factory = DESTDIR_factory(env, install_sandbox)
+ else:
+ target_factory = env.fs
+
+ BaseVersionedInstallBuilder = SCons.Builder.Builder(
+ action = installVerLib_action,
+ target_factory = target_factory.Entry,
+ source_factory = env.fs.Entry,
+ multi = 1,
+ emitter = [ add_versioned_targets_to_INSTALLED_FILES, ],
+ name = 'InstallVersionedBuilder')
+
env['BUILDERS']['_InternalInstall'] = InstallBuilderWrapper
env['BUILDERS']['_InternalInstallAs'] = InstallAsBuilderWrapper
+ env['BUILDERS']['_InternalInstallVersionedLib'] = InstallVersionedBuilderWrapper
# We'd like to initialize this doing something like the following,
# but there isn't yet support for a ${SOURCE.type} expansion that
@@ -352,6 +445,11 @@ def generate(env):
except KeyError:
env['INSTALL'] = copyFunc
+ try:
+ env['INSTALLVERSIONEDLIB']
+ except KeyError:
+ env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib
+
def exists(env):
return 1