[Scons-dev] Plans for 2013
Eric S. Raymond
esr at thyrsus.com
Mon Feb 4 14:47:32 EST 2013
While you're making plans for 2013, would somebody please pay
attention to the continuing lack of out-of-the-box support for
versioned shared libraries?
I know of at least two projects that have rejected moving to SCons for this
reason. It is quite a bit more important in the real world than
(for example) D support.
Here, once again, is my custom builder code solving this problem. If
someone on the core teanm is willing to integrate this properly, I'll write the
documentation for it.
# Cope with scons's failure to set SONAME in its builtins.
# Inspired by Richard Levitte's (slightly buggy) code at
# http://markmail.org/message/spttz3o4xrsftofr
def VersionedSharedLibrary(env, libname, version, lib_objs=[], parse_flags=[]):
platform = env.subst('$PLATFORM')
shlib_pre_action = None
shlib_suffix = env.subst('$SHLIBSUFFIX')
shlib_post_action = None
shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS'))
if platform == 'posix':
ilib_suffix = shlib_suffix + '.' + version
(major, age, revision) = version.split(".")
soname = "lib" + libname + shlib_suffix + "." + major
shlink_flags += [ '-Wl,-Bsymbolic', '-Wl,-soname=%s' % soname ]
elif platform == 'cygwin':
ilib_suffix = shlib_suffix
shlink_flags += [ '-Wl,-Bsymbolic',
'-Wl,--out-implib,${TARGET.base}.a' ]
elif platform == 'darwin':
ilib_suffix = '.' + version + shlib_suffix
shlink_flags += [ '-current_version', '%s' % version,
'-compatibility_version', '%s' % version,
'-undefined', 'dynamic_lookup' ]
ilib = env.SharedLibrary(libname,lib_objs,
SHLIBSUFFIX=ilib_suffix,
SHLINKFLAGS=shlink_flags, parse_flags=parse_flags)
if platform == 'darwin':
if version.count(".") != 2:
# We need a library name in libfoo.x.y.z.dylib form to proceed
raise ValueError
lib = 'lib' + libname + '.' + version + '.dylib'
lib_no_ver = 'lib' + libname + '.dylib'
# Link libfoo.x.y.z.dylib to libfoo.dylib
env.AddPostAction(ilib, 'rm -f %s; ln -s %s %s' % (
lib_no_ver, lib, lib_no_ver))
env.Clean(lib, lib_no_ver)
elif platform == 'posix':
if version.count(".") != 2:
# We need a library name in libfoo.so.x.y.z form to proceed
raise ValueError
lib = "lib" + libname + ".so." + version
suffix_re = '%s\\.[0-9\\.]*$' % re.escape(shlib_suffix)
# For libfoo.so.x.y.z, links libfoo.so libfoo.so.x.y libfoo.so.x
major_name = shlib_suffix + "." + lib.split(".")[2]
minor_name = major_name + "." + lib.split(".")[3]
for linksuffix in [shlib_suffix, major_name, minor_name]:
linkname = re.sub(suffix_re, linksuffix, lib)
env.AddPostAction(ilib, 'rm -f %s; ln -s %s %s' % (
linkname, lib, linkname))
env.Clean(lib, linkname)
return ilib
def VersionedSharedLibraryInstall(env, destination, libs):
platform = env.subst('$PLATFORM')
shlib_suffix = env.subst('$SHLIBSUFFIX')
ilibs = env.Install(destination, libs)
if platform == 'posix':
suffix_re = '%s\\.[0-9\\.]*$' % re.escape(shlib_suffix)
for lib in map(str, libs):
if lib.count(".") != 4:
# We need a library name in libfoo.so.x.y.z form to proceed
raise ValueError
# For libfoo.so.x.y.z, links libfoo.so libfoo.so.x.y libfoo.so.x
major_name = shlib_suffix + "." + lib.split(".")[2]
minor_name = major_name + "." + lib.split(".")[3]
for linksuffix in [shlib_suffix, major_name, minor_name]:
linkname = re.sub(suffix_re, linksuffix, lib)
env.AddPostAction(ilibs, 'cd %s; rm -f %s; ln -s %s %s' % (destination, linkname, lib, linkname))
env.Clean(lib, linkname)
return ilibs
if not env["shared"]:
def Library(env, target, sources, version, parse_flags=[]):
return env.StaticLibrary(target, sources, parse_flags=parse_flags)
LibraryInstall = lambda env, libdir, sources: env.Install(libdir, sources)
else:
def Library(env, target, sources, version, parse_flags=[]):
return VersionedSharedLibrary(env=env,
libname=target,
version=version,
lib_objs=sources,
parse_flags=parse_flags)
LibraryInstall = lambda env, libdir, sources: \
VersionedSharedLibraryInstall(env, libdir, sources)
# Klugery to handle sonames ends
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
More information about the Scons-dev
mailing list