The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
7.5 KiB
176 lines
7.5 KiB
# SPDX-License-Identifier: Apache-2.0 |
|
# Copyright 2016-2021 The Meson development team |
|
|
|
import subprocess |
|
import re |
|
import os |
|
import platform |
|
import unittest |
|
|
|
from mesonbuild.mesonlib import ( |
|
MachineChoice, is_osx, version_compare |
|
) |
|
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() |
|
|
|
@unittest.skipIf(version_compare(platform.mac_ver()[0], '<10.7'), '-export_dynamic was added in 10.7') |
|
def test_apple_lto_export_dynamic(self): |
|
''' |
|
Tests that -Wl,-export_dynamic is correctly added, when export_dynamic: true is set. |
|
On macOS, this is relevant for LTO builds only. |
|
''' |
|
testdir = os.path.join(self.common_test_dir, '148 shared module resolving symbol in executable') |
|
# Ensure that it builds even with LTO enabled |
|
env = {'CFLAGS': '-flto'} |
|
self.init(testdir, override_envvars=env) |
|
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() |
|
|
|
def _get_darwin_rpaths(self, fname: str) -> T.List[str]: |
|
out = subprocess.check_output(['otool', '-l', fname], universal_newlines=True) |
|
pattern = re.compile(r'path (.*) \(offset \d+\)') |
|
rpaths = pattern.findall(out) |
|
return rpaths |
|
|
|
@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']) |
|
|
|
def test_darwin_meson_rpaths_removed_on_install(self): |
|
testdir = os.path.join(self.darwin_test_dir, '1 rpath removal on install') |
|
self.init(testdir) |
|
self.build() |
|
# Meson-created RPATHs are usually only valid in the build directory |
|
rpaths = self._get_darwin_rpaths(os.path.join(self.builddir, 'libbar.dylib')) |
|
self.assertListEqual(rpaths, ['@loader_path/foo']) |
|
self.install() |
|
# Those RPATHs are no longer valid and should not be present after installation |
|
rpaths = self._get_darwin_rpaths(os.path.join(self.installdir, 'usr/lib/libbar.dylib')) |
|
self.assertListEqual(rpaths, [])
|
|
|