Merge pull request #2618 from mesonbuild/osxlinkerfixes

Fix many things have have been slightly broken in OSX
pull/2696/merge
Jussi Pakkanen 7 years ago committed by GitHub
commit 554b484468
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      mesonbuild/backend/backends.py
  2. 9
      mesonbuild/compilers/c.py
  3. 16
      mesonbuild/compilers/compilers.py
  4. 9
      run_unittests.py
  5. 15
      test cases/osx/2 library versions/CMakeLists.txt
  6. 12
      test cases/osx/2 library versions/meson.build

@ -330,6 +330,8 @@ class Backend:
link_deps = target.get_all_link_deps()
result = []
for ld in link_deps:
if ld is target:
continue
prospective = self.get_target_dir(ld)
if prospective not in result:
result.append(prospective)

@ -18,6 +18,7 @@ from .. import mlog
from .. import coredata
from ..mesonlib import EnvironmentException, version_compare, Popen_safe, listify
from ..mesonlib import for_windows, for_darwin, for_cygwin
from . import compilers
from .compilers import (
GCC_MINGW,
@ -89,6 +90,8 @@ class CCompiler(Compiler):
# The default behavior is this, override in MSVC
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)
def get_dependency_gen_args(self, outtarget, outfile):
@ -811,6 +814,12 @@ class ClangCCompiler(ClangCompiler, CCompiler):
def get_option_link_args(self, options):
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):
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):
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):
if not rpath_paths and not install_rpath and not build_rpath:
return []
@ -879,7 +889,11 @@ def get_gcc_soname_args(gcc_type, prefix, shlib_name, suffix, path, soversion, i
elif gcc_type == GCC_OSX:
if is_shared_module:
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:
raise RuntimeError('Not implemented yet.')

@ -58,7 +58,7 @@ def get_dynamic_section_entry(fname, entry):
m = pattern.search(line)
if m is not None:
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):
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')
self.init(testdir)
self.build()
for each in ('prog', 'subdir/liblib1.so', 'subdir/subdir2/liblib2.so',
'subdir/subdir3/liblib3.so'):
for each in ('prog', 'subdir/liblib1.so', ):
rpath = get_rpath(os.path.join(self.builddir, each))
self.assertTrue(rpath)
for path in rpath.split(':'):
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):
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
# CMake does it.
# libnoversion.dylib
add_library(noversion SHARED lib.c)
# libonlysoversion.dylib -> libonlysoversion.5.dylib
# libonlyversion.1.4.5.dylib
# -current_version 1.4.5
add_library(onlyversion SHARED lib.c)
set_target_properties(onlyversion PROPERTIES VERSION 1.4.5)
# libnoversion.dylib
# libonlysoversion.5.dylib
# libonlysoversion.6.dylib
# -compatibility_version 6.0.0
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.5.dylib -> libsome.1.4.5.dylib
# libsome.dylib -> libsome.5.dylib
# libsome.6.dylib -> libsome.1.4.5.dylib
# libsome.dylib -> libsome.6.dylib
# -current_version 1.4.5 -compatibility_version 5.0.0
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
# i.e., whether they were generated with the right naming scheme
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,
link_args : ['-L.', '-lnoversion']))
link_args : ['-L.', '-lnoversion'],
build_rpath : meson.current_build_dir()))
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,
link_args : ['-L.', '-lonlysoversion']))
link_args : ['-L.', '-lonlysoversion'],
build_rpath : meson.current_build_dir()))
shared_module('module', 'lib.c', install : true)

Loading…
Cancel
Save