diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2020-12-11 12:30:19 -0800 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2021-01-11 11:15:07 -0800 |
commit | e7a5c75285ce63a7197cd82e893450eb9bb68b6c (patch) | |
tree | 1fc774c47d7d709e91e0de441e889b245bba66c0 /mesonbuild | |
parent | 38c7a7590c25426dfd2d480d805d570d7e645096 (diff) | |
download | meson-e7a5c75285ce63a7197cd82e893450eb9bb68b6c.zip meson-e7a5c75285ce63a7197cd82e893450eb9bb68b6c.tar.gz meson-e7a5c75285ce63a7197cd82e893450eb9bb68b6c.tar.bz2 |
Move BinaryTable environment lookups to Environment
This means that all the env lookups are done once, at initial configure
time. This has all of the expected advantages.
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/envconfig.py | 63 | ||||
-rw-r--r-- | mesonbuild/environment.py | 26 |
2 files changed, 41 insertions, 48 deletions
diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index 642aab3..69b6678 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -23,6 +23,9 @@ from pathlib import Path _T = T.TypeVar('_T') +if T.TYPE_CHECKING: + from .environment import Environment + # These classes contains all the data pulled from configuration files (native # and cross file currently), and also assists with the reading environment @@ -122,10 +125,10 @@ ENV_VAR_PROG_MAP: T.Mapping[str, str] = { # Deprecated environment variables mapped from the new variable to the old one # Deprecated in 0.54.0 DEPRECATED_ENV_PROG_MAP: T.Mapping[str, str] = { - 'DC_LD': 'D_LD', - 'FC_LD': 'F_LD', - 'RUSTC_LD': 'RUST_LD', - 'OBJCXX_LD': 'OBJCPP_LD', + 'd_ld': 'D_LD', + 'fortran_ld': 'F_LD', + 'rust_ld': 'RUST_LD', + 'objcpp_ld': 'OBJCPP_LD', } class CMakeSkipCompilerTest(Enum): @@ -394,17 +397,18 @@ class MachineInfo: return self.is_windows() or self.is_cygwin() class BinaryTable: + def __init__( self, binaries: T.Optional[T.Dict[str, T.Union[str, T.List[str]]]] = None, ): - self.binaries = binaries or {} # type: T.Dict[str, T.Union[str, T.List[str]]] - for name, command in self.binaries.items(): - if not isinstance(command, (list, str)): - # TODO generalize message - raise mesonlib.MesonException( - 'Invalid type {!r} for binary {!r} in cross file' - ''.format(command, name)) + self.binaries: T.Dict[str, T.List[str]] = {} + if binaries: + for name, command in binaries.items(): + if not isinstance(command, (list, str)): + raise mesonlib.MesonException( + f'Invalid type {command!r} for entry {name!r} in cross file') + self.binaries[name] = mesonlib.listify(command) @staticmethod def detect_ccache() -> T.List[str]: @@ -426,42 +430,17 @@ class BinaryTable: # Return value has to be a list of compiler 'choices' return compiler, ccache - def lookup_entry(self, - for_machine: MachineChoice, - is_cross: bool, - name: str) -> T.Optional[T.List[str]]: + def lookup_entry(self, name: str) -> T.Optional[T.List[str]]: """Lookup binary in cross/native file and fallback to environment. Returns command with args as list if found, Returns `None` if nothing is found. """ - # Try explicit map, don't fall back on env var - # Try explict map, then env vars - for _ in [()]: # a trick to get `break` - raw_command = self.binaries.get(name) - if raw_command is not None: - command = mesonlib.stringlistify(raw_command) - break # found - evar = ENV_VAR_PROG_MAP.get(name) - if evar is not None: - raw_command = get_env_var(for_machine, is_cross, evar) - if raw_command is None: - deprecated = DEPRECATED_ENV_PROG_MAP.get(evar) - if deprecated is not None: - raw_command = get_env_var(for_machine, is_cross, deprecated) - if raw_command is not None: - mlog.deprecation( - 'The', deprecated, 'environment variable is deprecated in favor of', - evar, once=True) - if raw_command is not None: - command = split_args(raw_command) - break # found - command = None - - - # Do not return empty or blank string entries - if command is not None and (len(command) == 0 or len(command[0].strip()) == 0): - command = None + command = self.binaries.get(name) + if not command: + return None + elif not command[0].strip(): + return None return command class CMakeVariables: diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 12b9dbb..6275da0 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -29,7 +29,7 @@ from .mesonlib import ( from . import mlog from .envconfig import ( - BinaryTable, MachineInfo, + BinaryTable, ENV_VAR_PROG_MAP, MachineInfo, Properties, known_cpu_families, get_env_var_pair, CMakeVariables, ) @@ -129,6 +129,7 @@ from .compilers import ( VisualStudioCCompiler, VisualStudioCPPCompiler, ) +from mesonbuild import envconfig if T.TYPE_CHECKING: from configparser import ConfigParser @@ -654,6 +655,7 @@ class Environment: # Take default value from env if not set in cross/native files or command line. self.set_default_options_from_env() + self._set_default_binaries_from_env() # Warn if the user is using two different ways of setting build-type # options that override each other @@ -804,6 +806,21 @@ class Environment: v = mesonlib.listify(self.options.get(key, [])) self.options.setdefault(key, v + p_list) + def _set_default_binaries_from_env(self) -> None: + """Set default binaries from the environment. + + For example, pkg-config can be set via PKG_CONFIG, or in the machine + file. We want to set the default to the env variable. + """ + opts = itertools.chain(envconfig.DEPRECATED_ENV_PROG_MAP.items(), + envconfig.ENV_VAR_PROG_MAP.items()) + + for (name, evar), for_machine in itertools.product(opts, MachineChoice): + p_env_pair = get_env_var_pair(for_machine, self.is_cross_build(), evar) + if p_env_pair is not None: + _, p_env = p_env_pair + self.binaries[for_machine].binaries.setdefault(name, mesonlib.split_args(p_env)) + def create_new_coredata(self, options: 'argparse.Namespace') -> None: # WARNING: Don't use any values from coredata in __init__. It gets # re-initialized with project options by the interpreter during @@ -853,11 +870,8 @@ class Environment: def is_library(self, fname): return is_library(fname) - def lookup_binary_entry(self, for_machine: MachineChoice, name: str): - return self.binaries[for_machine].lookup_entry( - for_machine, - self.is_cross_build(), - name) + def lookup_binary_entry(self, for_machine: MachineChoice, name: str) -> T.List[str]: + return self.binaries[for_machine].lookup_entry(name) @staticmethod def get_gnu_compiler_defines(compiler): |