Add a new option for building with Apple bitcode support

Normally, people would just pass -fembed-bitcode in CFLAGS, but this
conflicts with -Wl,-dead_strip_dylibs and -bundle, so we need it as
an option so that those can be quietly disabled.
pull/3701/head
Nirbheek Chauhan 7 years ago committed by Nirbheek Chauhan
parent 68001193d3
commit 3e1a610702
  1. 3
      mesonbuild/backend/ninjabackend.py
  2. 3
      mesonbuild/backend/vs2010backend.py
  3. 49
      mesonbuild/compilers/compilers.py
  4. 43
      run_unittests.py

@ -2408,7 +2408,8 @@ rule FORTRAN_DEP_HACK%s
commands += linker.gen_import_library_args(os.path.join(self.get_target_dir(target), target.import_filename))
elif isinstance(target, build.SharedLibrary):
if isinstance(target, build.SharedModule):
commands += linker.get_std_shared_module_link_args()
options = self.environment.coredata.base_options
commands += linker.get_std_shared_module_link_args(options)
else:
commands += linker.get_std_shared_lib_link_args()
# All shared libraries are PIC

@ -950,7 +950,8 @@ class Vs2010Backend(backends.Backend):
self.generate_debug_information(link)
if not isinstance(target, build.StaticLibrary):
if isinstance(target, build.SharedModule):
extra_link_args += compiler.get_std_shared_module_link_args()
options = self.environment.coredata.base_options
extra_link_args += compiler.get_std_shared_module_link_args(options)
# Add link args added using add_project_link_arguments()
extra_link_args += self.build.get_project_link_args(compiler, target.subproject)
# Add link args added using add_global_link_arguments()

@ -249,6 +249,9 @@ base_options = {'b_pch': coredata.UserBooleanOption('b_pch', 'Use precompiled he
'b_staticpic': coredata.UserBooleanOption('b_staticpic',
'Build static libraries as position independent',
True),
'b_bitcode': coredata.UserBooleanOption('b_bitcode',
'Generate and embed bitcode (only macOS and iOS)',
False),
}
gnulike_instruction_set_args = {'mmx': ['-mmmx'],
@ -287,7 +290,6 @@ vs64_instruction_set_args = {'mmx': ['/arch:AVX'],
'neon': None,
}
def sanitizer_compile_args(value):
if value == 'none':
return []
@ -302,6 +304,14 @@ def sanitizer_link_args(value):
args = ['-fsanitize=' + value]
return args
def option_enabled(boptions, options, option):
try:
if option not in boptions:
return False
return options[option].value
except KeyError:
return False
def get_base_compile_args(options, compiler):
args = []
# FIXME, gcc/clang specific.
@ -338,6 +348,9 @@ def get_base_compile_args(options, compiler):
args += ['-DNDEBUG']
except KeyError:
pass
# This does not need a try...except
if option_enabled(compiler.base_options, options, 'b_bitcode'):
args.append('-fembed-bitcode')
return args
def get_base_link_args(options, linker, is_shared_module):
@ -360,21 +373,23 @@ def get_base_link_args(options, linker, is_shared_module):
args.append('-fprofile-use')
except KeyError:
pass
try:
if not is_shared_module and 'b_lundef' in linker.base_options and options['b_lundef'].value:
args.append('-Wl,--no-undefined')
except KeyError:
pass
try:
if 'b_asneeded' in linker.base_options and options['b_asneeded'].value:
args.append(linker.get_asneeded_args())
except KeyError:
pass
try:
if options['b_coverage'].value:
args += linker.get_coverage_link_args()
except KeyError:
pass
# These do not need a try...except
if not is_shared_module and option_enabled(linker.base_options, options, 'b_lundef'):
args.append('-Wl,--no-undefined')
as_needed = option_enabled(linker.base_options, options, 'b_asneeded')
bitcode = option_enabled(linker.base_options, options, 'b_bitcode')
# Shared modules cannot be built with bitcode_bundle because
# -bitcode_bundle is incompatible with -undefined and -bundle
if bitcode and not is_shared_module:
args.append('-Wl,-bitcode_bundle')
elif as_needed:
# -Wl,-dead_strip_dylibs is incompatible with bitcode
args.append(linker.get_asneeded_args())
return args
class CrossNoRunException(MesonException):
@ -862,7 +877,7 @@ class Compiler:
def get_std_shared_lib_link_args(self):
return []
def get_std_shared_module_link_args(self):
def get_std_shared_module_link_args(self, options):
return self.get_std_shared_lib_link_args()
def get_link_whole_for(self, args):
@ -1071,7 +1086,9 @@ class GnuCompiler:
self.defines = defines or {}
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
'b_colorout', 'b_ndebug', 'b_staticpic']
if self.gcc_type != GCC_OSX:
if self.gcc_type == GCC_OSX:
self.base_options.append('b_bitcode')
else:
self.base_options.append('b_lundef')
self.base_options.append('b_asneeded')
# All GCC backends can do assembly
@ -1201,7 +1218,9 @@ class ClangCompiler:
self.clang_type = clang_type
self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
'b_ndebug', 'b_staticpic', 'b_colorout']
if self.clang_type != CLANG_OSX:
if self.clang_type == CLANG_OSX:
self.base_options.append('b_bitcode')
else:
self.base_options.append('b_lundef')
self.base_options.append('b_asneeded')
# All Clang backends can do assembly and LLVM IR
@ -1270,7 +1289,7 @@ class ClangCompiler:
extra_args.append('-Wl,-no_weak_imports')
return super().has_function(funcname, prefix, env, extra_args, dependencies)
def get_std_shared_module_link_args(self):
def get_std_shared_module_link_args(self, options):
if self.clang_type == CLANG_OSX:
return ['-bundle', '-Wl,-undefined,dynamic_lookup']
return ['-shared']

