|
|
|
# Copyright 2016-2021 The Meson development team
|
|
|
|
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
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('/System/Library/CoreServices/Encodings/libSymbolConverter.dylib')
|
|
|
|
self.assertEqual(archs, ['x86_64', 'aarch64'])
|