summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Managan <ramanagan@att.net>2012-12-18 15:08:45 -0800
committerRobert Managan <ramanagan@att.net>2012-12-18 15:08:45 -0800
commit3687ead0810082b0a84522b786d1600cbbadce12 (patch)
tree6313f756aba2d013f3d762f46812f3274a91f981
parentdc1f4a53e0ed3387447e86e8d9482de2542bbc51 (diff)
downloadscons-3687ead0810082b0a84522b786d1600cbbadce12.tar.gz
removed versioned library support from Install and put it in InstallVersionedLib
-rw-r--r--src/CHANGES.txt4
-rw-r--r--src/engine/SCons/Tool/__init__.py8
-rw-r--r--src/engine/SCons/Tool/install.py102
-rw-r--r--src/engine/SCons/Tool/install.xml10
-rw-r--r--src/engine/SCons/Tool/link.py4
-rw-r--r--test/LINK/VersionedLib.py2
6 files changed, 118 insertions, 12 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 994cc714..ea257d4c 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -53,8 +53,8 @@ RELEASE 2.X.X -
so biber is called automatically if biblatex requires it.
- Add SHLIBVERSION as an option that tells SharedLibrary to build
a versioned shared library and create the required symlinks.
- Update Install to create the required symlinks when installing
- a versioned shared library.
+ Add builder InstallVersionedLib to create the required symlinks
+ installing a versioned shared library.
RELEASE 2.2.0 - Mon, 05 Aug 2012 15:37:48 +0000
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 4f46cd86..83c2fb51 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -246,6 +246,7 @@ def VersionShLibLinkNames(version, libname, env):
linknames = []
if version.count(".") != 2:
# We need a version string of the form x.y.z to proceed
+ # Several changes need to be made to support versions like x.y
raise ValueError
if platform == 'darwin':
@@ -639,13 +640,16 @@ class ToolInitializer(object):
# the ToolInitializer class.
def Initializers(env):
- ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs'])
+ ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs', '_InternalInstallVersionedLib'])
def Install(self, *args, **kw):
return self._InternalInstall(*args, **kw)
def InstallAs(self, *args, **kw):
return self._InternalInstallAs(*args, **kw)
+ def InstallVersionedLib(self, *args, **kw):
+ return self._InternalInstallVersionedLib(*args, **kw)
env.AddMethod(Install)
env.AddMethod(InstallAs)
+ env.AddMethod(InstallVersionedLib)
def FindTool(tools, env):
for tool in tools:
@@ -792,5 +796,3 @@ def tool_list(platform, env):
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
-
-
diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py
index eb504058..9aa9d460 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
diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml
index b83bb609..d9cb6710 100644
--- a/src/engine/SCons/Tool/install.xml
+++ b/src/engine/SCons/Tool/install.xml
@@ -24,8 +24,7 @@ which must be a directory.
The names of the specified source files or directories
remain the same within the destination directory. The
sources may be given as a string or as a node returned by
-a builder. If the source is a versioned shared library
-the appropriate symlinks to it will be generated.
+a builder.
<example>
env.Install('/usr/local/bin', source = ['foo', 'bar'])
@@ -45,6 +44,13 @@ and
source
arguments list different numbers of files or directories.
+<builder name="InstallVersionedLib">
+<summary>
+Installs a versioned shared library. The &cv-link-SHLIBVERSION;
+construction variable should be defined in the environment
+to confirm the version number in the library name.
+The symlinks appropriate to the architecture will be generated.
+
<example>
env.InstallAs(target = '/usr/local/bin/foo',
source = 'foo_debug')
diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py
index 67d5b199..2ba419ec 100644
--- a/src/engine/SCons/Tool/link.py
+++ b/src/engine/SCons/Tool/link.py
@@ -140,7 +140,7 @@ def generate(env):
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared')
env['SHLINKCOM'] = '$SHLINK -o $TARGET $SHLINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS'
# don't set up the emitter, cause AppendUnique will generate a list
- # starting with None
+ # starting with None :-(
env.Append(SHLIBEMITTER = [shlib_emitter])
env['SMARTLINK'] = smart_link
env['LINK'] = "$SMARTLINK"
@@ -164,7 +164,7 @@ def generate(env):
SCons.Tool.createLoadableModuleBuilder(env)
env['LDMODULE'] = '$SHLINK'
# don't set up the emitter, cause AppendUnique will generate a list
- # starting with None
+ # starting with None :-(
env.Append(LDMODULEEMITTER='$SHLIBEMITTER')
env['LDMODULEPREFIX'] = '$SHLIBPREFIX'
env['LDMODULESUFFIX'] = '$SHLIBSUFFIX'
diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py
index da0a8c4e..34bef2a5 100644
--- a/test/LINK/VersionedLib.py
+++ b/test/LINK/VersionedLib.py
@@ -41,7 +41,7 @@ objs = env.SharedObject('test.c')
mylib = env.SharedLibrary('test', objs, SHLIBVERSION = '2.5.4')
env.Program(source=['testapp.c',mylib])
env.Program(target=['testapp2'],source=['testapp.c','libtest.dylib'])
-instnode = env.Install("#/installtest",mylib)
+instnode = env.InstallVersionedLib("#/installtest",mylib)
env.Default(instnode)
""")