diff options
author | Gary Oberbrunner <garyo@oberbrunner.com> | 2012-12-20 23:59:23 -0500 |
---|---|---|
committer | Gary Oberbrunner <garyo@oberbrunner.com> | 2012-12-20 23:59:23 -0500 |
commit | 7120265b1ae307e046b061f175ded16de5d710fa (patch) | |
tree | fcd0d8c10af4218b79a923a4ea4e3bd47c7344bc | |
parent | 798958ecf7d5c9037df885cc0913879accc1becf (diff) | |
parent | fe48a24ada8834c2d7b0c7f558989115319cb273 (diff) | |
download | scons-7120265b1ae307e046b061f175ded16de5d710fa.tar.gz |
Merged in techtonik/scons (pull request #63: Another minor cleanup as the code study goes on)
-rw-r--r-- | src/CHANGES.txt | 4 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 1 | ||||
-rw-r--r-- | src/engine/SCons/Tool/__init__.py | 121 | ||||
-rw-r--r-- | src/engine/SCons/Tool/__init__.xml | 24 | ||||
-rw-r--r-- | src/engine/SCons/Tool/install.py | 181 | ||||
-rw-r--r-- | src/engine/SCons/Tool/install.xml | 13 | ||||
-rw-r--r-- | src/engine/SCons/Tool/link.py | 63 | ||||
-rw-r--r-- | test/LINK/VersionedLib.py | 124 |
8 files changed, 526 insertions, 5 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 50a748d2..16cfa3ae 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -62,6 +62,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..532c8503 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 @@ -383,3 +396,14 @@ TODO TODO </summary> </cvar> + +<cvar name="SHLIBVERSION"> +<summary> +When this 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. +</summary> +</cvar> 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..bec592bc 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']) @@ -41,6 +43,15 @@ target and source arguments list different numbers of files or directories. +</summary> +</builder> + +<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', 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:
|