aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2018-05-22 13:39:00 +0530
committerNirbheek Chauhan <nirbheek.chauhan@gmail.com>2018-06-06 07:53:10 +0000
commit3e1a610702adfec51a24a7dfdcba8a0319a795a1 (patch)
tree48e7a07ca16ba946ce03eedff498383db5e17aae
parent68001193d30909c6b00044360e6366630c8ff337 (diff)
downloadmeson-3e1a610702adfec51a24a7dfdcba8a0319a795a1.zip
meson-3e1a610702adfec51a24a7dfdcba8a0319a795a1.tar.gz
meson-3e1a610702adfec51a24a7dfdcba8a0319a795a1.tar.bz2
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.
-rw-r--r--mesonbuild/backend/ninjabackend.py3
-rw-r--r--mesonbuild/backend/vs2010backend.py3
-rw-r--r--mesonbuild/compilers/compilers.py49
-rwxr-xr-xrun_unittests.py43
4 files changed, 81 insertions, 17 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 423c2ff..cd43b69 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.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
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 09822ed..0ff7157 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -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()
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 9bd9bb2..6a310ba 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -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):
@@ -361,20 +374,22 @@ def get_base_link_args(options, linker, is_shared_module):
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']
diff --git a/run_unittests.py b/run_unittests.py
index 1e2cc27..a25ba34 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -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