Merge pull request #2618 from mesonbuild/osxlinkerfixes
Fix many things have have been slightly broken in OSX
This commit is contained in:
commit
554b484468
|
@ -330,6 +330,8 @@ class Backend:
|
||||||
link_deps = target.get_all_link_deps()
|
link_deps = target.get_all_link_deps()
|
||||||
result = []
|
result = []
|
||||||
for ld in link_deps:
|
for ld in link_deps:
|
||||||
|
if ld is target:
|
||||||
|
continue
|
||||||
prospective = self.get_target_dir(ld)
|
prospective = self.get_target_dir(ld)
|
||||||
if prospective not in result:
|
if prospective not in result:
|
||||||
result.append(prospective)
|
result.append(prospective)
|
||||||
|
|
|
@ -18,6 +18,7 @@ from .. import mlog
|
||||||
from .. import coredata
|
from .. import coredata
|
||||||
from ..mesonlib import EnvironmentException, version_compare, Popen_safe, listify
|
from ..mesonlib import EnvironmentException, version_compare, Popen_safe, listify
|
||||||
from ..mesonlib import for_windows, for_darwin, for_cygwin
|
from ..mesonlib import for_windows, for_darwin, for_cygwin
|
||||||
|
from . import compilers
|
||||||
|
|
||||||
from .compilers import (
|
from .compilers import (
|
||||||
GCC_MINGW,
|
GCC_MINGW,
|
||||||
|
@ -89,6 +90,8 @@ class CCompiler(Compiler):
|
||||||
|
|
||||||
# The default behavior is this, override in MSVC
|
# The default behavior is this, override in MSVC
|
||||||
def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
|
def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
|
||||||
|
if self.id == 'clang' and self.clang_type == compilers.CLANG_OSX:
|
||||||
|
return self.build_osx_rpath_args(build_dir, rpath_paths, build_rpath)
|
||||||
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
|
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
|
||||||
|
|
||||||
def get_dependency_gen_args(self, outtarget, outfile):
|
def get_dependency_gen_args(self, outtarget, outfile):
|
||||||
|
@ -811,6 +814,12 @@ class ClangCCompiler(ClangCompiler, CCompiler):
|
||||||
def get_option_link_args(self, options):
|
def get_option_link_args(self, options):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def get_linker_always_args(self):
|
||||||
|
basic = super().get_linker_always_args()
|
||||||
|
if self.clang_type == compilers.CLANG_OSX:
|
||||||
|
return basic + ['-Wl,-headerpad_max_install_names']
|
||||||
|
return basic
|
||||||
|
|
||||||
|
|
||||||
class GnuCCompiler(GnuCompiler, CCompiler):
|
class GnuCCompiler(GnuCompiler, CCompiler):
|
||||||
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None):
|
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None):
|
||||||
|
|
|
@ -817,6 +817,16 @@ class Compiler:
|
||||||
def get_instruction_set_args(self, instruction_set):
|
def get_instruction_set_args(self, instruction_set):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def build_osx_rpath_args(self, build_dir, rpath_paths, build_rpath):
|
||||||
|
if not rpath_paths and not build_rpath:
|
||||||
|
return []
|
||||||
|
# On OSX, rpaths must be absolute.
|
||||||
|
abs_rpaths = [os.path.join(build_dir, p) for p in rpath_paths]
|
||||||
|
if build_rpath != '':
|
||||||
|
abs_rpaths.append(build_rpath)
|
||||||
|
args = ['-Wl,-rpath,' + rp for rp in abs_rpaths]
|
||||||
|
return args
|
||||||
|
|
||||||
def build_unix_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
|
def build_unix_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
|
||||||
if not rpath_paths and not install_rpath and not build_rpath:
|
if not rpath_paths and not install_rpath and not build_rpath:
|
||||||
return []
|
return []
|
||||||
|
@ -879,7 +889,11 @@ def get_gcc_soname_args(gcc_type, prefix, shlib_name, suffix, path, soversion, i
|
||||||
elif gcc_type == GCC_OSX:
|
elif gcc_type == GCC_OSX:
|
||||||
if is_shared_module:
|
if is_shared_module:
|
||||||
return []
|
return []
|
||||||
return ['-install_name', os.path.join(path, 'lib' + shlib_name + '.dylib')]
|
install_name = prefix + shlib_name
|
||||||
|
if soversion is not None:
|
||||||
|
install_name += '.' + soversion
|
||||||
|
install_name += '.dylib'
|
||||||
|
return ['-install_name', os.path.join('@rpath', install_name)]
|
||||||
else:
|
else:
|
||||||
raise RuntimeError('Not implemented yet.')
|
raise RuntimeError('Not implemented yet.')
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ def get_dynamic_section_entry(fname, entry):
|
||||||
m = pattern.search(line)
|
m = pattern.search(line)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
return m.group(1)
|
return m.group(1)
|
||||||
raise RuntimeError('Could not determine {}:\n\n'.format(entry) + raw_out)
|
return None # The file did not contain the specified entry.
|
||||||
|
|
||||||
def get_soname(fname):
|
def get_soname(fname):
|
||||||
return get_dynamic_section_entry(fname, 'soname')
|
return get_dynamic_section_entry(fname, 'soname')
|
||||||
|
@ -1360,12 +1360,15 @@ int main(int argc, char **argv) {
|
||||||
testdir = os.path.join(self.common_test_dir, '46 library chain')
|
testdir = os.path.join(self.common_test_dir, '46 library chain')
|
||||||
self.init(testdir)
|
self.init(testdir)
|
||||||
self.build()
|
self.build()
|
||||||
for each in ('prog', 'subdir/liblib1.so', 'subdir/subdir2/liblib2.so',
|
for each in ('prog', 'subdir/liblib1.so', ):
|
||||||
'subdir/subdir3/liblib3.so'):
|
|
||||||
rpath = get_rpath(os.path.join(self.builddir, each))
|
rpath = get_rpath(os.path.join(self.builddir, each))
|
||||||
self.assertTrue(rpath)
|
self.assertTrue(rpath)
|
||||||
for path in rpath.split(':'):
|
for path in rpath.split(':'):
|
||||||
self.assertTrue(path.startswith('$ORIGIN'), msg=(each, path))
|
self.assertTrue(path.startswith('$ORIGIN'), msg=(each, path))
|
||||||
|
# These two don't link to anything else, so they do not need an rpath entry.
|
||||||
|
for each in ('subdir/subdir2/liblib2.so', 'subdir/subdir3/liblib3.so'):
|
||||||
|
rpath = get_rpath(os.path.join(self.builddir, each))
|
||||||
|
self.assertTrue(rpath is None)
|
||||||
|
|
||||||
def test_dash_d_dedup(self):
|
def test_dash_d_dedup(self):
|
||||||
testdir = os.path.join(self.unit_test_dir, '10 d dedup')
|
testdir = os.path.join(self.unit_test_dir, '10 d dedup')
|
||||||
|
|
|
@ -4,23 +4,26 @@ project(dylibversion C)
|
||||||
# This file is here for debugging purposes to easily compare how
|
# This file is here for debugging purposes to easily compare how
|
||||||
# CMake does it.
|
# CMake does it.
|
||||||
|
|
||||||
|
# libnoversion.dylib
|
||||||
add_library(noversion SHARED lib.c)
|
add_library(noversion SHARED lib.c)
|
||||||
|
|
||||||
# libonlysoversion.dylib -> libonlysoversion.5.dylib
|
# libonlysoversion.dylib -> libonlysoversion.5.dylib
|
||||||
# libonlyversion.1.4.5.dylib
|
# libonlyversion.1.4.5.dylib
|
||||||
|
# -current_version 1.4.5
|
||||||
|
|
||||||
add_library(onlyversion SHARED lib.c)
|
add_library(onlyversion SHARED lib.c)
|
||||||
set_target_properties(onlyversion PROPERTIES VERSION 1.4.5)
|
set_target_properties(onlyversion PROPERTIES VERSION 1.4.5)
|
||||||
|
|
||||||
# libnoversion.dylib
|
# libonlysoversion.6.dylib
|
||||||
# libonlysoversion.5.dylib
|
# -compatibility_version 6.0.0
|
||||||
|
|
||||||
add_library(onlysoversion SHARED lib.c)
|
add_library(onlysoversion SHARED lib.c)
|
||||||
set_target_properties(onlysoversion PROPERTIES SOVERSION 5)
|
set_target_properties(onlysoversion PROPERTIES SOVERSION 6)
|
||||||
|
|
||||||
# libsome.1.4.5.dylib
|
# libsome.1.4.5.dylib
|
||||||
# libsome.5.dylib -> libsome.1.4.5.dylib
|
# libsome.6.dylib -> libsome.1.4.5.dylib
|
||||||
# libsome.dylib -> libsome.5.dylib
|
# libsome.dylib -> libsome.6.dylib
|
||||||
|
# -current_version 1.4.5 -compatibility_version 5.0.0
|
||||||
|
|
||||||
add_library(some SHARED lib.c)
|
add_library(some SHARED lib.c)
|
||||||
set_target_properties(some PROPERTIES VERSION 1.4.5 SOVERSION 5)
|
set_target_properties(some PROPERTIES VERSION 1.4.5 SOVERSION 6)
|
||||||
|
|
|
@ -29,15 +29,19 @@ out = custom_target('library-dependency-hack',
|
||||||
# Manually test if the linker can find the above libraries
|
# Manually test if the linker can find the above libraries
|
||||||
# i.e., whether they were generated with the right naming scheme
|
# i.e., whether they were generated with the right naming scheme
|
||||||
test('manually linked 1', executable('manuallink1', out,
|
test('manually linked 1', executable('manuallink1', out,
|
||||||
link_args : ['-L.', '-lsome']))
|
link_args : ['-L.', '-lsome'],
|
||||||
|
build_rpath : meson.current_build_dir()))
|
||||||
|
|
||||||
test('manually linked 2', executable('manuallink2', out,
|
test('manually linked 2', executable('manuallink2', out,
|
||||||
link_args : ['-L.', '-lnoversion']))
|
link_args : ['-L.', '-lnoversion'],
|
||||||
|
build_rpath : meson.current_build_dir()))
|
||||||
|
|
||||||
test('manually linked 3', executable('manuallink3', out,
|
test('manually linked 3', executable('manuallink3', out,
|
||||||
link_args : ['-L.', '-lonlyversion']))
|
link_args : ['-L.', '-lonlyversion'],
|
||||||
|
build_rpath : meson.current_build_dir()))
|
||||||
|
|
||||||
test('manually linked 4', executable('manuallink4', out,
|
test('manually linked 4', executable('manuallink4', out,
|
||||||
link_args : ['-L.', '-lonlysoversion']))
|
link_args : ['-L.', '-lonlysoversion'],
|
||||||
|
build_rpath : meson.current_build_dir()))
|
||||||
|
|
||||||
shared_module('module', 'lib.c', install : true)
|
shared_module('module', 'lib.c', install : true)
|
||||||
|
|
Loading…
Reference in New Issue