diff options
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 3 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 3 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 49 | ||||
-rwxr-xr-x | run_unittests.py | 43 |
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 |