diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2023-08-06 14:35:25 -0400 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2023-08-23 11:33:39 -0400 |
commit | 18b96cd0692255b30f8f0597cbf4af89d142a93d (patch) | |
tree | b2edf3ee61fb7b1fef7f0e697c7288923f434a51 | |
parent | bde690b06e930020a0ec6ccaea7a76babf77dff5 (diff) | |
download | meson-18b96cd0692255b30f8f0597cbf4af89d142a93d.zip meson-18b96cd0692255b30f8f0597cbf4af89d142a93d.tar.gz meson-18b96cd0692255b30f8f0597cbf4af89d142a93d.tar.bz2 |
machine file: Add @GLOBAL_SOURCE_ROOT@ and @DIRNAME@
-rw-r--r-- | docs/markdown/Machine-files.md | 12 | ||||
-rw-r--r-- | docs/markdown/snippets/machine_file_source_dir.md | 13 | ||||
-rw-r--r-- | mesonbuild/coredata.py | 19 | ||||
-rw-r--r-- | mesonbuild/environment.py | 6 | ||||
-rwxr-xr-x | run_project_tests.py | 8 | ||||
-rw-r--r-- | unittests/allplatformstests.py | 8 |
6 files changed, 51 insertions, 15 deletions
diff --git a/docs/markdown/Machine-files.md b/docs/markdown/Machine-files.md index c300769..a3e876d 100644 --- a/docs/markdown/Machine-files.md +++ b/docs/markdown/Machine-files.md @@ -128,6 +128,18 @@ b = a + 'World' a = 'Hello' ``` +*Since 1.3.0* Some tokens are replaced in the machine file before parsing it: +- `@GLOBAL_SOURCE_ROOT@`: the absolute path to the project's source tree +- `@DIRNAME@`: the absolute path to the machine file's parent directory. + +It can be used, for example, to have paths relative to the source directory, or +relative to toolchain's installation directory. +```ini +[binaries] +c = '@DIRNAME@/toolchain/gcc' +exe_wrapper = '@GLOBAL_SOURCE_ROOT@' / 'build-aux' / 'my-exe-wrapper.sh' +``` + ### Binaries The binaries section contains a list of binaries. These can be used diff --git a/docs/markdown/snippets/machine_file_source_dir.md b/docs/markdown/snippets/machine_file_source_dir.md new file mode 100644 index 0000000..5af344e --- /dev/null +++ b/docs/markdown/snippets/machine_file_source_dir.md @@ -0,0 +1,13 @@ +## `@GLOBAL_SOURCE_ROOT@` and `@DIRNAME@` in machine files + +Some tokens are now replaced in the machine file before parsing it: +- `@GLOBAL_SOURCE_ROOT@`: the absolute path to the project's source tree +- `@DIRNAME@`: the absolute path to the machine file's parent directory. + +It can be used, for example, to have paths relative to the source directory, or +relative to toolchain's installation directory. +```ini +[binaries] +c = '@DIRNAME@/toolchain/gcc' +exe_wrapper = '@GLOBAL_SOURCE_ROOT@' / 'build-aux' / 'my-exe-wrapper.sh' +``` diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index bb84f72..d59d9b8 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -964,15 +964,20 @@ class CmdLineFileParser(configparser.ConfigParser): return optionstr class MachineFileParser(): - def __init__(self, filenames: T.List[str]) -> None: + def __init__(self, filenames: T.List[str], sourcedir: str) -> None: self.parser = CmdLineFileParser() self.constants: T.Dict[str, T.Union[str, bool, int, T.List[str]]] = {'True': True, 'False': False} self.sections: T.Dict[str, T.Dict[str, T.Union[str, bool, int, T.List[str]]]] = {} - try: - self.parser.read(filenames) - except configparser.Error as e: - raise EnvironmentException(f'Malformed cross or native file: {e}') + for fname in filenames: + with open(fname, encoding='utf-8') as f: + content = f.read() + content = content.replace('@GLOBAL_SOURCE_ROOT@', sourcedir) + content = content.replace('@DIRNAME@', os.path.dirname(fname)) + try: + self.parser.read_string(content, fname) + except configparser.Error as e: + raise EnvironmentException(f'Malformed machine file: {e}') # Parse [constants] first so they can be used in other sections if self.parser.has_section('constants'): @@ -1028,8 +1033,8 @@ class MachineFileParser(): return os.path.join(l, r) raise EnvironmentException('Unsupported node type') -def parse_machine_files(filenames: T.List[str]): - parser = MachineFileParser(filenames) +def parse_machine_files(filenames: T.List[str], sourcedir: str): + parser = MachineFileParser(filenames, sourcedir) return parser.sections def get_cmd_line_file(build_dir: str) -> str: diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index ab6f56c..36106e4 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -477,7 +477,7 @@ class Environment: log_dir = 'meson-logs' info_dir = 'meson-info' - def __init__(self, source_dir: T.Optional[str], build_dir: T.Optional[str], options: 'argparse.Namespace') -> None: + def __init__(self, source_dir: str, build_dir: str, options: 'argparse.Namespace') -> None: self.source_dir = source_dir self.build_dir = build_dir # Do not try to create build directories when build_dir is none. @@ -550,7 +550,7 @@ class Environment: ## Read in native file(s) to override build machine configuration if self.coredata.config_files is not None: - config = coredata.parse_machine_files(self.coredata.config_files) + config = coredata.parse_machine_files(self.coredata.config_files, self.source_dir) binaries.build = BinaryTable(config.get('binaries', {})) properties.build = Properties(config.get('properties', {})) cmakevars.build = CMakeVariables(config.get('cmake', {})) @@ -561,7 +561,7 @@ class Environment: ## Read in cross file(s) to override host machine configuration if self.coredata.cross_files: - config = coredata.parse_machine_files(self.coredata.cross_files) + config = coredata.parse_machine_files(self.coredata.cross_files, self.source_dir) properties.host = Properties(config.get('properties', {})) binaries.host = BinaryTable(config.get('binaries', {})) cmakevars.host = CMakeVariables(config.get('cmake', {})) diff --git a/run_project_tests.py b/run_project_tests.py index acfa284..f279332 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -793,7 +793,7 @@ def _skip_keys(test_def: T.Dict) -> T.Tuple[bool, bool]: # Test is expected to skip if os matches if 'skip_on_os' in test_def: - mesonenv = environment.Environment(None, None, get_fake_options('/')) + mesonenv = environment.Environment('', '', get_fake_options('/')) for skip_os in test_def['skip_on_os']: if skip_os.startswith('!'): if mesonenv.machines.host.system != skip_os[1:]: @@ -966,7 +966,7 @@ def have_d_compiler() -> bool: def have_objc_compiler(use_tmp: bool) -> bool: with TemporaryDirectoryWinProof(prefix='b ', dir=None if use_tmp else '.') as build_dir: - env = environment.Environment(None, build_dir, get_fake_options('/')) + env = environment.Environment('', build_dir, get_fake_options('/')) try: objc_comp = detect_objc_compiler(env, MachineChoice.HOST) except mesonlib.MesonException: @@ -982,7 +982,7 @@ def have_objc_compiler(use_tmp: bool) -> bool: def have_objcpp_compiler(use_tmp: bool) -> bool: with TemporaryDirectoryWinProof(prefix='b ', dir=None if use_tmp else '.') as build_dir: - env = environment.Environment(None, build_dir, get_fake_options('/')) + env = environment.Environment('', build_dir, get_fake_options('/')) try: objcpp_comp = detect_objcpp_compiler(env, MachineChoice.HOST) except mesonlib.MesonException: @@ -1458,7 +1458,7 @@ def detect_system_compiler(options: 'CompilerArgumentType') -> None: if options.native_file: fake_opts.native_file = [options.native_file] - env = environment.Environment(None, None, fake_opts) + env = environment.Environment('', '', fake_opts) print_compilers(env, MachineChoice.HOST) if options.cross_file: diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 819cc2e..b5252f7 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -3982,17 +3982,23 @@ class AllPlatformTests(BasePlatformTests): [properties] c_args = common_flags + ['-DSOMETHING'] cpp_args = c_args + ['-DSOMETHING_ELSE'] + rel_to_src = '@GLOBAL_SOURCE_ROOT@' / 'tool' + rel_to_file = '@DIRNAME@' / 'tool' + no_escaping = '@@DIRNAME@@' / 'tool' [binaries] c = toolchain / compiler ''')) - values = mesonbuild.coredata.parse_machine_files([crossfile1, crossfile2]) + values = mesonbuild.coredata.parse_machine_files([crossfile1, crossfile2], self.builddir) self.assertEqual(values['binaries']['c'], '/toolchain/gcc') self.assertEqual(values['properties']['c_args'], ['--sysroot=/toolchain/sysroot', '-DSOMETHING']) self.assertEqual(values['properties']['cpp_args'], ['--sysroot=/toolchain/sysroot', '-DSOMETHING', '-DSOMETHING_ELSE']) + self.assertEqual(values['properties']['rel_to_src'], os.path.join(self.builddir, 'tool')) + self.assertEqual(values['properties']['rel_to_file'], os.path.join(os.path.dirname(crossfile2), 'tool')) + self.assertEqual(values['properties']['no_escaping'], os.path.join(f'@{os.path.dirname(crossfile2)}@', 'tool')) @skipIf(is_windows(), 'Directory cleanup fails for some reason') def test_wrap_git(self): |