Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
#!/usr/bin/env python3
|
2023-12-14 03:38:41 +08:00
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
# Copyright 2018 The Meson development team
|
|
|
|
|
|
|
|
import os
|
|
|
|
import tempfile
|
|
|
|
import unittest
|
|
|
|
import subprocess
|
2018-08-03 21:17:21 +08:00
|
|
|
import zipapp
|
2022-10-05 19:53:56 +08:00
|
|
|
import sysconfig
|
2020-11-21 06:56:29 +08:00
|
|
|
from pathlib import Path
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
|
|
|
|
from mesonbuild.mesonlib import windows_proof_rmtree, python_command, is_windows
|
2020-05-15 01:55:46 +08:00
|
|
|
from mesonbuild.coredata import version as meson_version
|
|
|
|
|
2022-10-05 19:53:56 +08:00
|
|
|
scheme = None
|
|
|
|
|
|
|
|
def needs_debian_path_hack():
|
|
|
|
try:
|
|
|
|
import setuptools
|
|
|
|
return int(setuptools.__version__.split('.')[0]) < 65
|
|
|
|
except ModuleNotFoundError:
|
|
|
|
return False
|
|
|
|
|
|
|
|
if needs_debian_path_hack():
|
|
|
|
# Handle the scheme that Debian patches in the as default
|
|
|
|
# This function was renamed and made public in Python 3.10
|
|
|
|
if hasattr(sysconfig, 'get_default_scheme'):
|
|
|
|
scheme = sysconfig.get_default_scheme()
|
|
|
|
else:
|
|
|
|
scheme = sysconfig._get_default_scheme()
|
|
|
|
if scheme == 'posix_local':
|
|
|
|
scheme = 'posix_prefix'
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
|
|
|
|
def get_pypath():
|
2022-10-05 19:53:56 +08:00
|
|
|
if scheme:
|
|
|
|
pypath = sysconfig.get_path('purelib', scheme=scheme, vars={'base': ''})
|
|
|
|
else:
|
|
|
|
pypath = sysconfig.get_path('purelib', vars={'base': ''})
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
# Ensure that / is the path separator and not \, then strip /
|
|
|
|
return Path(pypath).as_posix().strip('/')
|
|
|
|
|
|
|
|
def get_pybindir():
|
|
|
|
# 'Scripts' on Windows and 'bin' on other platforms including MSYS
|
2022-10-05 19:53:56 +08:00
|
|
|
if scheme:
|
|
|
|
return sysconfig.get_path('scripts', scheme=scheme, vars={'base': ''}).strip('\\/')
|
|
|
|
return sysconfig.get_path('scripts', vars={'base': ''}).strip('\\/')
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
|
|
|
|
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()
|
|
|
|
|
2023-01-16 09:15:03 +08:00
|
|
|
def _run(self, command, workdir=None, env=None):
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
'''
|
2018-10-09 01:05:36 +08:00
|
|
|
Run a command while printing the stdout, and also return a copy of it
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
'''
|
|
|
|
# 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,
|
2023-01-16 09:15:03 +08:00
|
|
|
env=env, text=True,
|
2018-10-09 01:05:36 +08:00
|
|
|
cwd=workdir, timeout=60 * 5)
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
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)
|
2021-03-05 06:16:11 +08:00
|
|
|
self.assertEqual(line, f'meson_command is {cmd!r}')
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
|
|
|
|
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')
|
2022-11-17 14:43:44 +08:00
|
|
|
(bindir / 'python3').symlink_to(python_command[0])
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
os.environ['PATH'] = str(bindir) + os.pathsep + os.environ['PATH']
|
2022-11-17 14:43:44 +08:00
|
|
|
# use our overridden PATH-compatible python
|
do not resolve symlinks when calculating the meson command
We embed the route to executing meson in various cases, most especially
regen rules in build.ninja. And we take care to ensure that it's a
canonicalized path. Although the code has moved around over time, and
adapted in ways both bad and good, the root of the matter really comes
down to commit 69ca8f5b544f700210d9f18613311bcce3c2e37a which notes the
importance of being able to run meson from any location, potentially
not on PATH or anything else.
For this reason, we switched from embedding sys.argv[0] to
os.path.realpath, a very heavy stick indeed. It turns out that that's
not actually a good thing though... simply resolving the absolute path
is enough to ensure we can accurately call meson the same way we
originally did, and it avoids cases where the original way to call meson
is via a stable symlink, and we resolved a hidden location.
Homebrew does this, because the version of a package is embedded into
the install directory. Even the bugfix release. e.g.
```
/opt/homebrew/bin/meson
```
is symlinked to
```
/opt/homebrew/Cellar/meson/1.0.0/bin/meson
```
Since we went beyond absolutizing the path and onwards to canonicalizing
symlinks, we ended up writing the latter to build.ninja, and got a
"command not found" when meson was upgraded to 1.0.1. This was supposed
to work flawlessly, because build directories are compatible across
bugfix releases.
We also get a "command not found" when upgrading to new feature
releases, e.g. 0.64.x to 1.0.0, which is a terrible error message. Meson
explicitly "doesn't support" doing this, we throw a MesonVersionMismatchException
or in some cases warn you and then effectively act like --wipe was given.
But the user is supposed to be informed exactly what the problem is, rather
than getting "command not found".
Since there was never a rationale to get the realpath anyways, downgrade
this to abspath.
Fixes #11520
2023-03-15 11:09:56 +08:00
|
|
|
path_resolved_meson_command = [str(bindir / 'meson')]
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
# 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])
|
2022-11-17 14:43:44 +08:00
|
|
|
self.assertMesonCommandIs(stdo.split('\n')[0], path_resolved_meson_command)
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
|
|
|
|
def test_meson_installed(self):
|
|
|
|
# Install meson
|
|
|
|
prefix = self.tmpdir / 'prefix'
|
|
|
|
pylibdir = prefix / get_pypath()
|
|
|
|
bindir = prefix / get_pybindir()
|
|
|
|
pylibdir.mkdir(parents=True)
|
2018-11-14 02:48:12 +08:00
|
|
|
# XXX: join with empty name so it always ends with os.sep otherwise
|
|
|
|
# distutils complains that prefix isn't contained in PYTHONPATH
|
|
|
|
os.environ['PYTHONPATH'] = os.path.join(str(pylibdir), '')
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
os.environ['PATH'] = str(bindir) + os.pathsep + os.environ['PATH']
|
|
|
|
self._run(python_command + ['setup.py', 'install', '--prefix', str(prefix)])
|
2020-07-18 00:17:47 +08:00
|
|
|
# Fix importlib-metadata by appending all dirs in pylibdir
|
|
|
|
PYTHONPATHS = [pylibdir] + [x for x in pylibdir.iterdir()]
|
|
|
|
PYTHONPATHS = [os.path.join(str(x), '') for x in PYTHONPATHS]
|
|
|
|
os.environ['PYTHONPATH'] = os.pathsep.join(PYTHONPATHS)
|
2018-08-12 03:25:04 +08:00
|
|
|
# Check that all the files were installed correctly
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
self.assertTrue(bindir.is_dir())
|
2018-08-12 03:25:04 +08:00
|
|
|
self.assertTrue(pylibdir.is_dir())
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
# Run `meson`
|
|
|
|
os.chdir('/')
|
2018-08-10 18:35:07 +08:00
|
|
|
resolved_meson_command = [str(bindir / 'meson')]
|
|
|
|
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)
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
# Run `/path/to/meson`
|
|
|
|
builddir = str(self.tmpdir / 'build2')
|
2018-08-10 18:35:07 +08:00
|
|
|
meson_setup = [str(bindir / 'meson'), 'setup']
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
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`
|
2018-08-10 18:35:07 +08:00
|
|
|
resolved_meson_command = [str(bindir / 'meson.real')]
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
builddir = str(self.tmpdir / 'build4')
|
|
|
|
(bindir / 'meson').rename(bindir / 'meson.real')
|
|
|
|
wrapper = (bindir / 'meson')
|
2021-06-23 04:59:16 +08:00
|
|
|
wrapper.write_text('#!/bin/sh\n\nmeson.real "$@"', encoding='utf-8')
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
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')
|
|
|
|
|
2018-08-03 21:17:21 +08:00
|
|
|
def test_meson_zipapp(self):
|
|
|
|
if is_windows():
|
|
|
|
raise unittest.SkipTest('NOT IMPLEMENTED')
|
2020-11-25 04:41:56 +08:00
|
|
|
source = Path(__file__).resolve().parent
|
2018-08-03 21:17:21 +08:00
|
|
|
target = self.tmpdir / 'meson.pyz'
|
2020-11-25 04:41:56 +08:00
|
|
|
script = source / 'packaging' / 'create_zipapp.py'
|
|
|
|
self._run([script.as_posix(), source, '--outfile', target, '--interpreter', python_command[0]])
|
2018-08-03 21:17:21 +08:00
|
|
|
self._run([target.as_posix(), '--help'])
|
|
|
|
|
2023-01-16 09:15:03 +08:00
|
|
|
def test_meson_runpython(self):
|
|
|
|
meson_command = str(self.src_root / 'meson.py')
|
|
|
|
script_file = str(self.src_root / 'foo.py')
|
|
|
|
test_command = 'import sys; print(sys.argv[1])'
|
|
|
|
env = os.environ.copy()
|
|
|
|
del env['MESON_COMMAND_TESTS']
|
|
|
|
with open(script_file, 'w') as f:
|
|
|
|
f.write('#!/usr/bin/env python3\n\n')
|
|
|
|
f.write(f'{test_command}\n')
|
|
|
|
|
|
|
|
for cmd in [['-c', test_command, 'fake argument'], [script_file, 'fake argument']]:
|
|
|
|
pyout = self._run(python_command + cmd)
|
|
|
|
mesonout = self._run(python_command + [meson_command, 'runpython'] + cmd, env=env)
|
|
|
|
self.assertEqual(pyout, mesonout)
|
|
|
|
|
2018-10-11 03:17:24 +08:00
|
|
|
|
Set the meson command to use when we know what it is
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
2018-06-01 15:30:17 +08:00
|
|
|
if __name__ == '__main__':
|
2020-05-15 02:04:32 +08:00
|
|
|
print('Meson build system', meson_version, 'Command Tests')
|
2020-05-15 01:55:46 +08:00
|
|
|
raise SystemExit(unittest.main(buffer=True))
|