diff options
Diffstat (limited to 'unittests/allplatformstests.py')
-rw-r--r-- | unittests/allplatformstests.py | 446 |
1 files changed, 279 insertions, 167 deletions
diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 2fee06c..f158be7 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -29,7 +29,7 @@ import mesonbuild.coredata import mesonbuild.machinefile import mesonbuild.modules.gnome from mesonbuild.mesonlib import ( - BuildDirLock, MachineChoice, is_windows, is_osx, is_cygwin, is_dragonflybsd, + DirectoryLock, DirectoryLockAction, MachineChoice, is_windows, is_osx, is_cygwin, is_dragonflybsd, is_sunos, windows_proof_rmtree, python_command, version_compare, split_args, quote_arg, relpath, is_linux, git, search_version, do_conf_file, do_conf_str, default_prefix, MesonException, EnvironmentException, @@ -222,6 +222,47 @@ class AllPlatformTests(BasePlatformTests): confdata.values = {'VAR': (['value'], 'description')} self.assertRaises(MesonException, conf_str, ['#mesondefine VAR'], confdata, 'meson') + def test_cmake_configuration(self): + if self.backend is not Backend.ninja: + raise SkipTest('ninja backend needed to configure with cmake') + + cmake = ExternalProgram('cmake') + if not cmake.found(): + raise SkipTest('cmake not available') + + cmake_version = cmake.get_version() + if not version_compare(cmake_version, '>=3.13.5'): + raise SkipTest('cmake is too old') + + with tempfile.TemporaryDirectory() as tmpdir: + srcdir = os.path.join(tmpdir, 'src') + + shutil.copytree(os.path.join(self.src_root, 'test cases', 'common', '14 configure file'), srcdir) + self.init(srcdir) + + cmake_builddir = os.path.join(srcdir, "cmake_builddir") + self.assertNotEqual(self.builddir, cmake_builddir) + self._run([cmake.path, '-G', 'Ninja', '-S', srcdir, '-B', cmake_builddir]) + + header_list = [ + 'config7.h', + 'config10.h', + ] + + for header in header_list: + meson_header = "" + cmake_header = "" + + with open(os.path.join(self.builddir, header), encoding='utf-8') as f: + meson_header = f.read() + + cmake_header_path = os.path.join(cmake_builddir, header) + with open(os.path.join(cmake_builddir, header), encoding='utf-8') as f: + cmake_header = f.read() + + self.assertTrue(cmake_header, f'cmake generated header {header} is empty') + self.assertEqual(cmake_header, meson_header) + def test_absolute_prefix_libdir(self): ''' Tests that setting absolute paths for --prefix and --libdir work. Can't @@ -488,7 +529,7 @@ class AllPlatformTests(BasePlatformTests): ''' if not shutil.which('xmllint'): raise SkipTest('xmllint not installed') - testdir = os.path.join(self.unit_test_dir, '111 replace unencodable xml chars') + testdir = os.path.join(self.unit_test_dir, '112 replace unencodable xml chars') self.init(testdir) tests_command_output = self.run_tests() junit_xml_logs = Path(self.logdir, 'testlog.junit.xml') @@ -529,7 +570,8 @@ class AllPlatformTests(BasePlatformTests): if self.backend is not Backend.ninja: raise SkipTest(f'{self.backend.name!r} backend can\'t install files') testdir = os.path.join(self.common_test_dir, '8 install') - self.init(testdir) + # sneak in a test that covers backend options... + self.init(testdir, extra_args=['-Dbackend_max_links=4']) intro = self.introspect('--targets') if intro[0]['type'] == 'executable': intro = intro[::-1] @@ -648,7 +690,7 @@ class AllPlatformTests(BasePlatformTests): self.run_tests() def test_implicit_forcefallback(self): - testdir = os.path.join(self.unit_test_dir, '95 implicit force fallback') + testdir = os.path.join(self.unit_test_dir, '96 implicit force fallback') with self.assertRaises(subprocess.CalledProcessError): self.init(testdir) self.init(testdir, extra_args=['--wrap-mode=forcefallback']) @@ -1098,110 +1140,144 @@ class AllPlatformTests(BasePlatformTests): for lang, evar in langs: # Detect with evar and do sanity checks on that if evar in os.environ: - ecc = compiler_from_language(env, lang, MachineChoice.HOST) - self.assertTrue(ecc.version) - elinker = detect_static_linker(env, ecc) - # Pop it so we don't use it for the next detection - evalue = os.environ.pop(evar) - # Very rough/strict heuristics. Would never work for actual - # compiler detection, but should be ok for the tests. - ebase = os.path.basename(evalue) - if ebase.startswith('g') or ebase.endswith(('-gcc', '-g++')): - self.assertIsInstance(ecc, gnu) - self.assertIsInstance(elinker, ar) - elif 'clang-cl' in ebase: - self.assertIsInstance(ecc, clangcl) - self.assertIsInstance(elinker, lib) - elif 'clang' in ebase: - self.assertIsInstance(ecc, clang) - self.assertIsInstance(elinker, ar) - elif ebase.startswith('ic'): - self.assertIsInstance(ecc, intel) - self.assertIsInstance(elinker, ar) - elif ebase.startswith('cl'): - self.assertIsInstance(ecc, msvc) - self.assertIsInstance(elinker, lib) - else: - raise AssertionError(f'Unknown compiler {evalue!r}') - # Check that we actually used the evalue correctly as the compiler - self.assertEqual(ecc.get_exelist(), split_args(evalue)) + with self.subTest(lang=lang, evar=evar): + try: + ecc = compiler_from_language(env, lang, MachineChoice.HOST) + except EnvironmentException: + # always raise in ci, we expect to have a valid ObjC and ObjC++ compiler of some kind + if is_ci(): + self.fail(f'Could not find a compiler for {lang}') + if sys.version_info < (3, 11): + continue + self.skipTest(f'No valid compiler for {lang}.') + finally: + # Pop it so we don't use it for the next detection + evalue = os.environ.pop(evar) + assert ecc is not None, "Something went really wrong" + self.assertTrue(ecc.version) + elinker = detect_static_linker(env, ecc) + # Very rough/strict heuristics. Would never work for actual + # compiler detection, but should be ok for the tests. + ebase = os.path.basename(evalue) + if ebase.startswith('g') or ebase.endswith(('-gcc', '-g++')): + self.assertIsInstance(ecc, gnu) + self.assertIsInstance(elinker, ar) + elif 'clang-cl' in ebase: + self.assertIsInstance(ecc, clangcl) + self.assertIsInstance(elinker, lib) + elif 'clang' in ebase: + self.assertIsInstance(ecc, clang) + self.assertIsInstance(elinker, ar) + elif ebase.startswith('ic'): + self.assertIsInstance(ecc, intel) + self.assertIsInstance(elinker, ar) + elif ebase.startswith('cl'): + self.assertIsInstance(ecc, msvc) + self.assertIsInstance(elinker, lib) + else: + self.fail(f'Unknown compiler {evalue!r}') + # Check that we actually used the evalue correctly as the compiler + self.assertEqual(ecc.get_exelist(), split_args(evalue)) + # Do auto-detection of compiler based on platform, PATH, etc. - cc = compiler_from_language(env, lang, MachineChoice.HOST) - self.assertTrue(cc.version) - linker = detect_static_linker(env, cc) - # Check compiler type - if isinstance(cc, gnu): - self.assertIsInstance(linker, ar) - if is_osx(): - self.assertIsInstance(cc.linker, linkers.AppleDynamicLinker) - elif is_sunos(): - self.assertIsInstance(cc.linker, (linkers.SolarisDynamicLinker, linkers.GnuLikeDynamicLinkerMixin)) - else: - self.assertIsInstance(cc.linker, linkers.GnuLikeDynamicLinkerMixin) - if isinstance(cc, clangcl): - self.assertIsInstance(linker, lib) - self.assertIsInstance(cc.linker, linkers.ClangClDynamicLinker) - if isinstance(cc, clang): - self.assertIsInstance(linker, ar) - if is_osx(): - self.assertIsInstance(cc.linker, linkers.AppleDynamicLinker) - elif is_windows(): - # This is clang, not clang-cl. This can be either an - # ld-like linker of link.exe-like linker (usually the - # former for msys2, the latter otherwise) - self.assertIsInstance(cc.linker, (linkers.MSVCDynamicLinker, linkers.GnuLikeDynamicLinkerMixin)) - elif is_sunos(): - self.assertIsInstance(cc.linker, (linkers.SolarisDynamicLinker, linkers.GnuLikeDynamicLinkerMixin)) - else: - self.assertIsInstance(cc.linker, linkers.GnuLikeDynamicLinkerMixin) - if isinstance(cc, intel): - self.assertIsInstance(linker, ar) - if is_osx(): - self.assertIsInstance(cc.linker, linkers.AppleDynamicLinker) - elif is_windows(): - self.assertIsInstance(cc.linker, linkers.XilinkDynamicLinker) - else: - self.assertIsInstance(cc.linker, linkers.GnuDynamicLinker) - if isinstance(cc, msvc): - self.assertTrue(is_windows()) - self.assertIsInstance(linker, lib) - self.assertEqual(cc.id, 'msvc') - self.assertTrue(hasattr(cc, 'is_64')) - self.assertIsInstance(cc.linker, linkers.MSVCDynamicLinker) - # If we're on Windows CI, we know what the compiler will be - if 'arch' in os.environ: - if os.environ['arch'] == 'x64': - self.assertTrue(cc.is_64) + with self.subTest(lang=lang): + try: + cc = compiler_from_language(env, lang, MachineChoice.HOST) + except EnvironmentException: + # always raise in ci, we expect to have a valid ObjC and ObjC++ compiler of some kind + if is_ci(): + self.fail(f'Could not find a compiler for {lang}') + if sys.version_info < (3, 11): + continue + self.skipTest(f'No valid compiler for {lang}.') + assert cc is not None, "Something went really wrong" + self.assertTrue(cc.version) + linker = detect_static_linker(env, cc) + # Check compiler type + if isinstance(cc, gnu): + self.assertIsInstance(linker, ar) + if is_osx(): + self.assertIsInstance(cc.linker, linkers.AppleDynamicLinker) + elif is_sunos(): + self.assertIsInstance(cc.linker, (linkers.SolarisDynamicLinker, linkers.GnuLikeDynamicLinkerMixin)) + else: + self.assertIsInstance(cc.linker, linkers.GnuLikeDynamicLinkerMixin) + if isinstance(cc, clangcl): + self.assertIsInstance(linker, lib) + self.assertIsInstance(cc.linker, linkers.ClangClDynamicLinker) + if isinstance(cc, clang): + self.assertIsInstance(linker, ar) + if is_osx(): + self.assertIsInstance(cc.linker, linkers.AppleDynamicLinker) + elif is_windows(): + # This is clang, not clang-cl. This can be either an + # ld-like linker of link.exe-like linker (usually the + # former for msys2, the latter otherwise) + self.assertIsInstance(cc.linker, (linkers.MSVCDynamicLinker, linkers.GnuLikeDynamicLinkerMixin)) + elif is_sunos(): + self.assertIsInstance(cc.linker, (linkers.SolarisDynamicLinker, linkers.GnuLikeDynamicLinkerMixin)) + else: + self.assertIsInstance(cc.linker, linkers.GnuLikeDynamicLinkerMixin) + if isinstance(cc, intel): + self.assertIsInstance(linker, ar) + if is_osx(): + self.assertIsInstance(cc.linker, linkers.AppleDynamicLinker) + elif is_windows(): + self.assertIsInstance(cc.linker, linkers.XilinkDynamicLinker) else: - self.assertFalse(cc.is_64) + self.assertIsInstance(cc.linker, linkers.GnuDynamicLinker) + if isinstance(cc, msvc): + self.assertTrue(is_windows()) + self.assertIsInstance(linker, lib) + self.assertEqual(cc.id, 'msvc') + self.assertTrue(hasattr(cc, 'is_64')) + self.assertIsInstance(cc.linker, linkers.MSVCDynamicLinker) + # If we're on Windows CI, we know what the compiler will be + if 'arch' in os.environ: + if os.environ['arch'] == 'x64': + self.assertTrue(cc.is_64) + else: + self.assertFalse(cc.is_64) + # Set evar ourselves to a wrapper script that just calls the same # exelist + some argument. This is meant to test that setting # something like `ccache gcc -pipe` or `distcc ccache gcc` works. - wrapper = os.path.join(testdir, 'compiler wrapper.py') - wrappercc = python_command + [wrapper] + cc.get_exelist() + ['-DSOME_ARG'] - os.environ[evar] = ' '.join(quote_arg(w) for w in wrappercc) - - # Check static linker too - wrapperlinker = python_command + [wrapper] + linker.get_exelist() + linker.get_always_args() - os.environ['AR'] = ' '.join(quote_arg(w) for w in wrapperlinker) - - # Need a new env to re-run environment loading - env = get_fake_env(testdir, self.builddir, self.prefix) - - wcc = compiler_from_language(env, lang, MachineChoice.HOST) - wlinker = detect_static_linker(env, wcc) - # Pop it so we don't use it for the next detection - os.environ.pop('AR') - # Must be the same type since it's a wrapper around the same exelist - self.assertIs(type(cc), type(wcc)) - self.assertIs(type(linker), type(wlinker)) - # Ensure that the exelist is correct - self.assertEqual(wcc.get_exelist(), wrappercc) - self.assertEqual(wlinker.get_exelist(), wrapperlinker) - # Ensure that the version detection worked correctly - self.assertEqual(cc.version, wcc.version) - if hasattr(cc, 'is_64'): - self.assertEqual(cc.is_64, wcc.is_64) + with self.subTest('wrapper script', lang=lang): + wrapper = os.path.join(testdir, 'compiler wrapper.py') + wrappercc = python_command + [wrapper] + cc.get_exelist() + ['-DSOME_ARG'] + os.environ[evar] = ' '.join(quote_arg(w) for w in wrappercc) + + # Check static linker too + wrapperlinker = python_command + [wrapper] + linker.get_exelist() + linker.get_always_args() + os.environ['AR'] = ' '.join(quote_arg(w) for w in wrapperlinker) + + # Need a new env to re-run environment loading + env = get_fake_env(testdir, self.builddir, self.prefix) + + try: + wcc = compiler_from_language(env, lang, MachineChoice.HOST) + except EnvironmentException: + # always raise in ci, we expect to have a valid ObjC and ObjC++ compiler of some kind + if is_ci(): + self.fail(f'Could not find a compiler for {lang}') + if sys.version_info < (3, 11): + continue + self.skipTest(f'No valid compiler for {lang}.') + wlinker = detect_static_linker(env, wcc) + del os.environ['AR'] + + # Must be the same type since it's a wrapper around the same exelist + self.assertIs(type(cc), type(wcc)) + self.assertIs(type(linker), type(wlinker)) + + # Ensure that the exelist is correct + self.assertEqual(wcc.get_exelist(), wrappercc) + self.assertEqual(wlinker.get_exelist(), wrapperlinker) + + # Ensure that the version detection worked correctly + self.assertEqual(cc.version, wcc.version) + if hasattr(cc, 'is_64'): + self.assertEqual(cc.is_64, wcc.is_64) def test_always_prefer_c_compiler_for_asm(self): testdir = os.path.join(self.common_test_dir, '133 c cpp and asm') @@ -1366,7 +1442,7 @@ class AllPlatformTests(BasePlatformTests): Test that conflicts between -D for builtin options and the corresponding long option are detected without false positives or negatives. ''' - testdir = os.path.join(self.unit_test_dir, '128 long opt vs D') + testdir = os.path.join(self.unit_test_dir, '130 long opt vs D') for opt in ['-Dsysconfdir=/etc', '-Dsysconfdir2=/etc']: exception_raised = False @@ -2112,7 +2188,7 @@ class AllPlatformTests(BasePlatformTests): check_pcfile('libvartest2.pc', relocatable=False) self.wipe() - testdir_abs = os.path.join(self.unit_test_dir, '105 pkgconfig relocatable with absolute path') + testdir_abs = os.path.join(self.unit_test_dir, '106 pkgconfig relocatable with absolute path') self.init(testdir_abs) check_pcfile('libsimple.pc', relocatable=True, levels=3) @@ -2194,7 +2270,7 @@ class AllPlatformTests(BasePlatformTests): self.assertDictEqual(original, expected) def test_executable_names(self): - testdir = os.path.join(self.unit_test_dir, '121 executable suffix') + testdir = os.path.join(self.unit_test_dir, '122 executable suffix') self.init(testdir) self.build() exe1 = os.path.join(self.builddir, 'foo' + exe_suffix) @@ -2285,7 +2361,7 @@ class AllPlatformTests(BasePlatformTests): def test_options_listed_in_build_options(self) -> None: """Detect when changed options become listed in build options.""" - testdir = os.path.join(self.unit_test_dir, '113 list build options') + testdir = os.path.join(self.unit_test_dir, '114 list build options') out = self.init(testdir) for line in out.splitlines(): @@ -2498,10 +2574,9 @@ class AllPlatformTests(BasePlatformTests): def test_flock(self): exception_raised = False with tempfile.TemporaryDirectory() as tdir: - os.mkdir(os.path.join(tdir, 'meson-private')) - with BuildDirLock(tdir): + with DirectoryLock(tdir, 'lock', DirectoryLockAction.FAIL, 'failed to lock directory'): try: - with BuildDirLock(tdir): + with DirectoryLock(tdir, 'lock', DirectoryLockAction.FAIL, 'expected failure'): pass except MesonException: exception_raised = True @@ -2523,7 +2598,7 @@ class AllPlatformTests(BasePlatformTests): self.assertIn(msg, out) def test_mixed_language_linker_check(self): - testdir = os.path.join(self.unit_test_dir, '96 compiler.links file arg') + testdir = os.path.join(self.unit_test_dir, '97 compiler.links file arg') self.init(testdir) cmds = self.get_meson_log_compiler_checks() self.assertEqual(len(cmds), 5) @@ -3241,10 +3316,15 @@ class AllPlatformTests(BasePlatformTests): def test_identity_cross(self): testdir = os.path.join(self.unit_test_dir, '69 cross') # Do a build to generate a cross file where the host is this target - self.init(testdir, extra_args=['-Dgenerate=true']) + # build.c_args is ignored here. + self.init(testdir, extra_args=['-Dgenerate=true', '-Dc_args=-funroll-loops', + '-Dbuild.c_args=-pedantic']) + self.meson_native_files = [os.path.join(self.builddir, "nativefile")] + self.assertTrue(os.path.exists(self.meson_native_files[0])) self.meson_cross_files = [os.path.join(self.builddir, "crossfile")] self.assertTrue(os.path.exists(self.meson_cross_files[0])) - # Now verify that this is detected as cross + # Now verify that this is detected as cross and build options are + # processed correctly self.new_builddir() self.init(testdir) @@ -3263,6 +3343,11 @@ class AllPlatformTests(BasePlatformTests): testdir = os.path.join(self.unit_test_dir, '58 introspect buildoptions') self._run(self.mconf_command + [testdir]) + @skip_if_not_language('rust') + def test_meson_configure_srcdir(self): + testdir = os.path.join(self.rust_test_dir, '20 rust and cpp') + self._run(self.mconf_command + [testdir]) + def test_introspect_buildoptions_cross_only(self): testdir = os.path.join(self.unit_test_dir, '82 cross only introspect') testfile = os.path.join(testdir, 'meson.build') @@ -3611,6 +3696,8 @@ class AllPlatformTests(BasePlatformTests): # Account for differences in output res_wb = [i for i in res_wb if i['type'] != 'custom'] for i in res_wb: + if i['id'] == 'test1@exe': + i['build_by_default'] = 'unknown' i['filename'] = [os.path.relpath(x, self.builddir) for x in i['filename']] for k in ('install_filename', 'dependencies', 'win_subsystem'): if k in i: @@ -3729,7 +3816,7 @@ class AllPlatformTests(BasePlatformTests): }, { 'name': 'bugDep1', - 'required': True, + 'required': 'unknown', 'version': [], 'has_fallback': False, 'conditional': False @@ -4361,7 +4448,7 @@ class AllPlatformTests(BasePlatformTests): self.init(srcdir, extra_args=['-Dbuild.b_lto=true']) def test_install_skip_subprojects(self): - testdir = os.path.join(self.unit_test_dir, '91 install skip subprojects') + testdir = os.path.join(self.unit_test_dir, '92 install skip subprojects') self.init(testdir) self.build() @@ -4408,7 +4495,7 @@ class AllPlatformTests(BasePlatformTests): check_installed_files(['--skip-subprojects', 'another'], all_expected) def test_adding_subproject_to_configure_project(self) -> None: - srcdir = os.path.join(self.unit_test_dir, '92 new subproject in configured project') + srcdir = os.path.join(self.unit_test_dir, '93 new subproject in configured project') self.init(srcdir) self.build() self.setconf('-Duse-sub=true') @@ -4452,13 +4539,17 @@ class AllPlatformTests(BasePlatformTests): self.assertIn(f'TEST_C="{expected}"', o) self.assertIn('export TEST_C', o) + cmd = self.meson_command + ['devenv', '-C', self.builddir] + python_command + ['-c', 'import sys; sys.exit(42)'] + result = subprocess.run(cmd, encoding='utf-8') + self.assertEqual(result.returncode, 42) + def test_clang_format_check(self): if self.backend is not Backend.ninja: raise SkipTest(f'Skipping clang-format tests with {self.backend.name} backend') if not shutil.which('clang-format'): raise SkipTest('clang-format not found') - testdir = os.path.join(self.unit_test_dir, '93 clangformat') + testdir = os.path.join(self.unit_test_dir, '94 clangformat') newdir = os.path.join(self.builddir, 'testdir') shutil.copytree(testdir, newdir) self.new_builddir() @@ -4483,7 +4574,7 @@ class AllPlatformTests(BasePlatformTests): self.build('clang-format-check') def test_custom_target_implicit_include(self): - testdir = os.path.join(self.unit_test_dir, '94 custominc') + testdir = os.path.join(self.unit_test_dir, '95 custominc') self.init(testdir) self.build() compdb = self.get_compdb() @@ -4529,7 +4620,7 @@ class AllPlatformTests(BasePlatformTests): # self.assertEqual(sorted(link_args), sorted(['-flto'])) def test_install_tag(self) -> None: - testdir = os.path.join(self.unit_test_dir, '98 install all targets') + testdir = os.path.join(self.unit_test_dir, '99 install all targets') self.init(testdir) self.build() @@ -4700,7 +4791,7 @@ class AllPlatformTests(BasePlatformTests): def test_introspect_install_plan(self): - testdir = os.path.join(self.unit_test_dir, '98 install all targets') + testdir = os.path.join(self.unit_test_dir, '99 install all targets') introfile = os.path.join(self.builddir, 'meson-info', 'intro-install_plan.json') self.init(testdir) self.assertPathExists(introfile) @@ -4721,124 +4812,145 @@ class AllPlatformTests(BasePlatformTests): shared_lib_name = lambda name: output_name(name, SharedLibrary) static_lib_name = lambda name: output_name(name, StaticLibrary) exe_name = lambda name: output_name(name, Executable) + get_path = lambda f: Path(f).as_posix() expected = { 'targets': { - f'{self.builddir}/out1-notag.txt': { + get_path(f'{self.builddir}/out1-notag.txt'): { + 'build_rpaths': [], 'destination': '{datadir}/out1-notag.txt', 'install_rpath': None, 'tag': None, 'subproject': None, }, - f'{self.builddir}/out2-notag.txt': { + get_path(f'{self.builddir}/out2-notag.txt'): { + 'build_rpaths': [], 'destination': '{datadir}/out2-notag.txt', 'install_rpath': None, 'tag': None, 'subproject': None, }, - f'{self.builddir}/libstatic.a': { + get_path(f'{self.builddir}/libstatic.a'): { + 'build_rpaths': [], 'destination': '{libdir_static}/libstatic.a', 'install_rpath': None, 'tag': 'devel', 'subproject': None, }, - f'{self.builddir}/' + exe_name('app'): { + get_path(f'{self.builddir}/' + exe_name('app')): { + 'build_rpaths': [], 'destination': '{bindir}/' + exe_name('app'), 'install_rpath': None, 'tag': 'runtime', 'subproject': None, }, - f'{self.builddir}/' + exe_name('app-otherdir'): { + get_path(f'{self.builddir}/' + exe_name('app-otherdir')): { + 'build_rpaths': [], 'destination': '{prefix}/otherbin/' + exe_name('app-otherdir'), 'install_rpath': None, 'tag': 'runtime', 'subproject': None, }, - f'{self.builddir}/subdir/' + exe_name('app2'): { + get_path(f'{self.builddir}/subdir/' + exe_name('app2')): { + 'build_rpaths': [], 'destination': '{bindir}/' + exe_name('app2'), 'install_rpath': None, 'tag': 'runtime', 'subproject': None, }, - f'{self.builddir}/' + shared_lib_name('shared'): { + get_path(f'{self.builddir}/' + shared_lib_name('shared')): { + 'build_rpaths': [], 'destination': '{libdir_shared}/' + shared_lib_name('shared'), 'install_rpath': None, 'tag': 'runtime', 'subproject': None, }, - f'{self.builddir}/' + shared_lib_name('both'): { + get_path(f'{self.builddir}/' + shared_lib_name('both')): { + 'build_rpaths': [], 'destination': '{libdir_shared}/' + shared_lib_name('both'), 'install_rpath': None, 'tag': 'runtime', 'subproject': None, }, - f'{self.builddir}/' + static_lib_name('both'): { + get_path(f'{self.builddir}/' + static_lib_name('both')): { + 'build_rpaths': [], 'destination': '{libdir_static}/' + static_lib_name('both'), 'install_rpath': None, 'tag': 'devel', 'subproject': None, }, - f'{self.builddir}/' + shared_lib_name('bothcustom'): { + get_path(f'{self.builddir}/' + shared_lib_name('bothcustom')): { + 'build_rpaths': [], 'destination': '{libdir_shared}/' + shared_lib_name('bothcustom'), 'install_rpath': None, 'tag': 'custom', 'subproject': None, }, - f'{self.builddir}/' + static_lib_name('bothcustom'): { + get_path(f'{self.builddir}/' + static_lib_name('bothcustom')): { + 'build_rpaths': [], 'destination': '{libdir_static}/' + static_lib_name('bothcustom'), 'install_rpath': None, 'tag': 'custom', 'subproject': None, }, - f'{self.builddir}/subdir/' + shared_lib_name('both2'): { + get_path(f'{self.builddir}/subdir/' + shared_lib_name('both2')): { + 'build_rpaths': [], 'destination': '{libdir_shared}/' + shared_lib_name('both2'), 'install_rpath': None, 'tag': 'runtime', 'subproject': None, }, - f'{self.builddir}/subdir/' + static_lib_name('both2'): { + get_path(f'{self.builddir}/subdir/' + static_lib_name('both2')): { + 'build_rpaths': [], 'destination': '{libdir_static}/' + static_lib_name('both2'), 'install_rpath': None, 'tag': 'devel', 'subproject': None, }, - f'{self.builddir}/out1-custom.txt': { + get_path(f'{self.builddir}/out1-custom.txt'): { + 'build_rpaths': [], 'destination': '{datadir}/out1-custom.txt', 'install_rpath': None, 'tag': 'custom', 'subproject': None, }, - f'{self.builddir}/out2-custom.txt': { + get_path(f'{self.builddir}/out2-custom.txt'): { + 'build_rpaths': [], 'destination': '{datadir}/out2-custom.txt', 'install_rpath': None, 'tag': 'custom', 'subproject': None, }, - f'{self.builddir}/out3-custom.txt': { + get_path(f'{self.builddir}/out3-custom.txt'): { + 'build_rpaths': [], 'destination': '{datadir}/out3-custom.txt', 'install_rpath': None, 'tag': 'custom', 'subproject': None, }, - f'{self.builddir}/subdir/out1.txt': { + get_path(f'{self.builddir}/subdir/out1.txt'): { + 'build_rpaths': [], 'destination': '{datadir}/out1.txt', 'install_rpath': None, 'tag': None, 'subproject': None, }, - f'{self.builddir}/subdir/out2.txt': { + get_path(f'{self.builddir}/subdir/out2.txt'): { + 'build_rpaths': [], 'destination': '{datadir}/out2.txt', 'install_rpath': None, 'tag': None, 'subproject': None, }, - f'{self.builddir}/out-devel.h': { + get_path(f'{self.builddir}/out-devel.h'): { + 'build_rpaths': [], 'destination': '{includedir}/out-devel.h', 'install_rpath': None, 'tag': 'devel', 'subproject': None, }, - f'{self.builddir}/out3-notag.txt': { + get_path(f'{self.builddir}/out3-notag.txt'): { + 'build_rpaths': [], 'destination': '{datadir}/out3-notag.txt', 'install_rpath': None, 'tag': None, @@ -4846,80 +4958,80 @@ class AllPlatformTests(BasePlatformTests): }, }, 'configure': { - f'{self.builddir}/foo-notag.h': { + get_path(f'{self.builddir}/foo-notag.h'): { 'destination': '{datadir}/foo-notag.h', 'tag': None, 'subproject': None, }, - f'{self.builddir}/foo2-devel.h': { + get_path(f'{self.builddir}/foo2-devel.h'): { 'destination': '{includedir}/foo2-devel.h', 'tag': 'devel', 'subproject': None, }, - f'{self.builddir}/foo-custom.h': { + get_path(f'{self.builddir}/foo-custom.h'): { 'destination': '{datadir}/foo-custom.h', 'tag': 'custom', 'subproject': None, }, - f'{self.builddir}/subdir/foo2.h': { + get_path(f'{self.builddir}/subdir/foo2.h'): { 'destination': '{datadir}/foo2.h', 'tag': None, 'subproject': None, }, }, 'data': { - f'{testdir}/bar-notag.txt': { + get_path(f'{testdir}/bar-notag.txt'): { 'destination': '{datadir}/bar-notag.txt', 'tag': None, 'subproject': None, }, - f'{testdir}/bar-devel.h': { + get_path(f'{testdir}/bar-devel.h'): { 'destination': '{includedir}/bar-devel.h', 'tag': 'devel', 'subproject': None, }, - f'{testdir}/bar-custom.txt': { + get_path(f'{testdir}/bar-custom.txt'): { 'destination': '{datadir}/bar-custom.txt', 'tag': 'custom', 'subproject': None, }, - f'{testdir}/subdir/bar2-devel.h': { + get_path(f'{testdir}/subdir/bar2-devel.h'): { 'destination': '{includedir}/bar2-devel.h', 'tag': 'devel', 'subproject': None, }, - f'{testdir}/subprojects/subproject/aaa.txt': { + get_path(f'{testdir}/subprojects/subproject/aaa.txt'): { 'destination': '{datadir}/subproject/aaa.txt', 'tag': None, 'subproject': 'subproject', }, - f'{testdir}/subprojects/subproject/bbb.txt': { + get_path(f'{testdir}/subprojects/subproject/bbb.txt'): { 'destination': '{datadir}/subproject/bbb.txt', 'tag': 'data', 'subproject': 'subproject', }, }, 'headers': { - f'{testdir}/foo1-devel.h': { + get_path(f'{testdir}/foo1-devel.h'): { 'destination': '{includedir}/foo1-devel.h', 'tag': 'devel', 'subproject': None, }, - f'{testdir}/subdir/foo3-devel.h': { + get_path(f'{testdir}/subdir/foo3-devel.h'): { 'destination': '{includedir}/foo3-devel.h', 'tag': 'devel', 'subproject': None, }, }, 'install_subdirs': { - f'{testdir}/custom_files': { + get_path(f'{testdir}/custom_files'): { 'destination': '{datadir}/custom_files', 'tag': 'custom', 'subproject': None, 'exclude_dirs': [], 'exclude_files': [], }, - f'{testdir}/excludes': { + get_path(f'{testdir}/excludes'): { 'destination': '{datadir}/excludes', 'tag': 'custom', 'subproject': None, @@ -4929,11 +5041,10 @@ class AllPlatformTests(BasePlatformTests): } } - fix_path = lambda path: os.path.sep.join(path.split('/')) expected_fixed = { data_type: { - fix_path(source): { - key: fix_path(value) if key == 'destination' else value + get_path(source): { + key: get_path(value) if key == 'destination' else value for key, value in attributes.items() } for source, attributes in files.items() @@ -4944,6 +5055,7 @@ class AllPlatformTests(BasePlatformTests): for data_type, files in expected_fixed.items(): for file, details in files.items(): with self.subTest(key='{}.{}'.format(data_type, file)): + if data_type == 'data': print(res[data_type]) self.assertEqual(res[data_type][file], details) @skip_if_not_language('rust') @@ -5015,7 +5127,7 @@ class AllPlatformTests(BasePlatformTests): }} ''') - testdir = os.path.join(self.unit_test_dir, '101 rlib linkage') + testdir = os.path.join(self.unit_test_dir, '102 rlib linkage') gen_file = os.path.join(testdir, 'lib.rs') with open(gen_file, 'w', encoding='utf-8') as f: f.write(template.format(0)) @@ -5063,7 +5175,7 @@ class AllPlatformTests(BasePlatformTests): return def test_custom_target_name(self): - testdir = os.path.join(self.unit_test_dir, '99 custom target name') + testdir = os.path.join(self.unit_test_dir, '100 custom target name') self.init(testdir) out = self.build() if self.backend is Backend.ninja: @@ -5071,7 +5183,7 @@ class AllPlatformTests(BasePlatformTests): self.assertIn('Generating subdir/file.txt with a custom command', out) def test_symlinked_subproject(self): - testdir = os.path.join(self.unit_test_dir, '107 subproject symlink') + testdir = os.path.join(self.unit_test_dir, '108 subproject symlink') subproject_dir = os.path.join(testdir, 'subprojects') subproject = os.path.join(testdir, 'symlinked_subproject') symlinked_subproject = os.path.join(testdir, 'subprojects', 'symlinked_subproject') @@ -5087,7 +5199,7 @@ class AllPlatformTests(BasePlatformTests): self.build() def test_configure_same_noop(self): - testdir = os.path.join(self.unit_test_dir, '109 configure same noop') + testdir = os.path.join(self.unit_test_dir, '110 configure same noop') args = [ '-Dstring=val', '-Dboolean=true', @@ -5125,7 +5237,7 @@ class AllPlatformTests(BasePlatformTests): def __test_multi_stds(self, test_c: bool = True, test_objc: bool = False) -> None: assert test_c or test_objc, 'must test something' - testdir = os.path.join(self.unit_test_dir, '115 c cpp stds') + testdir = os.path.join(self.unit_test_dir, '116 c cpp stds') self.init(testdir, extra_args=[f'-Dwith-c={str(test_c).lower()}', f'-Dwith-objc={str(test_objc).lower()}']) # Invalid values should fail whatever compiler we have @@ -5184,7 +5296,7 @@ class AllPlatformTests(BasePlatformTests): self.__test_multi_stds(test_objc=True) def test_slice(self): - testdir = os.path.join(self.unit_test_dir, '126 test slice') + testdir = os.path.join(self.unit_test_dir, '128 test slice') self.init(testdir) self.build() @@ -5196,7 +5308,7 @@ class AllPlatformTests(BasePlatformTests): '10/10': [10], }.items(): output = self._run(self.mtest_command + ['--slice=' + arg]) - tests = sorted([ int(x[5:]) for x in re.findall(r'test-[0-9]*', output) ]) + tests = sorted([ int(x) for x in re.findall(r'\n[ 0-9]+/[0-9]+ test-([0-9]*)', output) ]) self.assertEqual(tests, expectation) for arg, expectation in {'': 'error: argument --slice: value does not conform to format \'SLICE/NUM_SLICES\'', @@ -5216,13 +5328,13 @@ class AllPlatformTests(BasePlatformTests): env = get_fake_env() cc = detect_c_compiler(env, MachineChoice.HOST) has_rsp = cc.linker.id in { - 'ld.bfd', 'ld.gold', 'ld.lld', 'ld.mold', 'ld.qcld', 'ld.wasm', + 'ld.bfd', 'ld.eld', 'ld.gold', 'ld.lld', 'ld.mold', 'ld.qcld', 'ld.wasm', 'link', 'lld-link', 'mwldarm', 'mwldeppc', 'optlink', 'xilink', } self.assertEqual(cc.linker.get_accepts_rsp(), has_rsp) def test_nonexisting_bargs(self): - testdir = os.path.join(self.unit_test_dir, '116 empty project') + testdir = os.path.join(self.unit_test_dir, '117 empty project') args = ['-Db_ndebug=if_release'] self.init(testdir, extra_args=args) @@ -5232,7 +5344,7 @@ class AllPlatformTests(BasePlatformTests): self.init(testdir, extra_args=['--wipe']) def test_interactive_tap(self): - testdir = os.path.join(self.unit_test_dir, '124 interactive tap') + testdir = os.path.join(self.unit_test_dir, '125 interactive tap') self.init(testdir, extra_args=['--wrap-mode=forcefallback']) output = self._run(self.mtest_command + ['--interactive']) self.assertRegex(output, r'Ok:\s*0') |