@ -3195,6 +3195,49 @@ endian = 'little'
deps.append(b'-lintl')
self.assertEqual(set(deps), set(stdo.split()))
def test_apple_bitcode(self):
'''
Test that -fembed-bitcode is correctly added while compiling and
-bitcode_bundle is added while linking when b_bitcode is true and not
when it is false. This can't be an ordinary test case because we need
to inspect the compiler database.
'''
if not is_osx():
raise unittest.SkipTest('Apple bitcode not relevant')
testdir = os.path.join(self.common_test_dir, '4 shared')
# Try with bitcode enabled
self.init(testdir, extra_args='-Db_bitcode=true')
compdb = self.get_compdb()
self.assertIn('-fembed-bitcode', compdb[0]['command'])
build_ninja = os.path.join(self.builddir, 'build.ninja')
with open(build_ninja, 'r', encoding='utf-8') as f:
contents = f.read()
m = re.search('LINK_ARGS =.*-bitcode_bundle', contents)
self.assertIsNotNone(m, msg=contents)
# Try with bitcode disabled
self.setconf('-Db_bitcode=false')
# Regenerate build
self.build()
compdb = self.get_compdb()
self.assertNotIn('-fembed-bitcode', compdb[0]['command'])
build_ninja = os.path.join(self.builddir, 'build.ninja')
with open(build_ninja, 'r', encoding='utf-8') as f:
contents = f.read()
m = re.search('LINK_ARGS =.*-bitcode_bundle', contents)
self.assertIsNone(m, msg=contents)
def test_apple_bitcode_modules(self):
'''
Same as above, just for shared_module()
'''
if not is_osx():
raise unittest.SkipTest('Apple bitcode not relevant')
testdir = os.path.join(self.common_test_dir, '156 shared module resolving symbol in executable')
# Ensure that it builds even with bitcode enabled
self.init(testdir, extra_args='-Db_bitcode=true')
self.build()
self.run_tests()
class LinuxArmCrossCompileTests(BasePlatformTests):
'''
Tests that verify cross-compilation to Linux/ARM

Loading…
Cancel
Save