aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/envconfig.py
diff options
context:
space:
mode:
authorJohn Ericson <git@JohnEricson.me>2019-08-02 14:29:40 -0400
committerJussi Pakkanen <jpakkane@gmail.com>2020-03-23 17:51:36 +0200
commit3a4388e51dee5e7e58f1e5ad4e60fb73b4aacf08 (patch)
tree8f0637e630777cc4a5707c16a30c4d980b888371 /mesonbuild/envconfig.py
parentf6b0425576640e1613f64503951c7c604b868947 (diff)
downloadmeson-3a4388e51dee5e7e58f1e5ad4e60fb73b4aacf08.zip
meson-3a4388e51dee5e7e58f1e5ad4e60fb73b4aacf08.tar.gz
meson-3a4388e51dee5e7e58f1e5ad4e60fb73b4aacf08.tar.bz2
Fix legacy env var support with cross
Fix #3969
Diffstat (limited to 'mesonbuild/envconfig.py')
-rw-r--r--mesonbuild/envconfig.py114
1 files changed, 65 insertions, 49 deletions
diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py
index 0ae1e6d..ac13a71 100644
--- a/mesonbuild/envconfig.py
+++ b/mesonbuild/envconfig.py
@@ -16,7 +16,7 @@ import configparser, os, subprocess
import typing as T
from . import mesonlib
-from .mesonlib import EnvironmentException, split_args
+from .mesonlib import EnvironmentException, MachineChoice, PerMachine, split_args
from . import mlog
_T = T.TypeVar('_T')
@@ -108,27 +108,47 @@ class MesonConfigFile:
out[s] = section
return out
-class HasEnvVarFallback:
+def get_env_var_pair(for_machine: MachineChoice,
+ is_cross: bool,
+ var_name: str) -> T.Tuple[T.Optional[str], T.Optional[str]]:
"""
- A tiny class to indicate that this class contains data that can be
- initialized from either a config file or environment file. The `fallback`
- field says whether env vars should be used. Downstream logic (e.g. subclass
- methods) can check it to decide what to do, since env vars are currently
- lazily decoded.
-
- Frankly, this is a pretty silly class at the moment. The hope is the way
- that we deal with environment variables will become more structured, and
- this can be starting point.
+ Returns the exact env var and the value.
"""
- def __init__(self, fallback: bool = True):
- self.fallback = fallback
-
-class Properties(HasEnvVarFallback):
+ candidates = PerMachine(
+ # The prefixed build version takes priority, but if we are native
+ # compiling we fall back on the unprefixed host version. This
+ # allows native builds to never need to worry about the 'BUILD_*'
+ # ones.
+ ([var_name + '_FOR_BUILD'] if is_cross else [var_name]),
+ # Always just the unprefixed host verions
+ ([] if is_cross else [var_name]),
+ )[for_machine]
+ for var in candidates:
+ value = os.environ.get(var)
+ if value is not None:
+ break
+ else:
+ formatted = ', '.join(['{!r}'.format(var) for var in candidates])
+ mlog.debug('None of {} are defined in the environment, not changing global flags.'.format(formatted))
+ return None
+ mlog.log('Using {!r} from environment with value: {!r}'.format(var, value))
+ return var, value
+
+def get_env_var(for_machine: MachineChoice,
+ is_cross: bool,
+ var_name: str) -> T.Tuple[T.Optional[str], T.Optional[str]]:
+ ret = get_env_var_pair(for_machine, is_cross, var_name)
+ if ret is None:
+ return None
+ else:
+ var, value = ret
+ return value
+
+class Properties:
def __init__(
self,
properties: T.Optional[T.Dict[str, T.Union[str, T.List[str]]]] = None,
- fallback: bool = True):
- super().__init__(fallback)
+ ):
self.properties = properties or {} # type: T.Dict[str, T.Union[str, T.List[str]]]
def has_stdlib(self, language: str) -> bool:
@@ -290,12 +310,11 @@ class MachineInfo:
def libdir_layout_is_win(self) -> bool:
return self.is_windows() or self.is_cygwin()
-class BinaryTable(HasEnvVarFallback):
+class BinaryTable:
def __init__(
self,
binaries: T.Optional[T.Dict[str, T.Union[str, T.List[str]]]] = None,
- fallback: bool = True):
- super().__init__(fallback)
+ ):
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)):
@@ -355,13 +374,6 @@ class BinaryTable(HasEnvVarFallback):
return ['ccache']
@classmethod
- def _warn_about_lang_pointing_to_cross(cls, compiler_exe: str, evar: str) -> None:
- evar_str = os.environ.get(evar, 'WHO_WOULD_CALL_THEIR_COMPILER_WITH_THIS_NAME')
- if evar_str == compiler_exe:
- mlog.warning('''Env var %s seems to point to the cross compiler.
-This is probably wrong, it should always point to the native compiler.''' % evar)
-
- @classmethod
def parse_entry(cls, entry: T.Union[str, T.List[str]]) -> T.Tuple[T.List[str], T.List[str]]:
compiler = mesonlib.stringlistify(entry)
# Ensure ccache exists and remove it if it doesn't
@@ -373,38 +385,42 @@ This is probably wrong, it should always point to the native compiler.''' % evar
# Return value has to be a list of compiler 'choices'
return compiler, ccache
- def lookup_entry(self, name: str) -> T.Optional[T.List[str]]:
+ def lookup_entry(self,
+ for_machine: MachineChoice,
+ is_cross: bool,
+ 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
- command = self.binaries.get(name)
- if command is not None:
- command = mesonlib.stringlistify(command)
- # Relies on there being no "" env var
- evar = self.evarMap.get(name, "")
- self._warn_about_lang_pointing_to_cross(command[0], evar)
- elif self.fallback:
- # Relies on there being no "" env var
- evar = self.evarMap.get(name, "")
- command = os.environ.get(evar)
- if command is None:
- deprecated = self.DEPRECATION_MAP.get(evar)
- if deprecated:
- command = os.environ.get(deprecated)
- if command:
- mlog.deprecation(
- 'The', deprecated, 'environment variable is deprecated in favor of',
- evar, once=True)
- if command is not None:
- command = split_args(command)
+ # 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 = self.evarMap.get(name)
+ if evar is not None:
+ raw_command = get_env_var(for_machine, is_cross, evar)
+ if raw_command is None:
+ deprecated = self.DEPRECATION_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):
- return None
+ command = None
return command
class Directories: