summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons
diff options
context:
space:
mode:
authorPaweł Tomulik <ptomulik@meil.pw.edu.pl>2015-09-04 21:37:17 (GMT)
committerPaweł Tomulik <ptomulik@meil.pw.edu.pl>2015-09-04 21:37:17 (GMT)
commitd124e8dd69f7c73e7ce82d55abf5f69e12379098 (patch)
tree790c4e960f2782dec24110802a0080ddd8aa3772 /src/engine/SCons
parent97a7990e29435b7fe752ce220aac9a6048393395 (diff)
downloadSCons-d124e8dd69f7c73e7ce82d55abf5f69e12379098.zip
SCons-d124e8dd69f7c73e7ce82d55abf5f69e12379098.tar.gz
SCons-d124e8dd69f7c73e7ce82d55abf5f69e12379098.tar.bz2
refactored the versioned lib code a little
Diffstat (limited to 'src/engine/SCons')
-rw-r--r--src/engine/SCons/Tool/__init__.py98
-rw-r--r--src/engine/SCons/Tool/cyglink.py48
-rw-r--r--src/engine/SCons/Tool/gnulink.py56
-rw-r--r--src/engine/SCons/Tool/link.py35
4 files changed, 148 insertions, 89 deletions
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 0e6e7d8..0b09a13 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -236,31 +236,31 @@ def createStaticLibBuilder(env):
return static_lib
-def _call_env_cb(env, callback, args, result = None):
- """Returns the result of env[callback](*args) call if env[callback] is
- callable. If env[callback] does not exist or is not callable, return the
- value provided as the *result* argument. This function is mainly used for
- generating library info such as versioned suffixes, symlink maps, sonames
- etc. by delegating the core job to callbacks configured by current linker
- tool"""
+def _call_linker_cb(env, callback, args, result = None):
+ """Returns the result of env['LINKCALLBACKS'][callback](*args)
+ if env['LINKCALLBACKS'] is a dictionary and env['LINKCALLBACKS'][callback]
+ is callable. If these conditions are not meet, return the value provided as
+ the *result* argument. This function is mainly used for generating library
+ info such as versioned suffixes, symlink maps, sonames etc. by delegating
+ the core job to callbacks configured by current linker tool"""
Verbose = False
if Verbose:
- print '_call_env_cb: args=%r' % args
- print '_call_env_cb: callback=%r' % callback
-
+ print '_call_linker_cb: args=%r' % args
+ print '_call_linker_cb: callback=%r' % callback
+
try:
- cbfun = env[callback]
- except KeyError:
+ cbfun = env['LINKCALLBACKS'][callback]
+ except (KeyError, TypeError):
pass
else:
if Verbose:
- print '_call_env_cb: env[%r] found' % callback
- print '_call_env_cb: env[%r]=%r' % (callback, cbfun)
+ print '_call_linker_cb: env[%r] found' % callback
+ print '_call_linker_cb: env[%r]=%r' % (callback, cbfun)
if(callable(cbfun)):
if Verbose:
- print '_call_env_cb: env[%r] is callable' % callback
+ print '_call_linker_cb: env[%r] is callable' % callback
result = cbfun(env, *args)
return result
@@ -298,6 +298,17 @@ class _LibInfoGeneratorBase(object):
prefix = env.subst('$IMPLIBPREFIX')
return prefix
+ def get_lib_prefix(self, env):
+ prefix = None
+ libtype = self.get_libtype()
+ if libtype == 'ShLib':
+ prefix = env.subst('$SHLIBPREFIX')
+ elif libtype == 'LdMod':
+ prefix = env.subst('$LDMODULEPREFIX')
+ elif libtype == 'ImpLib':
+ prefix = env.subst('$IMPLIBPREFIX')
+ return prefix
+
def get_lib_suffix(self, env):
suffix = None
libtype = self.get_libtype()
@@ -332,11 +343,39 @@ class _LibInfoGeneratorBase(object):
try: libtype = kw['generator_libtype']
except KeyError: libtype = self.get_libtype()
infoname = self.get_infoname()
- return 'GenerateVersioned%s%s' % (libtype, infoname)
+ return 'Versioned%s%s' % (libtype, infoname)
def generate_versioned_lib_info(self, env, args, result = None, **kw):
callback = self.get_versioned_lib_info_generator(**kw)
- return _call_env_cb(env, callback, args, result)
+ return _call_linker_cb(env, callback, args, result)
+
+class _LibPrefixGenerator(_LibInfoGeneratorBase):
+ """Library prefix generator, used as target_prefix in SharedLibrary and
+ LoadableModule builders"""
+ def __init__(self, libtype):
+ super(_LibPrefixGenerator, self).__init__(libtype, 'Prefix')
+
+ def __call__(self, env, sources = None, **kw):
+ Verbose = False
+
+ prefix = self.get_lib_prefix(env)
+ if Verbose:
+ print "_LibPrefixGenerator: input prefix=%r" % prefix
+
+ version = self.get_lib_version(env, **kw)
+ if Verbose:
+ print "_LibPrefixGenerator: version=%r" % version
+
+ if version:
+ prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw)
+
+ if Verbose:
+ print "_LibPrefixGenerator: return prefix=%r" % prefix
+ return prefix
+
+ShLibPrefixGenerator = _LibPrefixGenerator('ShLib')
+LdModPrefixGenerator = _LibPrefixGenerator('LdMod')
+ImpLibPrefixGenerator = _LibPrefixGenerator('ImpLib')
class _LibSuffixGenerator(_LibInfoGeneratorBase):
"""Library suffix generator, used as target_suffix in SharedLibrary and
@@ -408,8 +447,9 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase):
print '_LibSymlinkGenerator: disable=%r' % disable
if version and not disable:
+ prefix = self.get_lib_prefix(env)
suffix = self.get_lib_suffix(env)
- symlinks = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw)
+ symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw)
if Verbose:
print '_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks)
@@ -420,8 +460,19 @@ LdModSymlinkGenerator = _LibSymlinkGenerator('LdMod')
ImpLibSymlinkGenerator = _LibSymlinkGenerator('ImpLib')
class _LibNameGenerator(_LibInfoGeneratorBase):
- """Library name generator. Returns library name (e.g. libfoo.so) for
- a given node (e.g. /foo/bar/libfoo.so.0.1.2)"""
+ """Generates "unmangled" library name from a library file node.
+
+ Generally, it's thought to revert modifications done by prefix/suffix
+ generators (_LibPrefixGenerator/_LibSuffixGenerator) used by a library
+ builder. For example, on gnulink the suffix generator used by SharedLibrary
+ builder appends $SHLIBVERSION to $SHLIBSUFFIX producing node name which
+ ends with "$SHLIBSUFFIX.$SHLIBVERSION". Correspondingly, the implementation
+ of _LibNameGenerator replaces "$SHLIBSUFFIX.$SHLIBVERSION" with
+ "$SHLIBSUFFIX" in the node's basename. So that, if $SHLIBSUFFIX is ".so",
+ $SHLIBVERSION is "0.1.2" and the node path is "/foo/bar/libfoo.so.0.1.2",
+ the _LibNameGenerator shall return "libfoo.so". Other link tools may
+ implement it's own way of library name unmangling.
+ """
def __init__(self, libtype):
super(_LibNameGenerator, self).__init__(libtype, 'Name')
@@ -438,8 +489,9 @@ class _LibNameGenerator(_LibInfoGeneratorBase):
name = None
if version:
+ prefix = self.get_lib_prefix(env)
suffix = self.get_lib_suffix(env)
- name = self.generate_versioned_lib_info(env, [libnode, version, suffix], **kw)
+ name = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw)
if not name:
name = os.path.basename(libnode.get_path())
@@ -566,7 +618,7 @@ def createSharedLibBuilder(env):
LibSymlinksAction ]
shared_lib = SCons.Builder.Builder(action = action_list,
emitter = "$SHLIBEMITTER",
- prefix = '$SHLIBPREFIX',
+ prefix = ShLibPrefixGenerator,
suffix = ShLibSuffixGenerator,
target_scanner = ProgramScanner,
src_suffix = '$SHOBJSUFFIX',
@@ -591,7 +643,7 @@ def createLoadableModuleBuilder(env):
LibSymlinksAction ]
ld_module = SCons.Builder.Builder(action = action_list,
emitter = "$LDMODULEEMITTER",
- prefix = '$LDMODULEPREFIX',
+ prefix = ShLibPrefixGenerator,
suffix = LdModSuffixGenerator,
target_scanner = ProgramScanner,
src_suffix = '$SHOBJSUFFIX',
diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py
index 59258b2..e05e85f 100644
--- a/src/engine/SCons/Tool/cyglink.py
+++ b/src/engine/SCons/Tool/cyglink.py
@@ -15,6 +15,7 @@ import SCons.Util
import SCons.Tool
import gnulink
+import link
def _lib_generator(target, source, env, for_signature, **kw):
try: cmd = kw['cmd']
@@ -135,13 +136,13 @@ def _versioned_lib_suffix(env, suffix, version):
print "_versioned_lib_suffix: return suffix= ", suffix
return suffix
-def _versioned_implib_name(env, libnode, version, suffix, **kw):
- import link
- generator = SCons.Tool.ImpLibSuffixGenerator
- libtype = kw['libtype']
- return link._versioned_lib_name(env, libnode, version, suffix, generator, implib_libtype=libtype)
+def _versioned_implib_name(env, libnode, version, prefix, suffix, **kw):
+ return link._versioned_lib_name(env, libnode, version, prefix, suffix,
+ SCons.Tool.ImpLibPrefixGenerator,
+ SCons.Tool.ImpLibSuffixGenerator,
+ implib_libtype=kw['libtype'])
-def _versioned_implib_symlinks(env, libnode, version, suffix, **kw):
+def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw):
"""Generate link names that should be created for a versioned shared lirbrary.
Returns a list in the form [ (link, linktarget), ... ]
"""
@@ -201,27 +202,24 @@ def generate(env):
# SHLIBVERSIONFLAGS and LDMODULEVERSIONFLAGS are same as in gnulink...
- env['GenerateVersionedShLibSuffix'] = _versioned_lib_suffix
- env['GenerateVersionedLdModSuffix'] = _versioned_lib_suffix
- env['GenerateVersionedImpLibSuffix'] = _versioned_lib_suffix
- env['GenerateVersionedShLibImpLibName'] = lambda *args: _versioned_implib_name(*args, libtype='ShLib')
- env['GenerateVersionedLdModImpLibName'] = lambda *args: _versioned_implib_name(*args, libtype='LdMod')
- env['GenerateVersionedShLibImpLibSymlinks'] = lambda *args: _versioned_implib_symlinks(*args, libtype='ShLib')
- env['GenerateVersionedLdModImpLibSymlinks'] = lambda *args: _versioned_implib_symlinks(*args, libtype='LdMod')
-
- def trydel(env, key):
- try: del env[key]
- except KeyError: pass
+ # LINKCALLBACKS are NOT inherited from gnulink
+ env['LINKCALLBACKS'] = {
+ 'VersionedShLibSuffix' : _versioned_lib_suffix,
+ 'VersionedLdModSuffix' : _versioned_lib_suffix,
+ 'VersionedImpLibSuffix' : _versioned_lib_suffix,
+ 'VersionedShLibName' : link._versioned_shlib_name,
+ 'VersionedLdModName' : link._versioned_ldmod_name,
+ 'VersionedShLibImpLibName' : lambda *args: _versioned_implib_name(*args, libtype='ShLib'),
+ 'VersionedLdModImpLibName' : lambda *args: _versioned_implib_name(*args, libtype='LdMod'),
+ 'VersionedShLibImpLibSymlinks' : lambda *args: _versioned_implib_symlinks(*args, libtype='ShLib'),
+ 'VersionedLdModImpLibSymlinks' : lambda *args: _versioned_implib_symlinks(*args, libtype='LdMod'),
+ }
# these variables were set by gnulink but are not used in cyglink
- trydel(env,'_SHLINKSONAME')
- trydel(env,'_LDMODULESONAME')
- trydel(env,'ShLibSonameGenerator')
- trydel(env,'LdModSonameGenerator')
- trydel(env,'GenerateVersionedShLibSymlinks')
- trydel(env,'GenerateVersionedLdModSymlinks')
- trydel(env,'GenerateVersionedShLibSoname')
- trydel(env,'GenerateVersionedLdModSoname')
+ try: del env['_SHLINKSONAME']
+ except KeyError: pass
+ try: del env['_LDMODULESONAME']
+ except KeyError: pass
def exists(env):
return gnulink.exists(env)
diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py
index 14007af..e5e8818 100644
--- a/src/engine/SCons/Tool/gnulink.py
+++ b/src/engine/SCons/Tool/gnulink.py
@@ -53,12 +53,12 @@ def _versioned_lib_suffix(env, suffix, version):
print "_versioned_lib_suffix: return suffix=%r" % suffix
return suffix
-def _versioned_lib_soname(env, libnode, version, suffix, name_generator):
+def _versioned_lib_soname(env, libnode, version, prefix, suffix, name_func):
"""For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so.X'"""
Verbose = False
if Verbose:
print "_versioned_lib_soname: version=%r" % version
- name = name_generator(env, libnode)
+ name = name_func(env, libnode, version, prefix, suffix)
if Verbose:
print "_versioned_lib_soname: name=%r" % name
major = version.split('.')[0]
@@ -67,22 +67,20 @@ def _versioned_lib_soname(env, libnode, version, suffix, name_generator):
print "_versioned_lib_soname: soname=%r" % soname
return soname
-def _versioned_shlib_soname(env, libnode, version, suffix):
- generator = SCons.Tool.ShLibNameGenerator
- return _versioned_lib_soname(env, libnode, version, suffix, generator)
+def _versioned_shlib_soname(env, libnode, version, prefix, suffix):
+ return _versioned_lib_soname(env, libnode, version, prefix, suffix, link._versioned_shlib_name)
-def _versioned_ldmod_soname(env, libnode, version, suffix):
- generator = SCons.Tool.LdModNameGenerator
- return _versioned_lib_soname(env, libnode, version, suffix, generator)
+def _versioned_ldmod_soname(env, libnode, version, prefix, suffix):
+ return _versioned_lib_soname(env, libnode, version, prefix, suffix, link._versioned_ldmod_name)
-def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator):
+def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func):
"""Generate link names that should be created for a versioned shared lirbrary.
Returns a dictionary in the form { linkname : linktarget }
"""
Verbose = False
if Verbose:
- print "_versioned_lib_symlinks: str(libnode)=%r" % str(libnode)
+ print "_versioned_lib_symlinks: libnode=%r" % libnode.get_path()
print "_versioned_lib_symlinks: version=%r" % version
if sys.platform.startswith('openbsd'):
@@ -96,11 +94,11 @@ def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, sonam
if Verbose:
print "_versioned_lib_symlinks: linkdir=%r" % linkdir.get_path()
- name = name_generator(env, libnode)
+ name = name_func(env, libnode, version, prefix, suffix)
if Verbose:
print "_versioned_lib_symlinks: name=%r" % name
- soname = soname_generator(env, libnode)
+ soname = soname_func(env, libnode, version, prefix, suffix)
link0 = env.fs.File(soname, linkdir)
link1 = env.fs.File(name, linkdir)
@@ -112,15 +110,15 @@ def _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, sonam
return symlinks
-def _versioned_shlib_symlinks(env, libnode, version, suffix):
- name_generator = SCons.Tool.ShLibNameGenerator
- soname_generator = SCons.Tool.ShLibSonameGenerator
- return _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator)
+def _versioned_shlib_symlinks(env, libnode, version, prefix, suffix):
+ nf = link._versioned_shlib_name
+ sf = _versioned_shlib_soname
+ return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf)
-def _versioned_ldmod_symlinks(env, libnode, version, suffix):
- name_generator = SCons.Tool.LdModNameGenerator
- soname_generator = SCons.Tool.LdModSonameGenerator
- return _versioned_lib_symlinks(env, libnode, version, suffix, name_generator, soname_generator)
+def _versioned_ldmod_symlinks(env, libnode, version, prefix, suffix):
+ nf = link._versioned_ldmod_name
+ sf = _versioned_ldmod_soname
+ return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, nf, sf)
def generate(env):
"""Add Builders and construction variables for gnulink to an Environment."""
@@ -155,14 +153,16 @@ def generate(env):
env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator
env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator
- env['GenerateVersionedShLibSuffix'] = _versioned_lib_suffix
- env['GenerateVersionedLdModSuffix'] = _versioned_lib_suffix
- env['GenerateVersionedShLibSymlinks'] = _versioned_shlib_symlinks
- env['GenerateVersionedLdModSymlinks'] = _versioned_ldmod_symlinks
- env['GenerateVersionedShLibName'] = link._versioned_shlib_name
- env['GenerateVersionedLdModName'] = link._versioned_ldmod_name
- env['GenerateVersionedShLibSoname'] = _versioned_shlib_soname
- env['GenerateVersionedLdModSoname'] = _versioned_shlib_soname
+ env['LINKCALLBACKS'] = {
+ 'VersionedShLibSuffix' : _versioned_lib_suffix,
+ 'VersionedLdModSuffix' : _versioned_lib_suffix,
+ 'VersionedShLibSymlinks' : _versioned_shlib_symlinks,
+ 'VersionedLdModSymlinks' : _versioned_ldmod_symlinks,
+ 'VersionedShLibName' : link._versioned_shlib_name,
+ 'VersionedLdModName' : link._versioned_ldmod_name,
+ 'VersionedShLibSoname' : _versioned_shlib_soname,
+ 'VersionedLdModSoname' : _versioned_shlib_soname,
+ }
def exists(env):
# TODO: sync with link.smart_link() to choose a linker
diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py
index 33e50d9..d52a9e5 100644
--- a/src/engine/SCons/Tool/link.py
+++ b/src/engine/SCons/Tool/link.py
@@ -76,7 +76,7 @@ def smart_link(source, target, env, for_signature):
def _lib_emitter(target, source, env, **kw):
Verbose = False
if Verbose:
- print "_lib_emitter: str(target[0])=%r" % str(target[0])
+ print "_lib_emitter: target[0]=%r" % target[0].get_path()
for tgt in target:
tgt.attributes.shared = 1
@@ -103,35 +103,44 @@ def ldmod_emitter(target, source, env):
return _lib_emitter(target, source, env, symlink_generator = SCons.Tool.LdModSymlinkGenerator)
# This is generic enough to be included here...
-def _versioned_lib_name(env, libnode, version, suffix, suffix_generator, **kw):
+def _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw):
"""For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so'"""
Verbose = False
if Verbose:
+ print "_versioned_lib_name: libnode=%r" % libnode.get_path()
print "_versioned_lib_name: version=%r" % version
+ print "_versioned_lib_name: prefix=%r" % prefix
+ print "_versioned_lib_name: suffix=%r" % suffix
+ print "_versioned_lib_name: suffix_generator=%r" % suffix_generator
- versioned_name = os.path.basename(str(libnode))
+ versioned_name = os.path.basename(libnode.get_path())
if Verbose:
print "_versioned_lib_name: versioned_name=%r" % versioned_name
- if Verbose:
- print "_versioned_lib_name: suffix=%r" % suffix
-
+ versioned_prefix = prefix_generator(env, **kw)
versioned_suffix = suffix_generator(env, **kw)
+ if Verbose:
+ print "_versioned_lib_name: versioned_prefix=%r" % versioned_prefix
+ print "_versioned_lib_name: versioned_suffix=%r" % versioned_suffix
+ versioned_prefix_re = '^' + re.escape(versioned_prefix)
versioned_suffix_re = re.escape(versioned_suffix) + '$'
- name = re.sub(versioned_suffix_re, suffix, versioned_name)
+ name = re.sub(versioned_prefix_re, prefix, versioned_name)
+ name = re.sub(versioned_suffix_re, suffix, name)
if Verbose:
print "_versioned_lib_name: name=%r" % name
return name
-def _versioned_shlib_name(env, libnode, version, suffix, **kw):
- generator = SCons.Tool.ShLibSuffixGenerator
- return _versioned_lib_name(env, libnode, version, suffix, generator, **kw)
+def _versioned_shlib_name(env, libnode, version, prefix, suffix, **kw):
+ pg = SCons.Tool.ShLibPrefixGenerator
+ sg = SCons.Tool.ShLibSuffixGenerator
+ return _versioned_lib_name(env, libnode, version, prefix, suffix, pg, sg, **kw)
-def _versioned_ldmod_name(env, libnode, version, suffix, **kw):
- generator = SCons.Tool.LdModSuffixGenerator
- return _versioned_lib_name(env, libnode, version, suffix, generator, **kw)
+def _versioned_ldmod_name(env, libnode, version, prefix, suffix, **kw):
+ pg = SCons.Tool.LdModPrefixGenerator
+ sg = SCons.Tool.LdModSuffixGenerator
+ return _versioned_lib_name(env, libnode, version, prefix, suffix, pg, sg, **kw)
def generate(env):