machine file: Add @GLOBAL_SOURCE_ROOT@ and @DIRNAME@

pull/12151/head
Xavier Claessens 1 year ago committed by Xavier Claessens
parent bde690b06e
commit 18b96cd069
  1. 12
      docs/markdown/Machine-files.md
  2. 13
      docs/markdown/snippets/machine_file_source_dir.md
  3. 19
      mesonbuild/coredata.py
  4. 6
      mesonbuild/environment.py
  5. 8
      run_project_tests.py
  6. 8
      unittests/allplatformstests.py

@ -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

@ -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'
```

@ -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:

@ -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', {}))

@ -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:

@ -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):

Loading…
Cancel
Save