summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Managan <ramanagan@att.net>2012-12-18 15:09:21 -0800
committerRobert Managan <ramanagan@att.net>2012-12-18 15:09:21 -0800
commit8eb588841cb8365877c704d8d48072eb28279329 (patch)
tree5767433bfda9d36e134af9b09446db20ddd34f0b
parent84d3d7f420f14bf33bea7f4cfc583118731da93f (diff)
parent3687ead0810082b0a84522b786d1600cbbadce12 (diff)
downloadscons-8eb588841cb8365877c704d8d48072eb28279329.tar.gz
update to latest SCons commits
-rwxr-xr-x[-rw-r--r--]runtest.py0
-rw-r--r--src/CHANGES.txt4
-rw-r--r--src/engine/SCons/Environment.py1
-rw-r--r--src/engine/SCons/Tool/__init__.py121
-rw-r--r--src/engine/SCons/Tool/__init__.xml13
-rw-r--r--src/engine/SCons/Tool/install.py181
-rw-r--r--src/engine/SCons/Tool/install.xml11
-rw-r--r--src/engine/SCons/Tool/link.py63
-rw-r--r--test/LINK/VersionedLib.py124
9 files changed, 513 insertions, 5 deletions
diff --git a/runtest.py b/runtest.py
index 6beb4ba7..6beb4ba7 100644..100755
--- a/runtest.py
+++ b/runtest.py
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index e8aa5eec..21984e42 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -60,6 +60,10 @@ RELEASE 2.X.X -
in LaTeX's glossaries package and the files it creates.
- Improve support for new versions of biblatex in the TeX builder
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.
+ 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/Environment.py b/src/engine/SCons/Environment.py
index 2c71e617..8cc033eb 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -2247,6 +2247,7 @@ class Base(SubstitutionEnvironment):
install._UNIQUE_INSTALLED_FILES = SCons.Util.uniquer_hashables(install._INSTALLED_FILES)
return install._UNIQUE_INSTALLED_FILES
+
class OverrideEnvironment(Base):
"""A proxy that overrides variables in a wrapped construction
environment by returning values from an overrides dictionary in
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 53579593..83c2fb51 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -39,6 +39,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import imp
import sys
+import re
+import os
+import shutil
import SCons.Builder
import SCons.Errors
@@ -233,6 +236,116 @@ def createStaticLibBuilder(env):
return static_lib
+def VersionShLibLinkNames(version, libname, env):
+ """Generate names of symlinks to the versioned shared library"""
+ Verbose = False
+ platform = env.subst('$PLATFORM')
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS'))
+
+ 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':
+ # For libfoo.x.y.z.dylib, linknames libfoo.so
+ suffix_re = re.escape('.' + version + shlib_suffix)
+ linkname = re.sub(suffix_re, shlib_suffix, libname)
+ if Verbose:
+ print "VersionShLibLinkNames: linkname = ",linkname
+ linknames.append(linkname)
+ elif platform == 'posix':
+ # For libfoo.so.x.y.z, linknames libfoo.so libfoo.so.x.y libfoo.so.x
+ suffix_re = re.escape(shlib_suffix + '.' + version)
+ # First linkname has no version number
+ linkname = re.sub(suffix_re, shlib_suffix, libname)
+ if Verbose:
+ print "VersionShLibLinkNames: linkname = ",linkname
+ linknames.append(linkname)
+ versionparts = version.split('.')
+ major_name = linkname + "." + versionparts[0]
+ minor_name = major_name + "." + versionparts[1]
+ #Only add link for major_name
+ #for linkname in [major_name, minor_name]:
+ for linkname in [major_name, ]:
+ if Verbose:
+ print "VersionShLibLinkNames: linkname ",linkname, ", target ",libname
+ linknames.append(linkname)
+ return linknames
+
+def VersionedSharedLibrary(target = None, source= None, env=None):
+ """Build a shared library. If the environment has SHLIBVERSION
+defined make a versioned shared library and create the appropriate
+symlinks for the platform we are on"""
+ Verbose = False
+ try:
+ version = env.subst('$SHLIBVERSION')
+ except KeyError:
+ version = None
+
+ # libname includes the version number if one was given
+ libname = target[0].name
+ platform = env.subst('$PLATFORM')
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS'))
+ if Verbose:
+ print "VersionShLib: libname = ",libname
+ print "VersionShLib: platform = ",platform
+ print "VersionShLib: shlib_suffix = ",shlib_suffix
+ print "VersionShLib: target = ",str(target[0])
+
+ if version:
+ # set the shared library link flags
+ if platform == 'posix':
+ suffix_re = re.escape(shlib_suffix + '.' + version)
+ (major, age, revision) = version.split(".")
+ # soname will have only the major version number in it
+ soname = re.sub(suffix_re, shlib_suffix, libname) + '.' + major
+ shlink_flags += [ '-Wl,-Bsymbolic', '-Wl,-soname=%s' % soname ]
+ if Verbose:
+ print " soname ",soname,", shlink_flags ",shlink_flags
+ elif platform == 'cygwin':
+ shlink_flags += [ '-Wl,-Bsymbolic',
+ '-Wl,--out-implib,${TARGET.base}.a' ]
+ elif platform == 'darwin':
+ shlink_flags += [ '-current_version', '%s' % version,
+ '-compatibility_version', '%s' % version,
+ '-undefined', 'dynamic_lookup' ]
+ if Verbose:
+ print "VersionShLib: shlink_flags = ",shlink_flags
+ envlink = env.Clone()
+ envlink['SHLINKFLAGS'] = shlink_flags
+ else:
+ envlink = env
+
+ result = SCons.Defaults.ShLinkAction(target, source, envlink)
+
+ if version:
+ # here we need the full pathname so the links end up in the right directory
+ libname = target[0].path
+ linknames = VersionShLibLinkNames(version, libname, env)
+ if Verbose:
+ print "VerShLib: linknames ",linknames
+ # Here we just need the file name w/o path as the target of the link
+ lib_ver = target[0].name
+ # make symlink of adjacent names in linknames
+ for count in range(len(linknames)):
+ linkname = linknames[count]
+ if count > 0:
+ os.symlink(os.path.basename(linkname),lastname)
+ if Verbose:
+ print "VerShLib: made sym link of %s -> %s" % (lastname,linkname)
+ lastname = linkname
+ # finish chain of sym links with link to the actual library
+ os.symlink(lib_ver,lastname)
+ if Verbose:
+ print "VerShLib: made sym link of %s -> %s" % (lib_ver,linkname)
+ return result
+
+ShLibAction = SCons.Action.Action(VersionedSharedLibrary, None)
+
def createSharedLibBuilder(env):
"""This is a utility function that creates the SharedLibrary
Builder in an Environment if it is not there already.
@@ -245,7 +358,7 @@ def createSharedLibBuilder(env):
except KeyError:
import SCons.Defaults
action_list = [ SCons.Defaults.SharedCheck,
- SCons.Defaults.ShLinkAction ]
+ ShLibAction ]
shared_lib = SCons.Builder.Builder(action = action_list,
emitter = "$SHLIBEMITTER",
prefix = '$SHLIBPREFIX',
@@ -527,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:
@@ -679,3 +795,4 @@ def tool_list(platform, env):
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
+
diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml
index d274a953..d491fa5d 100644
--- a/src/engine/SCons/Tool/__init__.xml
+++ b/src/engine/SCons/Tool/__init__.xml
@@ -146,6 +146,19 @@ On some platforms, there is a distinction between a shared library
and a loadable module (explicitly loaded by user action).
For maximum portability, use the &b-LoadableModule; builder for the latter.
+When the &cv-link-SHLIBVERSION; construction variable is defined a versioned
+shared library is created. This modifies the &cv-link-SHLINKFLAGS; as required,
+adds the version number to the library name, and creates the symlinks that
+are needed. &cv-link-SHLIBVERSION; needs to be of the form X.Y.Z, where X
+and Y are numbers, and Z is a number but can also contain letters to designate
+alpha, beta, or release candidate patch levels.
+
+This builder may create multiple links to the library. On a POSIX system,
+for the shared library libbar.so.2.3.1, the links created would be
+libbar.so, libbar.so.2, and libbar.so.2.3; on a Darwin (OSX) system
+the library would be libbar.2.3.1.dylib and the link would be
+libbar.dylib.
+
On Windows systems, specifying
<literal>register=1</literal>
will cause the <filename>.dll</filename> to be
diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py
index 7e5fed5e..9aa9d460 100644
--- a/src/engine/SCons/Tool/install.py
+++ b/src/engine/SCons/Tool/install.py
@@ -33,6 +33,7 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
+import re
import shutil
import stat
@@ -121,6 +122,87 @@ def copyFunc(dest, source, env):
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
+
+def versionedLibVersion(dest, env):
+ """Check if dest is a version shared library name. Return version, libname, & install_dir if it is."""
+ Verbose = False
+ platform = env.subst('$PLATFORM')
+ if not (platform == 'posix' or platform == 'darwin'):
+ return (None, None, None)
+
+ libname = os.path.basename(dest)
+ install_dir = os.path.dirname(dest)
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ # See if the source name is a versioned shared library, get the version number
+ result = False
+
+ version_re = re.compile("[0-9]+\\.[0-9]+\\.[0-9a-zA-Z]+")
+ version_File = None
+ if platform == 'posix':
+ # handle unix names
+ versioned_re = re.compile(re.escape(shlib_suffix + '.') + "[0-9]+\\.[0-9]+\\.[0-9a-zA-Z]+")
+ result = versioned_re.findall(libname)
+ if result:
+ version_File = version_re.findall(versioned_re.findall(libname)[-1])[-1]
+ elif platform == 'darwin':
+ # handle OSX names
+ versioned_re = re.compile("\\.[0-9]+\\.[0-9]+\\.[0-9a-zA-Z]+" + re.escape(shlib_suffix) )
+ result = versioned_re.findall(libname)
+ if result:
+ version_File = version_re.findall(versioned_re.findall(libname)[-1])[-1]
+
+ if Verbose:
+ print "install: version_File ", version_File
+ # result is False if we did not find a versioned shared library name, so return and empty list
+ if not result:
+ return (None, libname, install_dir)
+
+ version = None
+ # get version number from the environment
+ try:
+ version = env.subst('$SHLIBVERSION')
+ except KeyError:
+ version = None
+
+ if version != version_File:
+ #raise SCons.Errors.UserError("SHLIBVERSION '%s' does not match the version # '%s' in the filename" % (version, version_File) )
+ print "SHLIBVERSION '%s' does not match the version # '%s' in the filename, proceeding based on file name" % (version, version_File)
+ version = version_File
+ return (version, libname, install_dir)
+
+def versionedLibLinks(dest, source, env):
+ """If we are installing a versioned shared library create the required links."""
+ Verbose = False
+ linknames = []
+ version, libname, install_dir = versionedLibVersion(dest, env)
+
+ if version != None:
+ # libname includes the version number if one was given
+ linknames = SCons.Tool.VersionShLibLinkNames(version,libname,env)
+ for linkname in linknames:
+ if Verbose:
+ print "make link of %s to %s" %(libname, os.path.join(install_dir, linkname))
+ fulllinkname = os.path.join(install_dir, linkname)
+ os.symlink(libname,fulllinkname)
+ return
+
def installFunc(target, source, env):
"""Install a source file into a target using the function specified
as the INSTALL construction variable."""
@@ -137,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:
@@ -159,6 +257,31 @@ def add_targets_to_INSTALLED_FILES(target, source, env):
"""
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)
+
+ # see if we have a versioned shared library, if so generate side effects
+ version, libname, install_dir = versionedLibVersion(target[0].path, env)
+ if version != None:
+ # generate list of link names
+ linknames = SCons.Tool.VersionShLibLinkNames(version,libname,env)
+ for linkname in linknames:
+ if Verbose:
+ print "make side effect of %s" % os.path.join(install_dir, linkname)
+ fulllinkname = os.path.join(install_dir, linkname)
+ env.SideEffect(fulllinkname,target[0])
+ env.Clean(target[0],fulllinkname)
+
_UNIQUE_INSTALLED_FILES = None
return (target, source)
@@ -181,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
@@ -223,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):
@@ -253,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
@@ -273,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 4b57a688..d9cb6710 100644
--- a/src/engine/SCons/Tool/install.xml
+++ b/src/engine/SCons/Tool/install.xml
@@ -22,7 +22,9 @@ Installs one or more source files or directories
in the specified target,
which must be a directory.
The names of the specified source files or directories
-remain the same within the destination directory.
+remain the same within the destination directory. The
+sources may be given as a string or as a node returned by
+a builder.
<example>
env.Install('/usr/local/bin', source = ['foo', 'bar'])
@@ -42,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 fae7f631..2ba419ec 100644
--- a/src/engine/SCons/Tool/link.py
+++ b/src/engine/SCons/Tool/link.py
@@ -33,6 +33,8 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import re
+
import SCons.Defaults
import SCons.Tool
import SCons.Util
@@ -64,10 +66,71 @@ def smart_link(source, target, env, for_signature):
return '$CC'
def shlib_emitter(target, source, env):
+ Verbose = False
+ platform = env.subst('$PLATFORM')
for tgt in target:
tgt.attributes.shared = 1
+ try:
+ # target[0] comes in as libtest.so. Add the version extensions
+ version = env.subst('$SHLIBVERSION')
+ if version:
+ version_names = shlib_emitter_names(target, source, env)
+ # change the name of the target to include the version number
+ target[0].name = version_names[0]
+ for name in version_names:
+ env.SideEffect(name, target[0])
+ env.Clean(target[0], name)
+ if Verbose:
+ print "shlib_emitter: add side effect - ",name
+ except KeyError:
+ version = None
return (target, source)
+def shlib_emitter_names(target, source, env):
+ """Return list of file names that are side effects for a versioned library build. The first name in the list is the new name for the target"""
+ Verbose = False
+ platform = env.subst('$PLATFORM')
+ version_names = []
+ try:
+ # target[0] comes in as libtest.so. Add the version extensions
+ version = env.subst('$SHLIBVERSION')
+ if version.count(".") != 2:
+ # We need a version of the form x.y.z to proceed
+ raise ValueError
+ if version:
+ if platform == 'posix':
+ versionparts = version.split('.')
+ name = target[0].name
+ # generate library name with the version number
+ version_name = target[0].name + '.' + version
+ if Verbose:
+ print "shlib_emitter_names: target is ", version_name
+ print "shlib_emitter_names: side effect: ", name
+ # add version_name to list of names to be a Side effect
+ version_names.append(version_name)
+ if Verbose:
+ print "shlib_emitter_names: versionparts ",versionparts
+ for ver in versionparts[0:-1]:
+ name = name + '.' + ver
+ if Verbose:
+ print "shlib_emitter_names: side effect: ", name
+ # add name to list of names to be a Side effect
+ version_names.append(name)
+ elif platform == 'darwin':
+ shlib_suffix = env.subst('$SHLIBSUFFIX')
+ name = target[0].name
+ # generate library name with the version number
+ suffix_re = re.escape(shlib_suffix)
+ version_name = re.sub(suffix_re, '.' + version + shlib_suffix, name)
+ if Verbose:
+ print "shlib_emitter_names: target is ", version_name
+ print "shlib_emitter_names: side effect: ", name
+ # add version_name to list of names to be a Side effect
+ version_names.append(version_name)
+ except KeyError:
+ version = None
+ return version_names
+
def generate(env):
"""Add Builders and construction variables for gnulink to an Environment."""
SCons.Tool.createSharedLibBuilder(env)
diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py
new file mode 100644
index 00000000..34bef2a5
--- /dev/null
+++ b/test/LINK/VersionedLib.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+#
+# __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__"
+
+import os
+import sys
+import TestSCons
+
+import SCons.Platform
+
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """\
+import os
+env = Environment()
+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.InstallVersionedLib("#/installtest",mylib)
+env.Default(instnode)
+""")
+
+test.write('test.c', """\
+int testlib(int n)
+{
+return n+1 ;
+}
+""")
+
+test.write('testapp.c', """\
+#include <stdio.h>
+int main(int argc, char **argv)
+{
+int itest ;
+
+itest = testlib(2) ;
+printf("results: testlib(2) = %d\n",itest) ;
+return 0 ;
+}
+""")
+
+platform = SCons.Platform.platform_default()
+
+
+test.run()
+
+if platform == 'posix':
+ # All (?) the files we expect will get created in the current directory
+ files = [
+ 'libtest.so',
+ 'libtest.so.2',
+ 'libtest.so.2.5.4',
+ 'test.os',
+ ]
+ # All (?) the files we expect will get created in the 'installtest' directory
+ instfiles = [
+ 'libtest.so',
+ 'libtest.so.2',
+ 'libtest.so.2.5.4',
+ ]
+elif platform == 'darwin':
+ # All (?) the files we expect will get created in the current directory
+ files = [
+ 'libtest.dylib',
+ 'libtest.2.5.4.dylib',
+ 'test.os',
+ ]
+ # All (?) the files we expect will get created in the 'installtest' directory
+ instfiles = [
+ 'libtest.dylib',
+ 'libtest.2.5.4.dylib',
+ ]
+else:
+ # All (?) the files we expect will get created in the current directory
+ files= [
+ 'libtest.so',
+ 'test.os']
+ # All (?) the files we expect will get created in the 'installtest' directory
+ instfiles = []
+
+for f in files:
+ test.must_exist([ f])
+for f in instfiles:
+ test.must_exist(['installtest', f])
+
+test.run(arguments = '-c')
+
+for f in files:
+ test.must_not_exist([ f])
+for f in instfiles:
+ test.must_not_exist(['installtest', f])
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: