From 6431a0f89d973a9096684d5670cf54b2715aa0cc Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 13 Nov 2020 14:07:26 -0800 Subject: [PATCH 1/4] run_unittests: Don't assume things are in /usr/bin This is generally a safe assumption, except for some of the more exotic OSes/distros like nixos, where env is the only thing in /usr/bin --- run_unittests.py | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index 7f7df360c..308a091c4 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -6832,13 +6832,16 @@ class LinuxlikeTests(BasePlatformTests): testdir = os.path.join(self.unit_test_dir, '11 cross prog') crossfile = tempfile.NamedTemporaryFile(mode='w') print(os.path.join(testdir, 'some_cross_tool.py')) - crossfile.write(textwrap.dedent('''\ + + tool_path = os.path.join(testdir, 'some_cross_tool.py') + + crossfile.write(textwrap.dedent(f'''\ [binaries] - c = '/usr/bin/{1}' - ar = '/usr/bin/ar' - strip = '/usr/bin/ar' - sometool.py = ['{0}'] - someothertool.py = '{0}' + c = '{shutil.which('gcc' if is_sunos() else 'cc')}' + ar = '{shutil.which('ar')}' + strip = '{shutil.which('strip')}' + sometool.py = ['{tool_path}'] + someothertool.py = '{tool_path}' [properties] @@ -6847,8 +6850,7 @@ class LinuxlikeTests(BasePlatformTests): cpu_family = 'arm' cpu = 'armv7' # Not sure if correct. endian = 'little' - ''').format(os.path.join(testdir, 'some_cross_tool.py'), - 'gcc' if is_sunos() else 'cc')) + ''')) crossfile.flush() self.meson_cross_file = crossfile.name self.init(testdir) @@ -8567,29 +8569,23 @@ class CrossFileTests(BasePlatformTests): exe_wrapper: T.Optional[T.List[str]] = None) -> str: if is_windows(): raise unittest.SkipTest('Cannot run this test on non-mingw/non-cygwin windows') - if is_sunos(): - cc = 'gcc' - else: - cc = 'cc' - return textwrap.dedent("""\ + return textwrap.dedent(f"""\ [binaries] - c = '/usr/bin/{}' - ar = '/usr/bin/ar' - strip = '/usr/bin/ar' - {} + c = '{shutil.which('gcc' if is_sunos() else 'cc')}' + ar = '{shutil.which('ar')}' + strip = '{shutil.which('strip')}' + exe_wrapper = {str(exe_wrapper) if exe_wrapper is not None else '[]'} [properties] - needs_exe_wrapper = {} + needs_exe_wrapper = {needs_exe_wrapper} [host_machine] system = 'linux' cpu_family = 'x86' cpu = 'i686' endian = 'little' - """.format(cc, - 'exe_wrapper = {}'.format(str(exe_wrapper)) if exe_wrapper is not None else '', - needs_exe_wrapper)) + """) def _stub_exe_wrapper(self) -> str: return textwrap.dedent('''\ From 85550e8fce3d2a1547db9fccc81e496d278eed90 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 13 Nov 2020 16:24:03 -0800 Subject: [PATCH 2/4] run_unittests: correctly handle users setting init.defaultBranch --- run_unittests.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index 308a091c4..4051e3be4 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -135,7 +135,15 @@ def is_pull(): return False def _git_init(project_dir): - subprocess.check_call(['git', 'init'], cwd=project_dir, stdout=subprocess.DEVNULL) + # If a user has git configuration init.defaultBranch set we want to override that + with tempfile.TemporaryDirectory() as d: + out = git(['--version'], str(d))[1] + if version_compare(mesonbuild.environment.search_version(out), '>= 2.28'): + extra_cmd = ['--initial-branch', 'master'] + else: + extra_cmd = [] + + subprocess.check_call(['git', 'init'] + extra_cmd, cwd=project_dir, stdout=subprocess.DEVNULL) subprocess.check_call(['git', 'config', 'user.name', 'Author Person'], cwd=project_dir) subprocess.check_call(['git', 'config', @@ -9154,8 +9162,16 @@ class SubprojectsCommandTests(BasePlatformTests): return self._git_remote(['rev-parse', ref], name) def _git_create_repo(self, path): + # If a user has git configuration init.defaultBranch set we want to override that + with tempfile.TemporaryDirectory() as d: + out = git(['--version'], str(d))[1] + if version_compare(mesonbuild.environment.search_version(out), '>= 2.28'): + extra_cmd = ['--initial-branch', 'master'] + else: + extra_cmd = [] + self._create_project(path) - self._git(['init'], path) + self._git(['init'] + extra_cmd, path) self._git_config(path) self._git(['add', '.'], path) self._git(['commit', '-m', 'Initial commit'], path) From 3e89c30bae2265e694212a5909a553de0484dc14 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 13 Nov 2020 16:28:21 -0800 Subject: [PATCH 3/4] unittests: Simplify and make test_templates more reliable env.detect__compiler only checks that there is a binary called whatever that returns a version. There are several cases where the found binary doesn't work: 1) gcc for ojbc[pp], when support isn't compiled in. 2) the compiler is broken (rust in appveyor somtimes) Because of that we need to call compiler.sanity_check() as well, and if we get an EnvironmentException from that skip the language Also, instead of having a long line of try: ... except: pass, roll all of the checking up into a loop using getattr(), which is less code and makes adding a new language easier --- run_unittests.py | 54 +++++++----------------------------------------- 1 file changed, 8 insertions(+), 46 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index 4051e3be4..ef5e48a4a 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -3506,53 +3506,15 @@ class AllPlatformTests(BasePlatformTests): ninja = detect_ninja() if ninja is None: raise unittest.SkipTest('This test currently requires ninja. Fix this once "meson build" works.') + langs = ['c'] env = get_fake_env() - try: - env.detect_cpp_compiler(MachineChoice.HOST) - langs.append('cpp') - except EnvironmentException: - pass - try: - env.detect_cs_compiler(MachineChoice.HOST) - langs.append('cs') - except EnvironmentException: - pass - try: - env.detect_d_compiler(MachineChoice.HOST) - langs.append('d') - except EnvironmentException: - pass - try: - env.detect_java_compiler(MachineChoice.HOST) - langs.append('java') - except EnvironmentException: - pass - try: - env.detect_cuda_compiler(MachineChoice.HOST) - langs.append('cuda') - except EnvironmentException: - pass - try: - env.detect_fortran_compiler(MachineChoice.HOST) - langs.append('fortran') - except EnvironmentException: - pass - try: - env.detect_objc_compiler(MachineChoice.HOST) - langs.append('objc') - except EnvironmentException: - pass - try: - env.detect_objcpp_compiler(MachineChoice.HOST) - langs.append('objcpp') - except EnvironmentException: - pass - # FIXME: omitting rust as Windows AppVeyor CI finds Rust but doesn't link correctly - if not is_windows(): + for l in ['cpp', 'cs', 'd', 'java', 'cuda', 'fortran', 'objc', 'objcpp', 'rust']: try: - env.detect_rust_compiler(MachineChoice.HOST) - langs.append('rust') + comp = getattr(env, f'detect_{l}_compiler')(MachineChoice.HOST) + with tempfile.TemporaryDirectory() as d: + comp.sanity_check(d, env) + langs.append(l) except EnvironmentException: pass @@ -3567,12 +3529,12 @@ class AllPlatformTests(BasePlatformTests): self._run(ninja, workdir=os.path.join(tmpdir, 'builddir')) # test directory with existing code file - if lang in ('c', 'cpp', 'd'): + if lang in {'c', 'cpp', 'd'}: with tempfile.TemporaryDirectory() as tmpdir: with open(os.path.join(tmpdir, 'foo.' + lang), 'w') as f: f.write('int main(void) {}') self._run(self.meson_command + ['init', '-b'], workdir=tmpdir) - elif lang in ('java'): + elif lang in {'java'}: with tempfile.TemporaryDirectory() as tmpdir: with open(os.path.join(tmpdir, 'Foo.' + lang), 'w') as f: f.write('public class Foo { public static void main() {} }') From 460cb9af08565b6e1c26fcec5eb19ac2d94a1776 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 16 Nov 2020 11:25:31 -0800 Subject: [PATCH 4/4] unittests: ignore nix rpaths As a necessity nix adds a bunch of rpaths to files, this is unavoidable do to the way nix package management works. Meson doesn't expect this however, and fails all rpath tests. To correct this we just ignore any rpath entries that start with `/nix`. --- run_unittests.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index ef5e48a4a..a6ca0870e 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -92,7 +92,7 @@ def chdir(path: str): os.chdir(curdir) -def get_dynamic_section_entry(fname, entry): +def get_dynamic_section_entry(fname: str, entry: str) -> T.Optional[str]: if is_cygwin() or is_osx(): raise unittest.SkipTest('Test only applicable to ELF platforms') @@ -106,14 +106,21 @@ def get_dynamic_section_entry(fname, entry): for line in raw_out.split('\n'): m = pattern.search(line) if m is not None: - return m.group(1) + return str(m.group(1)) return None # The file did not contain the specified entry. -def get_soname(fname): +def get_soname(fname: str) -> T.Optional[str]: return get_dynamic_section_entry(fname, 'soname') -def get_rpath(fname): - return get_dynamic_section_entry(fname, r'(?:rpath|runpath)') +def get_rpath(fname: str) -> T.Optional[str]: + raw = get_dynamic_section_entry(fname, r'(?:rpath|runpath)') + # Get both '' and None here + if not raw: + return None + # nix/nixos adds a bunch of stuff to the rpath out of necessity that we + # don't check for, so clear those + final = ':'.join([e for e in raw.split(':') if not e.startswith('/nix')]) + return final def is_tarball(): if not os.path.isdir('docs'):