diff options
-rwxr-xr-x | meson.py | 17 | ||||
-rw-r--r-- | mesonbuild/environment.py | 6 | ||||
-rw-r--r-- | mesonbuild/mesonlib.py | 48 | ||||
-rw-r--r-- | mesonbuild/mesonmain.py | 34 | ||||
-rw-r--r-- | mesonbuild/scripts/regen_checker.py | 6 | ||||
-rwxr-xr-x | run_meson_command_tests.py | 186 | ||||
-rwxr-xr-x | run_project_tests.py | 20 | ||||
-rwxr-xr-x | run_tests.py | 43 | ||||
-rwxr-xr-x | run_unittests.py | 64 |
9 files changed, 297 insertions, 127 deletions
@@ -14,13 +14,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -from mesonbuild import mesonmain -import sys, os +import sys +from pathlib import Path + +# If we're run uninstalled, add the script directory to sys.path to ensure that +# we always import the correct mesonbuild modules even if PYTHONPATH is mangled +meson_exe = Path(sys.argv[0]).resolve() +if (meson_exe.parent / 'mesonbuild').is_dir(): + sys.path.insert(0, meson_exe.parent) -def main(): - # Always resolve the command path so Ninja can find it for regen, tests, etc. - launcher = os.path.realpath(sys.argv[0]) - return mesonmain.run(sys.argv[1:], launcher) +from mesonbuild import mesonmain if __name__ == '__main__': - sys.exit(main()) + sys.exit(mesonmain.main()) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index fc837d6..4bcffbd 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -262,10 +262,9 @@ class Environment: private_dir = 'meson-private' log_dir = 'meson-logs' - def __init__(self, source_dir, build_dir, main_script_launcher, options, original_cmd_line_args): + def __init__(self, source_dir, build_dir, options, original_cmd_line_args): self.source_dir = source_dir self.build_dir = build_dir - self.meson_script_launcher = main_script_launcher self.scratch_dir = os.path.join(build_dir, Environment.private_dir) self.log_dir = os.path.join(build_dir, Environment.log_dir) os.makedirs(self.scratch_dir, exist_ok=True) @@ -278,7 +277,8 @@ class Environment: # re-initialized with project options by the interpreter during # build file parsing. self.coredata = coredata.CoreData(options) - self.coredata.meson_script_launcher = self.meson_script_launcher + # Used by the regenchecker script, which runs meson + self.coredata.meson_command = mesonlib.meson_command self.first_invocation = True if self.coredata.cross_file: self.cross_info = CrossBuildInfo(self.coredata.cross_file) diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 6a38479..5305ecb 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -38,58 +38,12 @@ except Exception: from glob import glob -def detect_meson_py_location(): - c = sys.argv[0] - c_dir, c_fname = os.path.split(c) - - # get the absolute path to the <mesontool> folder - m_dir = None - if os.path.isabs(c): - # $ /foo/<mesontool>.py <args> - m_dir = c_dir - elif c_dir == '': - # $ <mesontool> <args> (gets run from /usr/bin/<mesontool>) - in_path_exe = shutil.which(c_fname) - if in_path_exe: - if not os.path.isabs(in_path_exe): - m_dir = os.getcwd() - c_fname = in_path_exe - else: - m_dir, c_fname = os.path.split(in_path_exe) - else: - m_dir = os.path.abspath(c_dir) - - # find meson in m_dir - if m_dir is not None: - for fname in ['meson', 'meson.py']: - m_path = os.path.join(m_dir, fname) - if os.path.exists(m_path): - return m_path - - # No meson found, which means that either: - # a) meson is not installed - # b) meson is installed to a non-standard location - # c) the script that invoked mesonlib is not the one of meson tools (e.g. run_unittests.py) - fname = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'meson.py')) - if os.path.exists(fname): - return fname - # If meson is still not found, we might be imported by out-of-source tests - # https://github.com/mesonbuild/meson/issues/3015 - exe = shutil.which('meson') - if exe is None: - exe = shutil.which('meson.py') - if exe is not None: - return exe - # Give up. - raise RuntimeError('Could not determine how to run Meson. Please file a bug with details.') - if os.path.basename(sys.executable) == 'meson.exe': # In Windows and using the MSI installed executable. - meson_command = [sys.executable] python_command = [sys.executable, 'runpython'] else: python_command = [sys.executable] - meson_command = python_command + [detect_meson_py_location()] +meson_command = None def is_ascii_string(astring): try: diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py index 4a977a1..c03ef9b 100644 --- a/mesonbuild/mesonmain.py +++ b/mesonbuild/mesonmain.py @@ -73,9 +73,8 @@ def filter_builtin_options(args, original_args): class MesonApp: - def __init__(self, dir1, dir2, script_launcher, handshake, options, original_cmd_line_args): + def __init__(self, dir1, dir2, handshake, options, original_cmd_line_args): (self.source_dir, self.build_dir) = self.validate_dirs(dir1, dir2, handshake) - self.meson_script_launcher = script_launcher self.options = options self.original_cmd_line_args = original_cmd_line_args @@ -129,7 +128,7 @@ class MesonApp: env.coredata.pkgconf_envvar = curvar def generate(self): - env = environment.Environment(self.source_dir, self.build_dir, self.meson_script_launcher, self.options, self.original_cmd_line_args) + env = environment.Environment(self.source_dir, self.build_dir, self.options, self.original_cmd_line_args) mlog.initialize(env.get_log_dir()) with mesonlib.BuildDirLock(self.build_dir): self._generate(env) @@ -269,12 +268,27 @@ def run_script_command(args): raise MesonException('Unknown internal command {}.'.format(cmdname)) return cmdfunc(cmdargs) -def run(original_args, mainfile=None): +def set_meson_command(mainfile): + if mainfile.endswith('.exe'): + mesonlib.meson_command = [mainfile] + elif os.path.isabs(mainfile) and mainfile.endswith('mesonmain.py'): + # Can't actually run meson with an absolute path to mesonmain.py, it must be run as -m mesonbuild.mesonmain + mesonlib.meson_command = mesonlib.python_command + ['-m', 'mesonbuild.mesonmain'] + else: + mesonlib.meson_command = mesonlib.python_command + [mainfile] + # This won't go into the log file because it's not initialized yet, and we + # need this value for unit tests. + if 'MESON_COMMAND_TESTS' in os.environ: + mlog.log('meson_command is {!r}'.format(mesonlib.meson_command)) + +def run(original_args, mainfile): if sys.version_info < (3, 5): print('Meson works correctly only with python 3.5+.') print('You have python %s.' % sys.version) print('Please update your environment') return 1 + # Set the meson command that will be used to run scripts and so on + set_meson_command(mainfile) args = original_args[:] if len(args) > 0: # First check if we want to run a subcommand. @@ -352,9 +366,7 @@ def run(original_args, mainfile=None): else: dir2 = '.' try: - if mainfile is None: - raise AssertionError('I iz broken. Sorry.') - app = MesonApp(dir1, dir2, mainfile, handshake, options, original_args) + app = MesonApp(dir1, dir2, handshake, options, original_args) except Exception as e: # Log directory does not exist, so just print # to stdout. @@ -382,3 +394,11 @@ def run(original_args, mainfile=None): mlog.shutdown() return 0 + +def main(): + # Always resolve the command path so Ninja can find it for regen, tests, etc. + launcher = os.path.realpath(sys.argv[0]) + return run(sys.argv[1:], launcher) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/mesonbuild/scripts/regen_checker.py b/mesonbuild/scripts/regen_checker.py index a9b00c7..80d9242 100644 --- a/mesonbuild/scripts/regen_checker.py +++ b/mesonbuild/scripts/regen_checker.py @@ -14,7 +14,6 @@ import sys, os import pickle, subprocess -from mesonbuild.mesonlib import meson_command # This could also be used for XCode. @@ -32,7 +31,7 @@ def need_regen(regeninfo, regen_timestamp): Vs2010Backend.touch_regen_timestamp(regeninfo.build_dir) return False -def regen(regeninfo, mesonscript, backend): +def regen(regeninfo, meson_command, backend): cmd = meson_command + ['--internal', 'regenerate', regeninfo.build_dir, @@ -48,11 +47,10 @@ def run(args): regeninfo = pickle.load(f) with open(coredata, 'rb') as f: coredata = pickle.load(f) - mesonscript = coredata.meson_script_launcher backend = coredata.get_builtin_option('backend') regen_timestamp = os.stat(dumpfile).st_mtime if need_regen(regeninfo, regen_timestamp): - regen(regeninfo, mesonscript, backend) + regen(regeninfo, coredata.meson_command, backend) sys.exit(0) if __name__ == '__main__': diff --git a/run_meson_command_tests.py b/run_meson_command_tests.py new file mode 100755 index 0000000..6efd911 --- /dev/null +++ b/run_meson_command_tests.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 + +# Copyright 2018 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 os +import tempfile +import unittest +import subprocess +from pathlib import Path + +from mesonbuild.mesonlib import windows_proof_rmtree, python_command, is_windows + +# Find the meson.py adjacent to us +meson_py = Path(__file__).resolve().parent / 'meson.py' +if not meson_py.is_file(): + raise RuntimeError("meson.py not found: test must only run from git") + +def get_pypath(): + import sysconfig + pypath = sysconfig.get_path('purelib', vars={'base': ''}) + # Ensure that / is the path separator and not \, then strip / + return Path(pypath).as_posix().strip('/') + +def get_pybindir(): + import sysconfig + # 'Scripts' on Windows and 'bin' on other platforms including MSYS + return sysconfig.get_path('scripts', vars={'base': ''}).strip('\\/') + +class CommandTests(unittest.TestCase): + ''' + Test that running meson in various ways works as expected by checking the + value of mesonlib.meson_command that was set during configuration. + ''' + + def setUp(self): + super().setUp() + self.orig_env = os.environ.copy() + self.orig_dir = os.getcwd() + os.environ['MESON_COMMAND_TESTS'] = '1' + self.tmpdir = Path(tempfile.mkdtemp()).resolve() + self.src_root = Path(__file__).resolve().parent + self.testdir = str(self.src_root / 'test cases/common/1 trivial') + self.meson_args = ['--backend=ninja'] + + def tearDown(self): + try: + windows_proof_rmtree(str(self.tmpdir)) + except FileNotFoundError: + pass + os.environ.clear() + os.environ.update(self.orig_env) + os.chdir(str(self.orig_dir)) + super().tearDown() + + def _run(self, command, workdir=None): + ''' + Run a command while printing the stdout and stderr to stdout, + and also return a copy of it + ''' + # If this call hangs CI will just abort. It is very hard to distinguish + # between CI issue and test bug in that case. Set timeout and fail loud + # instead. + p = subprocess.run(command, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, env=os.environ.copy(), + universal_newlines=True, cwd=workdir, timeout=60 * 5) + print(p.stdout) + if p.returncode != 0: + raise subprocess.CalledProcessError(p.returncode, command) + return p.stdout + + def assertMesonCommandIs(self, line, cmd): + self.assertTrue(line.startswith('meson_command '), msg=line) + self.assertEqual(line, 'meson_command is {!r}'.format(cmd)) + + def test_meson_uninstalled(self): + # This is what the meson command must be for all these cases + resolved_meson_command = python_command + [str(self.src_root / 'meson.py')] + # Absolute path to meson.py + os.chdir('/') + builddir = str(self.tmpdir / 'build1') + meson_py = str(self.src_root / 'meson.py') + meson_setup = [meson_py, 'setup'] + meson_command = python_command + meson_setup + self.meson_args + stdo = self._run(meson_command + [self.testdir, builddir]) + self.assertMesonCommandIs(stdo.split('\n')[0], resolved_meson_command) + # ./meson.py + os.chdir(str(self.src_root)) + builddir = str(self.tmpdir / 'build2') + meson_py = './meson.py' + meson_setup = [meson_py, 'setup'] + meson_command = python_command + meson_setup + self.meson_args + stdo = self._run(meson_command + [self.testdir, builddir]) + self.assertMesonCommandIs(stdo.split('\n')[0], resolved_meson_command) + # Symlink to meson.py + if is_windows(): + # Symlinks require admin perms + return + os.chdir(str(self.src_root)) + builddir = str(self.tmpdir / 'build3') + # Create a symlink to meson.py in bindir, and add it to PATH + bindir = (self.tmpdir / 'bin') + bindir.mkdir() + (bindir / 'meson').symlink_to(self.src_root / 'meson.py') + os.environ['PATH'] = str(bindir) + os.pathsep + os.environ['PATH'] + # See if it works! + meson_py = 'meson' + meson_setup = [meson_py, 'setup'] + meson_command = meson_setup + self.meson_args + stdo = self._run(meson_command + [self.testdir, builddir]) + self.assertMesonCommandIs(stdo.split('\n')[0], resolved_meson_command) + + def test_meson_installed(self): + # Install meson + prefix = self.tmpdir / 'prefix' + pylibdir = prefix / get_pypath() + bindir = prefix / get_pybindir() + pylibdir.mkdir(parents=True) + os.environ['PYTHONPATH'] = str(pylibdir) + os.environ['PATH'] = str(bindir) + os.pathsep + os.environ['PATH'] + self._run(python_command + ['setup.py', 'install', '--prefix', str(prefix)]) + self.assertTrue(pylibdir.is_dir()) + self.assertTrue(bindir.is_dir()) + # Run `meson` + os.chdir('/') + if is_windows(): + resolved_meson_command = python_command + [str(bindir / 'meson.py')] + else: + resolved_meson_command = python_command + [str(bindir / 'meson')] + # The python configuration on appveyor does not register .py as + # a valid extension, so we cannot run `meson` on Windows. + builddir = str(self.tmpdir / 'build1') + meson_setup = ['meson', 'setup'] + meson_command = meson_setup + self.meson_args + stdo = self._run(meson_command + [self.testdir, builddir]) + self.assertMesonCommandIs(stdo.split('\n')[0], resolved_meson_command) + # Run `/path/to/meson` + builddir = str(self.tmpdir / 'build2') + if is_windows(): + # Cannot run .py directly because of the appveyor configuration, + # and the script is named meson.py, not meson + meson_setup = python_command + [str(bindir / 'meson.py'), 'setup'] + else: + meson_setup = [str(bindir / 'meson'), 'setup'] + meson_command = meson_setup + self.meson_args + stdo = self._run(meson_command + [self.testdir, builddir]) + self.assertMesonCommandIs(stdo.split('\n')[0], resolved_meson_command) + # Run `python3 -m mesonbuild.mesonmain` + resolved_meson_command = python_command + ['-m', 'mesonbuild.mesonmain'] + builddir = str(self.tmpdir / 'build3') + meson_setup = ['-m', 'mesonbuild.mesonmain', 'setup'] + meson_command = python_command + meson_setup + self.meson_args + stdo = self._run(meson_command + [self.testdir, builddir]) + self.assertMesonCommandIs(stdo.split('\n')[0], resolved_meson_command) + if is_windows(): + # Next part requires a shell + return + # `meson` is a wrapper to `meson.real` + resolved_meson_command = python_command + [str(bindir / 'meson.real')] + builddir = str(self.tmpdir / 'build4') + (bindir / 'meson').rename(bindir / 'meson.real') + wrapper = (bindir / 'meson') + with open(wrapper, 'w') as f: + f.write('#!/bin/sh\n\nmeson.real "$@"') + wrapper.chmod(0o755) + meson_setup = [str(wrapper), 'setup'] + meson_command = meson_setup + self.meson_args + stdo = self._run(meson_command + [self.testdir, builddir]) + self.assertMesonCommandIs(stdo.split('\n')[0], resolved_meson_command) + + def test_meson_exe_windows(self): + raise unittest.SkipTest('NOT IMPLEMENTED') + +if __name__ == '__main__': + unittest.main(buffer=True) diff --git a/run_project_tests.py b/run_project_tests.py index 2669a92..0b77a37 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -38,8 +38,7 @@ import time import multiprocessing from concurrent.futures import ProcessPoolExecutor import re -from run_unittests import get_fake_options, run_configure - +from run_tests import get_fake_options, run_configure, get_meson_script from run_tests import get_backend_commands, get_backend_args_for_dir, Backend from run_tests import ensure_backend_detects_changes @@ -88,12 +87,6 @@ no_meson_log_msg = 'No meson-log.txt found.' system_compiler = None -meson_command = os.path.join(os.getcwd(), 'meson') -if not os.path.exists(meson_command): - meson_command += '.py' - if not os.path.exists(meson_command): - raise RuntimeError('Could not find main Meson script to run.') - class StopException(Exception): def __init__(self): super().__init__('Stopped by user') @@ -324,7 +317,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen if pass_libdir_to_test(testdir): gen_args += ['--libdir', 'lib'] gen_args += [testdir, test_build_dir] + flags + test_args + extra_args - (returncode, stdo, stde) = run_configure(meson_command, gen_args) + (returncode, stdo, stde) = run_configure(gen_args) try: logfile = Path(test_build_dir, 'meson-logs', 'meson-log.txt') mesonlog = logfile.open(errors='ignore', encoding='utf-8').read() @@ -417,7 +410,7 @@ def have_d_compiler(): def have_objc_compiler(): with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir: - env = environment.Environment(None, build_dir, None, get_fake_options('/'), []) + env = environment.Environment(None, build_dir, get_fake_options('/'), []) try: objc_comp = env.detect_objc_compiler(False) except mesonlib.MesonException: @@ -432,7 +425,7 @@ def have_objc_compiler(): def have_objcpp_compiler(): with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir: - env = environment.Environment(None, build_dir, None, get_fake_options('/'), []) + env = environment.Environment(None, build_dir, get_fake_options('/'), []) try: objcpp_comp = env.detect_objcpp_compiler(False) except mesonlib.MesonException: @@ -648,11 +641,12 @@ def check_format(): check_file(fullname) def check_meson_commands_work(): - global backend, meson_command, compile_commands, test_commands, install_commands + global backend, compile_commands, test_commands, install_commands testdir = PurePath('test cases', 'common', '1 trivial').as_posix() + meson_commands = mesonlib.python_command + [get_meson_script()] with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir: print('Checking that configuring works...') - gen_cmd = mesonlib.meson_command + [testdir, build_dir] + backend_flags + gen_cmd = meson_commands + [testdir, build_dir] + backend_flags pc, o, e = Popen_safe(gen_cmd) if pc.returncode != 0: raise RuntimeError('Failed to configure {!r}:\n{}\n{}'.format(testdir, e, o)) diff --git a/run_tests.py b/run_tests.py index 648e6ce..736cdc0 100755 --- a/run_tests.py +++ b/run_tests.py @@ -21,13 +21,16 @@ import shutil import subprocess import tempfile import platform +from io import StringIO +from enum import Enum +from glob import glob +from pathlib import Path + +import mesonbuild from mesonbuild import mesonlib from mesonbuild import mesonmain from mesonbuild import mlog from mesonbuild.environment import detect_ninja -from io import StringIO -from enum import Enum -from glob import glob Backend = Enum('Backend', 'ninja vs xcode') @@ -42,6 +45,28 @@ if mesonlib.is_windows() or mesonlib.is_cygwin(): else: exe_suffix = '' +def get_meson_script(): + ''' + Guess the meson that corresponds to the `mesonbuild` that has been imported + so we can run configure and other commands in-process, since mesonmain.run + needs to know the meson_command to use. + + Also used by run_unittests.py to determine what meson to run when not + running in-process (which is the default). + ''' + # Is there a meson.py next to the mesonbuild currently in use? + mesonbuild_dir = Path(mesonbuild.__file__).resolve().parent.parent + meson_script = mesonbuild_dir / 'meson.py' + if meson_script.is_file(): + return str(meson_script) + # Then if mesonbuild is in PYTHONPATH, meson must be in PATH + mlog.warning('Could not find meson.py next to the mesonbuild module. ' + 'Trying system meson...') + meson_cmd = shutil.which('meson') + if meson_cmd: + return meson_cmd + raise RuntimeError('Could not find {!r} or a meson in PATH'.format(meson_script)) + def get_backend_args_for_dir(backend, builddir): ''' Visual Studio backend needs to be given the solution to build @@ -133,13 +158,13 @@ def get_fake_options(prefix): def should_run_linux_cross_tests(): return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm') -def run_configure_inprocess(meson_command, commandlist): +def run_configure_inprocess(commandlist): old_stdout = sys.stdout sys.stdout = mystdout = StringIO() old_stderr = sys.stderr sys.stderr = mystderr = StringIO() try: - returncode = mesonmain.run(commandlist, meson_command) + returncode = mesonmain.run(commandlist, get_meson_script()) finally: sys.stdout = old_stdout sys.stderr = old_stderr @@ -149,11 +174,11 @@ def run_configure_external(full_command): pc, o, e = mesonlib.Popen_safe(full_command) return pc.returncode, o, e -def run_configure(meson_command, commandlist): +def run_configure(commandlist): global meson_exe if meson_exe: return run_configure_external(meson_exe + commandlist) - return run_configure_inprocess(meson_command, commandlist) + return run_configure_inprocess(commandlist) def print_system_info(): print(mlog.bold('System information.').get_text(mlog.colorize_console)) @@ -214,6 +239,9 @@ if __name__ == '__main__': 'coverage.process_startup()\n') env['COVERAGE_PROCESS_START'] = '.coveragerc' env['PYTHONPATH'] = os.pathsep.join([td] + env.get('PYTHONPATH', [])) + # Meson command tests + returncode += subprocess.call(mesonlib.python_command + ['run_meson_command_tests.py', '-v'], env=env) + # Unit tests returncode += subprocess.call(mesonlib.python_command + ['run_unittests.py', '-v'], env=env) # Ubuntu packages do not have a binary without -6 suffix. if should_run_linux_cross_tests(): @@ -221,5 +249,6 @@ if __name__ == '__main__': print() returncode += subprocess.call(mesonlib.python_command + ['run_cross_test.py', 'cross/ubuntu-armhf.txt'], env=env) + # Project tests returncode += subprocess.call(mesonlib.python_command + ['run_project_tests.py'] + sys.argv[1:], env=env) sys.exit(returncode) diff --git a/run_unittests.py b/run_unittests.py index 552769b..d6b2619 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -36,7 +36,7 @@ import mesonbuild.modules.gnome from mesonbuild.interpreter import ObjectHolder from mesonbuild.mesonlib import ( is_windows, is_osx, is_cygwin, is_dragonflybsd, - windows_proof_rmtree, python_command, meson_command, version_compare, + windows_proof_rmtree, python_command, version_compare, BuildDirLock ) from mesonbuild.environment import Environment, detect_ninja @@ -44,9 +44,9 @@ from mesonbuild.mesonlib import MesonException, EnvironmentException from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram import mesonbuild.modules.pkgconfig -from run_tests import exe_suffix, get_fake_options +from run_tests import exe_suffix, get_fake_options, get_meson_script from run_tests import get_builddir_target_args, get_backend_commands, Backend -from run_tests import ensure_backend_detects_changes, run_configure, meson_exe +from run_tests import ensure_backend_detects_changes, run_configure_inprocess from run_tests import should_run_linux_cross_tests @@ -488,13 +488,13 @@ class BasePlatformTests(unittest.TestCase): # Get the backend # FIXME: Extract this from argv? self.backend = getattr(Backend, os.environ.get('MESON_UNIT_TEST_BACKEND', 'ninja')) - self.meson_mainfile = os.path.join(src_root, 'meson.py') self.meson_args = ['--backend=' + self.backend.name] self.meson_cross_file = None - self.meson_command = meson_command + self.meson_args - self.mconf_command = meson_command + ['configure'] - self.mintro_command = meson_command + ['introspect'] - self.wrap_command = meson_command + ['wrap'] + self.meson_command = python_command + [get_meson_script()] + self.setup_command = self.meson_command + self.meson_args + self.mconf_command = self.meson_command + ['configure'] + self.mintro_command = self.meson_command + ['introspect'] + self.wrap_command = self.meson_command + ['wrap'] # Backend-specific build commands self.build_command, self.clean_command, self.test_command, self.install_command, \ self.uninstall_command = get_backend_commands(self.backend) @@ -521,7 +521,7 @@ class BasePlatformTests(unittest.TestCase): self.logdir = os.path.join(self.builddir, 'meson-logs') self.installdir = os.path.join(self.builddir, 'install') self.distdir = os.path.join(self.builddir, 'meson-dist') - self.mtest_command = meson_command + ['test', '-C', self.builddir] + self.mtest_command = self.meson_command + ['test', '-C', self.builddir] self.builddirs.append(self.builddir) def new_builddir(self): @@ -581,7 +581,7 @@ class BasePlatformTests(unittest.TestCase): self.privatedir = os.path.join(self.builddir, 'meson-private') if inprocess: try: - (returncode, out, err) = run_configure(self.meson_mainfile, self.meson_args + args + extra_args) + (returncode, out, err) = run_configure_inprocess(self.meson_args + args + extra_args) if 'MESON_SKIP_TEST' in out: raise unittest.SkipTest('Project requested skipping.') if returncode != 0: @@ -601,7 +601,7 @@ class BasePlatformTests(unittest.TestCase): mesonbuild.mlog.log_file = None else: try: - out = self._run(self.meson_command + args + extra_args) + out = self._run(self.setup_command + args + extra_args) except unittest.SkipTest: raise unittest.SkipTest('Project requested skipping: ' + srcdir) except: @@ -902,8 +902,7 @@ class AllPlatformTests(BasePlatformTests): https://github.com/mesonbuild/meson/issues/1355 ''' testdir = os.path.join(self.common_test_dir, '3 static') - env = Environment(testdir, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdir, self.builddir, get_fake_options(self.prefix), []) cc = env.detect_c_compiler(False) static_linker = env.detect_static_linker(cc) if is_windows(): @@ -1184,8 +1183,7 @@ class AllPlatformTests(BasePlatformTests): if not is_windows(): langs += [('objc', 'OBJC'), ('objcpp', 'OBJCXX')] testdir = os.path.join(self.unit_test_dir, '5 compiler detection') - env = Environment(testdir, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdir, self.builddir, get_fake_options(self.prefix), []) for lang, evar in langs: # Detect with evar and do sanity checks on that if evar in os.environ: @@ -1287,8 +1285,7 @@ class AllPlatformTests(BasePlatformTests): def test_always_prefer_c_compiler_for_asm(self): testdir = os.path.join(self.common_test_dir, '141 c cpp and asm') # Skip if building with MSVC - env = Environment(testdir, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdir, self.builddir, get_fake_options(self.prefix), []) if env.detect_c_compiler(False).get_id() == 'msvc': raise unittest.SkipTest('MSVC can\'t compile assembly') self.init(testdir) @@ -1546,8 +1543,7 @@ int main(int argc, char **argv) { self.assertPathExists(os.path.join(testdir, i)) def detect_prebuild_env(self): - env = Environment('', self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment('', self.builddir, get_fake_options(self.prefix), []) cc = env.detect_c_compiler(False) stlinker = env.detect_static_linker(cc) if mesonbuild.mesonlib.is_windows(): @@ -1715,8 +1711,7 @@ int main(int argc, char **argv) { '--libdir=' + libdir]) # Find foo dependency os.environ['PKG_CONFIG_LIBDIR'] = self.privatedir - env = Environment(testdir, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdir, self.builddir, get_fake_options(self.prefix), []) kwargs = {'required': True, 'silent': True} foo_dep = PkgConfigDependency('libfoo', env, kwargs) # Ensure link_args are properly quoted @@ -1849,16 +1844,16 @@ int main(int argc, char **argv) { for lang in ('c', 'cpp'): for type in ('executable', 'library'): with tempfile.TemporaryDirectory() as tmpdir: - self._run(meson_command + ['init', '--language', lang, '--type', type], + self._run(self.meson_command + ['init', '--language', lang, '--type', type], workdir=tmpdir) - self._run(self.meson_command + ['--backend=ninja', 'builddir'], + self._run(self.setup_command + ['--backend=ninja', 'builddir'], workdir=tmpdir) self._run(ninja, workdir=os.path.join(tmpdir, 'builddir')) with tempfile.TemporaryDirectory() as tmpdir: with open(os.path.join(tmpdir, 'foo.' + lang), 'w') as f: f.write('int main() {}') - self._run(meson_command + ['init', '-b'], workdir=tmpdir) + self._run(self.meson_command + ['init', '-b'], workdir=tmpdir) # The test uses mocking and thus requires that # the current process is the one to run the Meson steps. @@ -1983,8 +1978,7 @@ recommended as it can lead to undefined behaviour on some platforms''') testdirbase = os.path.join(self.unit_test_dir, '26 guessed linker dependencies') testdirlib = os.path.join(testdirbase, 'lib') extra_args = None - env = Environment(testdirlib, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdirlib, self.builddir, get_fake_options(self.prefix), []) if env.detect_c_compiler(False).get_id() != 'msvc': # static libraries are not linkable with -l with msvc because meson installs them # as .a files which unix_args_to_native will not know as it expects libraries to use @@ -2146,9 +2140,6 @@ class FailureTests(BasePlatformTests): Assert that running meson configure on the specified @contents raises a error message matching regex @match. ''' - if meson_exe is not None: - # Because the exception happens in a different process. - raise unittest.SkipTest('Can not test assert raise tests with an external Meson command.') if langs is None: langs = [] with open(self.mbuild, 'w') as f: @@ -2283,8 +2274,7 @@ class FailureTests(BasePlatformTests): ''' Test that when we can't detect objc or objcpp, we fail gracefully. ''' - env = Environment('', self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment('', self.builddir, get_fake_options(self.prefix), []) try: env.detect_objc_compiler(False) env.detect_objcpp_compiler(False) @@ -2393,8 +2383,7 @@ class WindowsTests(BasePlatformTests): ExternalLibraryHolder from build files. ''' testdir = os.path.join(self.platform_test_dir, '1 basic') - env = Environment(testdir, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdir, self.builddir, get_fake_options(self.prefix), []) cc = env.detect_c_compiler(False) if cc.id != 'msvc': raise unittest.SkipTest('Not using MSVC') @@ -2464,8 +2453,7 @@ class LinuxlikeTests(BasePlatformTests): ''' testdir = os.path.join(self.common_test_dir, '51 pkgconfig-gen') self.init(testdir) - env = Environment(testdir, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdir, self.builddir, get_fake_options(self.prefix), []) kwargs = {'required': True, 'silent': True} os.environ['PKG_CONFIG_LIBDIR'] = self.privatedir foo_dep = PkgConfigDependency('libfoo', env, kwargs) @@ -2715,8 +2703,7 @@ class LinuxlikeTests(BasePlatformTests): an ordinary test because it requires passing options to meson. ''' testdir = os.path.join(self.common_test_dir, '1 trivial') - env = Environment(testdir, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdir, self.builddir, get_fake_options(self.prefix), []) cc = env.detect_c_compiler(False) self._test_stds_impl(testdir, cc, 'c') @@ -2726,8 +2713,7 @@ class LinuxlikeTests(BasePlatformTests): be an ordinary test because it requires passing options to meson. ''' testdir = os.path.join(self.common_test_dir, '2 cpp') - env = Environment(testdir, self.builddir, self.meson_command, - get_fake_options(self.prefix), []) + env = Environment(testdir, self.builddir, get_fake_options(self.prefix), []) cpp = env.detect_cpp_compiler(False) self._test_stds_impl(testdir, cpp, 'cpp') |