From f3fcbba1f89f0b2a323dd596a3caf4fce5a1611e Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 11 Dec 2020 13:27:26 -0800 Subject: [PATCH] boost: default machine file properties to env var values This both moves the env reading to configuration time, which is useful, and also simplifies the implementation of the boost dependency. The simplification comes from being able to delete basically duplicated code since the values will be in the Properties if they exist at all. --- mesonbuild/dependencies/boost.py | 65 ++++++++------------------------ mesonbuild/envconfig.py | 8 ---- mesonbuild/environment.py | 21 +++++++++++ run_unittests.py | 2 +- 4 files changed, 37 insertions(+), 59 deletions(-) diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py index 622ee3774..d12f37c3a 100644 --- a/mesonbuild/dependencies/boost.py +++ b/mesonbuild/dependencies/boost.py @@ -20,12 +20,14 @@ from pathlib import Path from .. import mlog from .. import mesonlib -from ..envconfig import get_env_var from ..environment import Environment from .base import DependencyException, ExternalDependency, PkgConfigDependency from .misc import threads_factory +if T.TYPE_CHECKING: + from ..environment import Properties + # On windows 3 directory layouts are supported: # * The default layout (versioned) installed: # - $BOOST_ROOT/include/boost-x_x/boost/*.hpp @@ -372,18 +374,11 @@ class BoostDependency(ExternalDependency): # First, look for paths specified in a machine file props = self.env.properties[self.for_machine] - boost_property_env = [props.get('boost_includedir'), props.get('boost_librarydir'), props.get('boost_root')] - if any(boost_property_env): + if any(x in self.env.properties[self.for_machine] for x in + ['boost_includedir', 'boost_librarydir', 'boost_root']): self.detect_boost_machine_file(props) return - # Next, look for paths in the environment - boost_manual_env_list = ['BOOST_INCLUDEDIR', 'BOOST_LIBRARYDIR', 'BOOST_ROOT', 'BOOSTROOT'] - boost_manual_env = [get_env_var(self.for_machine, self.env.is_cross_build, x) for x in boost_manual_env_list] - if any(boost_manual_env): - self.detect_boost_env() - return - # Finally, look for paths from .pc files and from searching the filesystem self.detect_roots() @@ -405,13 +400,20 @@ class BoostDependency(ExternalDependency): self.boost_root = j break - def detect_boost_machine_file(self, props: T.Dict[str, str]) -> None: + def detect_boost_machine_file(self, props: 'Properties') -> None: + """Detect boost with values in the machine file or environment. + + The machine file values are defaulted to the environment values. + """ + # XXX: if we had a TypedDict we woudn't need this incdir = props.get('boost_includedir') + assert incdir is None or isinstance(incdir, str) libdir = props.get('boost_librarydir') + assert libdir is None or isinstance(libdir, str) if incdir and libdir: - inc_dir = Path(props['boost_includedir']) - lib_dir = Path(props['boost_librarydir']) + inc_dir = Path(incdir) + lib_dir = Path(libdir) if not inc_dir.is_absolute() or not lib_dir.is_absolute(): raise DependencyException('Paths given for boost_includedir and boost_librarydir in machine file must be absolute') @@ -436,43 +438,6 @@ class BoostDependency(ExternalDependency): self.check_and_set_roots(paths) - def detect_boost_env(self) -> None: - boost_includedir = get_env_var(self.for_machine, self.env.is_cross_build, 'BOOST_INCLUDEDIR') - boost_librarydir = get_env_var(self.for_machine, self.env.is_cross_build, 'BOOST_LIBRARYDIR') - - boost_manual_env = [boost_includedir, boost_librarydir] - if all(boost_manual_env): - inc_dir = Path(boost_includedir) - lib_dir = Path(boost_librarydir) - - if not inc_dir.is_absolute() or not lib_dir.is_absolute(): - raise DependencyException('Paths given in BOOST_INCLUDEDIR and BOOST_LIBRARYDIR must be absolute') - - mlog.debug('Trying to find boost with:') - mlog.debug(' - BOOST_INCLUDEDIR = {}'.format(inc_dir)) - mlog.debug(' - BOOST_LIBRARYDIR = {}'.format(lib_dir)) - - return self.detect_split_root(inc_dir, lib_dir) - - elif any(boost_manual_env): - raise DependencyException('Both BOOST_INCLUDEDIR *and* BOOST_LIBRARYDIR have to be set (one is not enough). Ignoring.') - - boost_root = get_env_var(self.for_machine, self.env.is_cross_build, 'BOOST_ROOT') - boostroot = get_env_var(self.for_machine, self.env.is_cross_build, 'BOOSTROOT') - - # It shouldn't be possible to get here without something in BOOST_ROOT or BOOSTROOT - assert(boost_root or boostroot) - - for path, name in [(boost_root, 'BOOST_ROOT'), (boostroot, 'BOOSTROOT')]: - if path: - raw_paths = path.split(os.pathsep) - paths = [Path(x) for x in raw_paths] - if paths and any([not x.is_absolute() for x in paths]): - raise DependencyException('Paths in {} must be absolute'.format(name)) - break - - self.check_and_set_roots(paths) - def run_check(self, inc_dirs: T.List[BoostIncludeDir], lib_dirs: T.List[Path]) -> bool: mlog.debug(' - potential library dirs: {}'.format([x.as_posix() for x in lib_dirs])) mlog.debug(' - potential include dirs: {}'.format([x.path.as_posix() for x in inc_dirs])) diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index 69b667869..596defe53 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -163,14 +163,6 @@ def get_env_var_pair(for_machine: MachineChoice, mlog.debug('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.Optional[str]: - ret = get_env_var_pair(for_machine, is_cross, var_name) - if ret is None: - return None - return ret[1] - class Properties: def __init__( self, diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 6275da05a..ba24411eb 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -656,6 +656,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() + self._set_default_properties_from_env() # Warn if the user is using two different ways of setting build-type # options that override each other @@ -821,6 +822,26 @@ class Environment: _, p_env = p_env_pair self.binaries[for_machine].binaries.setdefault(name, mesonlib.split_args(p_env)) + def _set_default_properties_from_env(self) -> None: + """Properties which can alkso be set from the environment.""" + # name, evar, split + opts: T.List[T.Tuple[str, T.List[str], bool]] = [ + ('boost_includedir', ['BOOST_INCLUDEDIR'], False), + ('boost_librarydir', ['BOOST_LIBRARYDIR'], False), + ('boost_root', ['BOOST_ROOT', 'BOOSTROOT'], True), + ] + + for (name, evars, split), for_machine in itertools.product(opts, MachineChoice): + for evar in evars: + 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 + if split: + self.properties[for_machine].properties.setdefault(name, p_env.split(os.pathsep)) + else: + self.properties[for_machine].properties.setdefault(name, p_env) + break + 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 diff --git a/run_unittests.py b/run_unittests.py index bbcdb5fb7..21b6608a6 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -5376,7 +5376,7 @@ class FailureTests(BasePlatformTests): def test_boost_BOOST_ROOT_dependency(self): # Test BOOST_ROOT; can be run even if Boost is found or not self.assertMesonRaises("dependency('boost')", - "(BOOST_ROOT.*absolute|{})".format(self.dnf), + "(boost_root.*absolute|{})".format(self.dnf), override_envvars = {'BOOST_ROOT': 'relative/path'}) def test_dependency_invalid_method(self):