| # SPDX-License-Identifier: Apache-2.0 |
| # Copyright 2016-2021 The Meson development team |
| |
| import subprocess |
| import re |
| import os |
| import unittest |
| |
| from mesonbuild.mesonlib import ( |
| MachineChoice, is_osx |
| ) |
| from mesonbuild.compilers import ( |
| detect_c_compiler |
| ) |
| |
| |
| from run_tests import ( |
| get_fake_env |
| ) |
| |
| from .baseplatformtests import BasePlatformTests |
| from .helpers import * |
| |
| @unittest.skipUnless(is_osx(), "requires Darwin") |
| class DarwinTests(BasePlatformTests): |
| ''' |
| Tests that should run on macOS |
| ''' |
| |
| def setUp(self): |
| super().setUp() |
| self.platform_test_dir = os.path.join(self.src_root, 'test cases/osx') |
| |
| 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. |
| ''' |
| testdir = os.path.join(self.platform_test_dir, '7 bitcode') |
| env = get_fake_env(testdir, self.builddir, self.prefix) |
| cc = detect_c_compiler(env, MachineChoice.HOST) |
| if cc.id != 'clang': |
| raise unittest.SkipTest('Not using Clang on OSX') |
| # Try with bitcode enabled |
| out = self.init(testdir, extra_args='-Db_bitcode=true') |
| # Warning was printed |
| self.assertRegex(out, 'WARNING:.*b_bitcode') |
| # Compiler options were added |
| for compdb in self.get_compdb(): |
| if 'module' in compdb['file']: |
| self.assertNotIn('-fembed-bitcode', compdb['command']) |
| else: |
| self.assertIn('-fembed-bitcode', compdb['command']) |
| build_ninja = os.path.join(self.builddir, 'build.ninja') |
| # Linker options were added |
| with open(build_ninja, 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() |
| for compdb in self.get_compdb(): |
| self.assertNotIn('-fembed-bitcode', compdb['command']) |
| build_ninja = os.path.join(self.builddir, 'build.ninja') |
| with open(build_ninja, 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() |
| ''' |
| testdir = os.path.join(self.common_test_dir, '148 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() |
| |
| def _get_darwin_versions(self, fname): |
| fname = os.path.join(self.builddir, fname) |
| out = subprocess.check_output(['otool', '-L', fname], universal_newlines=True) |
| m = re.match(r'.*version (.*), current version (.*)\)', out.split('\n')[1]) |
| self.assertIsNotNone(m, msg=out) |
| return m.groups() |
| |
| @skipIfNoPkgconfig |
| def test_library_versioning(self): |
| ''' |
| Ensure that compatibility_version and current_version are set correctly |
| ''' |
| testdir = os.path.join(self.platform_test_dir, '2 library versions') |
| self.init(testdir) |
| self.build() |
| targets = {} |
| for t in self.introspect('--targets'): |
| targets[t['name']] = t['filename'][0] if isinstance(t['filename'], list) else t['filename'] |
| self.assertEqual(self._get_darwin_versions(targets['some']), ('7.0.0', '7.0.0')) |
| self.assertEqual(self._get_darwin_versions(targets['noversion']), ('0.0.0', '0.0.0')) |
| self.assertEqual(self._get_darwin_versions(targets['onlyversion']), ('1.0.0', '1.0.0')) |
| self.assertEqual(self._get_darwin_versions(targets['onlysoversion']), ('5.0.0', '5.0.0')) |
| self.assertEqual(self._get_darwin_versions(targets['intver']), ('2.0.0', '2.0.0')) |
| self.assertEqual(self._get_darwin_versions(targets['stringver']), ('2.3.0', '2.3.0')) |
| self.assertEqual(self._get_darwin_versions(targets['stringlistver']), ('2.4.0', '2.4.0')) |
| self.assertEqual(self._get_darwin_versions(targets['intstringver']), ('1111.0.0', '2.5.0')) |
| self.assertEqual(self._get_darwin_versions(targets['stringlistvers']), ('2.6.0', '2.6.1')) |
| |
| def test_duplicate_rpath(self): |
| testdir = os.path.join(self.unit_test_dir, '10 build_rpath') |
| # We purposely pass a duplicate rpath to Meson, in order |
| # to ascertain that Meson does not call install_name_tool |
| # with duplicate -delete_rpath arguments, which would |
| # lead to erroring out on installation |
| env = {"LDFLAGS": "-Wl,-rpath,/foo/bar"} |
| self.init(testdir, override_envvars=env) |
| self.build() |
| self.install() |
| |
| def test_removing_unused_linker_args(self): |
| testdir = os.path.join(self.common_test_dir, '104 has arg') |
| env = {'CFLAGS': '-L/tmp -L /var/tmp -headerpad_max_install_names -Wl,-export_dynamic -framework Foundation'} |
| self.init(testdir, override_envvars=env) |
| |
| def test_objc_versions(self): |
| # Objective-C always uses the C standard version. |
| # Objective-C++ always uses the C++ standard version. |
| # This is what most people seem to want and in addition |
| # it is the only setup supported by Xcode. |
| testdir = os.path.join(self.objc_test_dir, '1 simple') |
| self.init(testdir) |
| self.assertIn('-std=c99', self.get_compdb()[0]['command']) |
| self.wipe() |
| testdir = os.path.join(self.objcpp_test_dir, '1 simple') |
| self.init(testdir) |
| self.assertIn('-std=c++14', self.get_compdb()[0]['command']) |
| |
| def test_darwin_get_object_archs(self): |
| from mesonbuild.mesonlib import darwin_get_object_archs |
| archs = darwin_get_object_archs('/bin/cat') |
| self.assertEqual(archs, ['x86_64', 'aarch64']) |