summaryrefslogtreecommitdiff
path: root/lib/spack/spack/build_environment.py
diff options
context:
space:
mode:
authorMichael Kuhn <suraia@ikkoku.de>2017-11-07 01:21:46 +0100
committerChristoph Junghans <christoph.junghans@gmail.com>2017-11-06 17:21:46 -0700
commitca73103dac47dc2cdfff51c146205611a72bb401 (patch)
treebbe0dc903bd44ca26384b7fe89a79afbbe970d65 /lib/spack/spack/build_environment.py
parent54bb28ccb080c396f7947c6bf294b67f55b8b629 (diff)
downloadspack-ca73103dac47dc2cdfff51c146205611a72bb401.tar.gz
spack-ca73103dac47dc2cdfff51c146205611a72bb401.tar.bz2
spack-ca73103dac47dc2cdfff51c146205611a72bb401.tar.xz
spack-ca73103dac47dc2cdfff51c146205611a72bb401.zip
Introduce static_to_shared_library function (#6092)
The static_to_shared_library function takes an existing static library and produces a shared library based on it.
Diffstat (limited to 'lib/spack/spack/build_environment.py')
-rw-r--r--lib/spack/spack/build_environment.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 0a9bd22de7..f1cf0d5049 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -373,6 +373,104 @@ def set_module_variables_for_package(pkg, module):
# Platform-specific library suffix.
m.dso_suffix = dso_suffix
+ def static_to_shared_library(static_lib, shared_lib=None, **kwargs):
+ compiler_path = kwargs.get('compiler', m.spack_cc)
+ compiler = Executable(compiler_path)
+
+ return _static_to_shared_library(pkg.spec.architecture, compiler,
+ static_lib, shared_lib, **kwargs)
+
+ m.static_to_shared_library = static_to_shared_library
+
+
+def _static_to_shared_library(arch, compiler, static_lib, shared_lib=None,
+ **kwargs):
+ """
+ Converts a static library to a shared library. The static library has to
+ be built with PIC for the conversion to work.
+
+ Parameters:
+ static_lib (str): Path to the static library.
+ shared_lib (str): Path to the shared library. Default is to derive
+ from the static library's path.
+
+ Keyword arguments:
+ compiler (str): Path to the compiler. Default is spack_cc.
+ compiler_output: Where to print compiler output to.
+ arguments (str list): Additional arguments for the compiler.
+ version (str): Library version. Default is unspecified.
+ compat_version (str): Library compatibility version. Default is
+ version.
+ """
+ compiler_output = kwargs.get('compiler_output', None)
+ arguments = kwargs.get('arguments', [])
+ version = kwargs.get('version', None)
+ compat_version = kwargs.get('compat_version', version)
+
+ if not shared_lib:
+ shared_lib = '{0}.{1}'.format(os.path.splitext(static_lib)[0],
+ dso_suffix)
+
+ compiler_args = []
+
+ # TODO: Compiler arguments should not be hardcoded but provided by
+ # the different compiler classes.
+ if 'linux' in arch:
+ soname = os.path.basename(shared_lib)
+
+ if compat_version:
+ soname += '.{0}'.format(compat_version)
+
+ compiler_args = [
+ '-shared',
+ '-Wl,-soname,{0}'.format(soname),
+ '-Wl,--whole-archive',
+ static_lib,
+ '-Wl,--no-whole-archive'
+ ]
+ elif 'darwin' in arch:
+ install_name = shared_lib
+
+ if compat_version:
+ install_name += '.{0}'.format(compat_version)
+
+ compiler_args = [
+ '-dynamiclib',
+ '-install_name {0}'.format(install_name),
+ '-Wl,-force_load,{0}'.format(static_lib)
+ ]
+
+ if compat_version:
+ compiler_args.append('-compatibility_version {0}'.format(
+ compat_version))
+
+ if version:
+ compiler_args.append('-current_version {0}'.format(version))
+
+ if len(arguments) > 0:
+ compiler_args.extend(arguments)
+
+ shared_lib_base = shared_lib
+
+ if version:
+ shared_lib += '.{0}'.format(version)
+ elif compat_version:
+ shared_lib += '.{0}'.format(compat_version)
+
+ compiler_args.extend(['-o', shared_lib])
+
+ # Create symlinks for version and compat_version
+ shared_lib_link = os.path.basename(shared_lib)
+
+ if version or compat_version:
+ os.symlink(shared_lib_link, shared_lib_base)
+
+ if compat_version and compat_version != version:
+ os.symlink(shared_lib_link, '{0}.{1}'.format(shared_lib_base,
+ compat_version))
+
+ return compiler(*compiler_args, output=compiler_output)
+
def get_rpath_deps(pkg):
"""Return immediate or transitive RPATHs depending on the package."""