aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmeson.py9
-rw-r--r--mesonbuild/build.py4
-rw-r--r--mesonbuild/dependencies/base.py17
-rw-r--r--mesonbuild/mesonlib.py48
-rw-r--r--mesonbuild/mesonmain.py8
-rw-r--r--mesonbuild/scripts/commandrunner.py24
-rwxr-xr-xrun_cross_test.py2
-rwxr-xr-xrun_project_tests.py13
-rwxr-xr-xrun_tests.py22
-rwxr-xr-xrun_unittests.py5
10 files changed, 79 insertions, 73 deletions
diff --git a/meson.py b/meson.py
index abbac6f..8f944c7 100755
--- a/meson.py
+++ b/meson.py
@@ -15,12 +15,7 @@
# limitations under the License.
from mesonbuild import mesonmain
-import sys, os
-
-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)
+import sys
if __name__ == '__main__':
- sys.exit(main())
+ sys.exit(mesonmain.main())
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 362a6de..b6399bb 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -789,6 +789,10 @@ This will become a hard error in a future Meson release.''')
else:
if not isinstance(name_suffix, str):
raise InvalidArguments('name_suffix must be a string.')
+ if name_suffix == '':
+ raise InvalidArguments('name_suffix should not be an empty string. '
+ 'If you want meson to use the default behaviour '
+ 'for each platform pass `[]` (empty array)')
self.suffix = name_suffix
self.name_suffix_set = True
if isinstance(self, StaticLibrary):
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 0114a14..cc3c2d0 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -742,6 +742,17 @@ class ExternalProgram:
self.command = listify(command)
else:
self.command = self._search(name, search_dir)
+
+ # Set path to be the last item that is actually a file (in order to
+ # skip options in something like ['python', '-u', 'file.py']. If we
+ # can't find any components, default to the last component of the path.
+ self.path = self.command[-1]
+ for i in range(len(self.command) - 1, -1, -1):
+ arg = self.command[i]
+ if arg is not None and os.path.isfile(arg):
+ self.path = arg
+ break
+
if not silent:
if self.found():
mlog.log('Program', mlog.bold(name), 'found:', mlog.green('YES'),
@@ -889,11 +900,7 @@ class ExternalProgram:
return self.command[:]
def get_path(self):
- if self.found():
- # Assume that the last element is the full path to the script or
- # binary being run
- return self.command[-1]
- return None
+ return self.path
def get_name(self):
return self.name
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index fe426c5..28ae7b5 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 = python_command + ['-m', 'mesonbuild.mesonmain']
def is_ascii_string(astring):
try:
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 4a977a1..d77d148 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -382,3 +382,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/commandrunner.py b/mesonbuild/scripts/commandrunner.py
index fc65e5b..5922c64 100644
--- a/mesonbuild/scripts/commandrunner.py
+++ b/mesonbuild/scripts/commandrunner.py
@@ -59,9 +59,27 @@ def run(args):
subdir = args[2]
meson_command = args[3]
if 'python' in meson_command: # Hack.
- meson_command = [meson_command, args[4]]
- command = args[5]
- arguments = args[6:]
+ # Handle any of these:
+ # python meson.py ...
+ # python -m mesonbuild.mesonmain ...
+ # python ARGS -m mesonbuild.mesonmain ...
+ # python -m mesonbuild.mesonmain ARGS ...
+ i = 4
+ while i < len(args):
+ arg = args[i]
+ # Skip past optional arguments.
+ if arg[0] == '-':
+ if arg == '-m':
+ # Skip past -m PYTHONFILE.
+ i += 2
+ else:
+ i += 1
+ else:
+ break
+ end = i
+ meson_command = args[3:end]
+ command = args[end]
+ arguments = args[end + 1:]
else:
meson_command = [meson_command]
command = args[4]
diff --git a/run_cross_test.py b/run_cross_test.py
index 7191402..22e1972 100755
--- a/run_cross_test.py
+++ b/run_cross_test.py
@@ -28,6 +28,7 @@ from pathlib import Path
from run_project_tests import gather_tests, run_tests, StopException, setup_commands
from run_project_tests import failing_logs
+from run_tests import setup_pythonpath
def runtests(cross_file):
commontests = [('common', gather_tests(Path('test cases', 'common')), False)]
@@ -46,5 +47,6 @@ def runtests(cross_file):
if __name__ == '__main__':
setup_commands('ninja')
+ setup_pythonpath()
cross_file = sys.argv[1]
runtests(cross_file)
diff --git a/run_project_tests.py b/run_project_tests.py
index 3801432..644c6c3 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -41,7 +41,7 @@ import re
from run_unittests import get_fake_options, run_configure
from run_tests import get_backend_commands, get_backend_args_for_dir, Backend
-from run_tests import ensure_backend_detects_changes
+from run_tests import ensure_backend_detects_changes, setup_pythonpath
class BuildStep(Enum):
@@ -88,12 +88,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 +318,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(mesonlib.meson_command, gen_args)
try:
logfile = Path(test_build_dir, 'meson-logs', 'meson-log.txt')
mesonlog = logfile.open(errors='ignore', encoding='utf-8').read()
@@ -647,7 +641,7 @@ 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()
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
print('Checking that configuring works...')
@@ -692,6 +686,7 @@ if __name__ == '__main__':
setup_commands(options.backend)
detect_system_compiler()
+ setup_pythonpath()
script_dir = os.path.split(__file__)[0]
if script_dir != '':
os.chdir(script_dir)
diff --git a/run_tests.py b/run_tests.py
index 648e6ce..731d864 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -42,6 +42,28 @@ if mesonlib.is_windows() or mesonlib.is_cygwin():
else:
exe_suffix = ''
+def setup_pythonpath():
+ # Make sure python can import mesonbuild, even if we change directories as
+ # some tests do. Since sys.path is the final product of fairly complex code
+ # in site.py, it's hard to tell where each entry came from just by looking
+ # at sys.path, so we don't know if a given entry was set from a relative or
+ # absolute path. If an entry was set from a relative path, it won't
+ # continue to work if we change directories. Instead of trying to guess
+ # where a given entry came from, just add the known-good mesonbuild to
+ # PYTHONPATH so that it will continue to be importable from other
+ # directories.
+ import mesonbuild
+ meson_dir = os.path.dirname(os.path.abspath(mesonbuild.__file__))
+ meson_root = os.path.realpath(os.path.join(meson_dir, os.pardir))
+ try:
+ python_path = os.environ['PYTHONPATH']
+ except KeyError:
+ python_path = meson_root
+ else:
+ paths = python_path.split(os.pathsep) + [meson_root]
+ python_path = os.pathsep.join(paths)
+ os.environ['PYTHONPATH'] = python_path
+
def get_backend_args_for_dir(backend, builddir):
'''
Visual Studio backend needs to be given the solution to build
diff --git a/run_unittests.py b/run_unittests.py
index fb9fb03..2d4bd27 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -47,7 +47,7 @@ import mesonbuild.modules.pkgconfig
from run_tests import exe_suffix, get_fake_options
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 should_run_linux_cross_tests
+from run_tests import should_run_linux_cross_tests, setup_pythonpath
def get_dynamic_section_entry(fname, entry):
@@ -3303,7 +3303,7 @@ class RewriterTests(unittest.TestCase):
def unset_envs():
- # For unit tests we must fully control all commend lines
+ # For unit tests we must fully control all command lines
# so that there are no unexpected changes coming from the
# environment, for example when doing a package build.
varnames = ['CPPFLAGS', 'LDFLAGS'] + list(mesonbuild.environment.cflags_mapping.values())
@@ -3313,6 +3313,7 @@ def unset_envs():
if __name__ == '__main__':
unset_envs()
+ setup_pythonpath()
cases = ['InternalTests', 'AllPlatformTests', 'FailureTests', 'PythonTests']
if not is_windows():
cases += ['LinuxlikeTests']