diff options
author | Michael Kuhn <suraia@ikkoku.de> | 2017-11-07 01:21:46 +0100 |
---|---|---|
committer | Christoph Junghans <christoph.junghans@gmail.com> | 2017-11-06 17:21:46 -0700 |
commit | ca73103dac47dc2cdfff51c146205611a72bb401 (patch) | |
tree | bbe0dc903bd44ca26384b7fe89a79afbbe970d65 /lib/spack/spack/build_environment.py | |
parent | 54bb28ccb080c396f7947c6bf294b67f55b8b629 (diff) | |
download | spack-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.py | 98 |
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.""" |