The Meson Build System http://mesonbuild.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1091 lines
39 KiB

# Copyright 2013-2020 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
import re
import dataclasses
import functools
import typing as T
from pathlib import Path
from .. import mlog
from .. import mesonlib
from .base import DependencyException, SystemDependency
from .pkgconfig import PkgConfigDependency
from .misc import threads_factory
if T.TYPE_CHECKING:
from ..environment import Environment, Properties
# On windows 3 directory layouts are supported:
# * The default layout (versioned) installed:
# - $BOOST_ROOT/include/boost-x_x/boost/*.hpp
# - $BOOST_ROOT/lib/*.lib
# * The non-default layout (system) installed:
# - $BOOST_ROOT/include/boost/*.hpp
# - $BOOST_ROOT/lib/*.lib
# * The pre-built binaries from sf.net:
# - $BOOST_ROOT/boost/*.hpp
# - $BOOST_ROOT/lib<arch>-<compiler>/*.lib where arch=32/64 and compiler=msvc-14.1
#
# Note that we should also try to support:
# mingw-w64 / Windows : libboost_<module>-mt.a (location = <prefix>/mingw64/lib/)
# libboost_<module>-mt.dll.a
#
# The `modules` argument accept library names. This is because every module that
# has libraries to link against also has multiple options regarding how to
# link. See for example:
# * http://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/boost_test/usage_variants.html
# * http://www.boost.org/doc/libs/1_65_1/doc/html/stacktrace/configuration_and_build.html
# * http://www.boost.org/doc/libs/1_65_1/libs/math/doc/html/math_toolkit/main_tr1.html
# **On Unix**, official packaged versions of boost libraries follow the following schemes:
#
# Linux / Debian: libboost_<module>.so -> libboost_<module>.so.1.66.0
# Linux / Red Hat: libboost_<module>.so -> libboost_<module>.so.1.66.0
# Linux / OpenSuse: libboost_<module>.so -> libboost_<module>.so.1.66.0
# Win / Cygwin: libboost_<module>.dll.a (location = /usr/lib)
# libboost_<module>.a
# cygboost_<module>_1_64.dll (location = /usr/bin)
# Win / VS: boost_<module>-vc<ver>-mt[-gd]-<arch>-1_67.dll (location = C:/local/boost_1_67_0)
# Mac / homebrew: libboost_<module>.dylib + libboost_<module>-mt.dylib (location = /usr/local/lib)
# Mac / macports: libboost_<module>.dylib + libboost_<module>-mt.dylib (location = /opt/local/lib)
#
# Its not clear that any other abi tags (e.g. -gd) are used in official packages.
#
# On Linux systems, boost libs have multithreading support enabled, but without the -mt tag.
#
# Boost documentation recommends using complex abi tags like "-lboost_regex-gcc34-mt-d-1_36".
# (See http://www.boost.org/doc/libs/1_66_0/more/getting_started/unix-variants.html#library-naming)
# However, its not clear that any Unix distribution follows this scheme.
# Furthermore, the boost documentation for unix above uses examples from windows like
# "libboost_regex-vc71-mt-d-x86-1_34.lib", so apparently the abi tags may be more aimed at windows.
#
# We follow the following strategy for finding modules:
# A) Detect potential boost root directories (uses also BOOST_ROOT env var)
# B) Foreach candidate
# 1. Look for the boost headers (boost/version.pp)
# 2. Find all boost libraries
# 2.1 Add all libraries in lib*
# 2.2 Filter out non boost libraries
# 2.3 Filter the remaining libraries based on the meson requirements (static/shared, etc.)
# 2.4 Ensure that all libraries have the same boost tag (and are thus compatible)
# 3. Select the libraries matching the requested modules
@dataclasses.dataclass(eq=False, order=False)
class UnknownFileException(Exception):
path: Path
@functools.total_ordering
class BoostIncludeDir():
def __init__(self, path: Path, version_int: int):
self.path = path
self.version_int = version_int
major = int(self.version_int / 100000)
minor = int((self.version_int / 100) % 1000)
patch = int(self.version_int % 100)
self.version = f'{major}.{minor}.{patch}'
self.version_lib = f'{major}_{minor}'
def __repr__(self) -> str:
return f'<BoostIncludeDir: {self.version} -- {self.path}>'
def __lt__(self, other: object) -> bool:
if isinstance(other, BoostIncludeDir):
return (self.version_int, self.path) < (other.version_int, other.path)
return NotImplemented
@functools.total_ordering
class BoostLibraryFile():
# Python libraries are special because of the included
# minor version in the module name.
boost_python_libs = ['boost_python', 'boost_numpy']
reg_python_mod_split = re.compile(r'(boost_[a-zA-Z]+)([0-9]*)')
reg_abi_tag = re.compile(r'^s?g?y?d?p?n?$')
reg_ver_tag = re.compile(r'^[0-9_]+$')
def __init__(self, path: Path):
self.path = path
self.name = self.path.name
# Initialize default properties
self.static = False
self.toolset = ''
self.arch = ''
self.version_lib = ''
self.mt = True
self.runtime_static = False
self.runtime_debug = False
self.python_debug = False
self.debug = False
self.stlport = False
self.deprecated_iostreams = False
# Post process the library name
name_parts = self.name.split('.')
self.basename = name_parts[0]
self.suffixes = name_parts[1:]
self.vers_raw = [x for x in self.suffixes if x.isdigit()]
self.suffixes = [x for x in self.suffixes if not x.isdigit()]
self.nvsuffix = '.'.join(self.suffixes) # Used for detecting the library type
self.nametags = self.basename.split('-')
self.mod_name = self.nametags[0]
if self.mod_name.startswith('lib'):
self.mod_name = self.mod_name[3:]
# Set library version if possible
if len(self.vers_raw) >= 2:
self.version_lib = '{}_{}'.format(self.vers_raw[0], self.vers_raw[1])
# Detecting library type
if self.nvsuffix in {'so', 'dll', 'dll.a', 'dll.lib', 'dylib'}:
self.static = False
elif self.nvsuffix in {'a', 'lib'}:
self.static = True
else:
raise UnknownFileException(self.path)
# boost_.lib is the dll import library
if self.basename.startswith('boost_') and self.nvsuffix == 'lib':
self.static = False
# Process tags
tags = self.nametags[1:]
# Filter out the python version tag and fix modname
if self.is_python_lib():
tags = self.fix_python_name(tags)
if not tags:
return
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
# Without any tags mt is assumed, however, an absence of mt in the name
# with tags present indicates that the lib was built without mt support
self.mt = False
for i in tags:
if i == 'mt':
self.mt = True
elif len(i) == 3 and i[1:] in {'32', '64'}:
self.arch = i
elif BoostLibraryFile.reg_abi_tag.match(i):
self.runtime_static = 's' in i
self.runtime_debug = 'g' in i
self.python_debug = 'y' in i
self.debug = 'd' in i
self.stlport = 'p' in i
self.deprecated_iostreams = 'n' in i
elif BoostLibraryFile.reg_ver_tag.match(i):
self.version_lib = i
else:
self.toolset = i
def __repr__(self) -> str:
return f'<LIB: {self.abitag} {self.mod_name:<32} {self.path}>'
def __lt__(self, other: object) -> bool:
if isinstance(other, BoostLibraryFile):
return (
self.mod_name, self.static, self.version_lib, self.arch,
not self.mt, not self.runtime_static,
not self.debug, self.runtime_debug, self.python_debug,
self.stlport, self.deprecated_iostreams,
self.name,
) < (
other.mod_name, other.static, other.version_lib, other.arch,
not other.mt, not other.runtime_static,
not other.debug, other.runtime_debug, other.python_debug,
other.stlport, other.deprecated_iostreams,
other.name,
)
return NotImplemented
def __eq__(self, other: object) -> bool:
if isinstance(other, BoostLibraryFile):
return self.name == other.name
return NotImplemented
def __hash__(self) -> int:
return hash(self.name)
@property
def abitag(self) -> str:
abitag = ''
abitag += 'S' if self.static else '-'
abitag += 'M' if self.mt else '-'
abitag += ' '
abitag += 's' if self.runtime_static else '-'
abitag += 'g' if self.runtime_debug else '-'
abitag += 'y' if self.python_debug else '-'
abitag += 'd' if self.debug else '-'
abitag += 'p' if self.stlport else '-'
abitag += 'n' if self.deprecated_iostreams else '-'
abitag += ' ' + (self.arch or '???')
abitag += ' ' + (self.toolset or '?')
abitag += ' ' + (self.version_lib or 'x_xx')
return abitag
def is_boost(self) -> bool:
return any(self.name.startswith(x) for x in ['libboost_', 'boost_'])
def is_python_lib(self) -> bool:
return any(self.mod_name.startswith(x) for x in BoostLibraryFile.boost_python_libs)
def fix_python_name(self, tags: T.List[str]) -> T.List[str]:
# Handle the boost_python naming madness.
# See https://github.com/mesonbuild/meson/issues/4788 for some distro
# specific naming variations.
other_tags = [] # type: T.List[str]
# Split the current modname into the base name and the version
m_cur = BoostLibraryFile.reg_python_mod_split.match(self.mod_name)
cur_name = m_cur.group(1)
cur_vers = m_cur.group(2)
# Update the current version string if the new version string is longer
def update_vers(new_vers: str) -> None:
nonlocal cur_vers
new_vers = new_vers.replace('_', '')
new_vers = new_vers.replace('.', '')
if not new_vers.isdigit():
return
if len(new_vers) > len(cur_vers):
cur_vers = new_vers
for i in tags:
if i.startswith('py'):
update_vers(i[2:])
elif i.isdigit():
update_vers(i)
elif len(i) >= 3 and i[0].isdigit and i[2].isdigit() and i[1] == '.':
update_vers(i)
else:
other_tags += [i]
self.mod_name = cur_name + cur_vers
return other_tags
def mod_name_matches(self, mod_name: str) -> bool:
if self.mod_name == mod_name:
return True
if not self.is_python_lib():
return False
m_cur = BoostLibraryFile.reg_python_mod_split.match(self.mod_name)
m_arg = BoostLibraryFile.reg_python_mod_split.match(mod_name)
if not m_cur or not m_arg:
return False
if m_cur.group(1) != m_arg.group(1):
return False
cur_vers = m_cur.group(2)
arg_vers = m_arg.group(2)
# Always assume python 2 if nothing is specified
if not arg_vers:
arg_vers = '2'
return cur_vers.startswith(arg_vers)
def version_matches(self, version_lib: str) -> bool:
# If no version tag is present, assume that it fits
if not self.version_lib or not version_lib:
return True
return self.version_lib == version_lib
def arch_matches(self, arch: str) -> bool:
# If no version tag is present, assume that it fits
if not self.arch or not arch:
return True
return self.arch == arch
def vscrt_matches(self, vscrt: str) -> bool:
# If no vscrt tag present, assume that it fits ['/MD', '/MDd', '/MT', '/MTd']
if not vscrt:
return True
if vscrt in {'/MD', '-MD'}:
return not self.runtime_static and not self.runtime_debug
elif vscrt in {'/MDd', '-MDd'}:
return not self.runtime_static and self.runtime_debug
elif vscrt in {'/MT', '-MT'}:
return (self.runtime_static or not self.static) and not self.runtime_debug
elif vscrt in {'/MTd', '-MTd'}:
return (self.runtime_static or not self.static) and self.runtime_debug
mlog.warning(f'Boost: unknown vscrt tag {vscrt}. This may cause the compilation to fail. Please consider reporting this as a bug.', once=True)
return True
def get_compiler_args(self) -> T.List[str]:
args = [] # type: T.List[str]
if self.mod_name in boost_libraries:
libdef = boost_libraries[self.mod_name] # type: BoostLibrary
if self.static:
args += libdef.static
else:
args += libdef.shared
if self.mt:
args += libdef.multi
else:
args += libdef.single
return args
def get_link_args(self) -> T.List[str]:
return [self.path.as_posix()]
class BoostDependency(SystemDependency):
def __init__(self, environment: Environment, kwargs: T.Dict[str, T.Any]) -> None:
super().__init__('boost', environment, kwargs, language='cpp')
buildtype = environment.coredata.get_option(mesonlib.OptionKey('buildtype'))
assert isinstance(buildtype, str)
self.debug = buildtype.startswith('debug')
self.multithreading = kwargs.get('threading', 'multi') == 'multi'
self.boost_root = None # type: T.Optional[Path]
self.explicit_static = 'static' in kwargs
# Extract and validate modules
self.modules = mesonlib.extract_as_list(kwargs, 'modules') # type: T.List[str]
for i in self.modules:
if not isinstance(i, str):
raise DependencyException('Boost module argument is not a string.')
if i.startswith('boost_'):
raise DependencyException('Boost modules must be passed without the boost_ prefix')
self.modules_found = [] # type: T.List[str]
self.modules_missing = [] # type: T.List[str]
# Do we need threads?
if 'thread' in self.modules:
if not self._add_sub_dependency(threads_factory(environment, self.for_machine, {})):
self.is_found = False
return
# Try figuring out the architecture tag
self.arch = environment.machines[self.for_machine].cpu_family
self.arch = boost_arch_map.get(self.arch, None)
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
# First, look for paths specified in a machine file
props = self.env.properties[self.for_machine]
if any(x in self.env.properties[self.for_machine] for x in
['boost_includedir', 'boost_librarydir', 'boost_root']):
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
self.detect_boost_machine_file(props)
return
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
# Finally, look for paths from .pc files and from searching the filesystem
self.detect_roots()
def check_and_set_roots(self, roots: T.List[Path], use_system: bool) -> None:
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
roots = list(mesonlib.OrderedSet(roots))
for j in roots:
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
# 1. Look for the boost headers (boost/version.hpp)
mlog.debug(f'Checking potential boost root {j.as_posix()}')
inc_dirs = self.detect_inc_dirs(j)
inc_dirs = sorted(inc_dirs, reverse=True) # Prefer the newer versions
# Early abort when boost is not found
if not inc_dirs:
continue
lib_dirs = self.detect_lib_dirs(j, use_system)
self.is_found = self.run_check(inc_dirs, lib_dirs)
if self.is_found:
self.boost_root = j
break
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 wouldn't need this
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
incdir = props.get('boost_includedir')
assert incdir is None or isinstance(incdir, str)
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
libdir = props.get('boost_librarydir')
assert libdir is None or isinstance(libdir, str)
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
if incdir and libdir:
inc_dir = Path(incdir)
lib_dir = Path(libdir)
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
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')
mlog.debug('Trying to find boost with:')
mlog.debug(f' - boost_includedir = {inc_dir}')
mlog.debug(f' - boost_librarydir = {lib_dir}')
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
return self.detect_split_root(inc_dir, lib_dir)
elif incdir or libdir:
raise DependencyException('Both boost_includedir *and* boost_librarydir have to be set in your machine file (one is not enough)')
rootdir = props.get('boost_root')
# It shouldn't be possible to get here without something in boost_root
assert rootdir
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
raw_paths = mesonlib.stringlistify(rootdir)
paths = [Path(x) for x in raw_paths]
if paths and any(not x.is_absolute() for x in paths):
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
raise DependencyException('boost_root path given in machine file must be absolute')
self.check_and_set_roots(paths, use_system=False)
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
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]))
# 2. Find all boost libraries
libs = [] # type: T.List[BoostLibraryFile]
for i in lib_dirs:
libs = self.detect_libraries(i)
if libs:
mlog.debug(f' - found boost library dir: {i}')
# mlog.debug(' - raw library list:')
# for j in libs:
# mlog.debug(' - {}'.format(j))
break
libs = sorted(set(libs))
modules = ['boost_' + x for x in self.modules]
for inc in inc_dirs:
mlog.debug(f' - found boost {inc.version} include dir: {inc.path}')
f_libs = self.filter_libraries(libs, inc.version_lib)
mlog.debug(' - filtered library list:')
for j in f_libs:
mlog.debug(f' - {j}')
# 3. Select the libraries matching the requested modules
not_found = [] # type: T.List[str]
selected_modules = [] # type: T.List[BoostLibraryFile]
for mod in modules:
found = False
for l in f_libs:
if l.mod_name_matches(mod):
selected_modules += [l]
found = True
break
if not found:
not_found += [mod]
# log the result
mlog.debug(' - found:')
comp_args = [] # type: T.List[str]
link_args = [] # type: T.List[str]
for j in selected_modules:
c_args = j.get_compiler_args()
l_args = j.get_link_args()
mlog.debug(' - {:<24} link={} comp={}'.format(j.mod_name, str(l_args), str(c_args)))
comp_args += c_args
link_args += l_args
comp_args = list(mesonlib.OrderedSet(comp_args))
link_args = list(mesonlib.OrderedSet(link_args))
self.modules_found = [x.mod_name for x in selected_modules]
self.modules_found = [x[6:] for x in self.modules_found]
self.modules_found = sorted(set(self.modules_found))
self.modules_missing = not_found
self.modules_missing = [x[6:] for x in self.modules_missing]
self.modules_missing = sorted(set(self.modules_missing))
# if we found all modules we are done
if not not_found:
self.version = inc.version
self.compile_args = ['-I' + inc.path.as_posix()]
self.compile_args += comp_args
self.compile_args += self._extra_compile_args()
self.compile_args = list(mesonlib.OrderedSet(self.compile_args))
self.link_args = link_args
mlog.debug(f' - final compile args: {self.compile_args}')
mlog.debug(f' - final link args: {self.link_args}')
return True
# in case we missed something log it and try again
mlog.debug(' - NOT found:')
for mod in not_found:
mlog.debug(f' - {mod}')
return False
def detect_inc_dirs(self, root: Path) -> T.List[BoostIncludeDir]:
candidates = [] # type: T.List[Path]
inc_root = root / 'include'
candidates += [root / 'boost']
candidates += [inc_root / 'boost']
if inc_root.is_dir():
for i in inc_root.iterdir():
if not i.is_dir() or not i.name.startswith('boost-'):
continue
candidates += [i / 'boost']
candidates = [x for x in candidates if x.is_dir()]
candidates = [x / 'version.hpp' for x in candidates]
candidates = [x for x in candidates if x.exists()]
return [self._include_dir_from_version_header(x) for x in candidates]
def detect_lib_dirs(self, root: Path, use_system: bool) -> T.List[Path]:
# First check the system include paths. Only consider those within the
# given root path
if use_system:
system_dirs_t = self.clib_compiler.get_library_dirs(self.env)
system_dirs = [Path(x) for x in system_dirs_t]
system_dirs = [x.resolve() for x in system_dirs if x.exists()]
system_dirs = [x for x in system_dirs if mesonlib.path_is_in_root(x, root)]
system_dirs = list(mesonlib.OrderedSet(system_dirs))
if system_dirs:
return system_dirs
# No system include paths were found --> fall back to manually looking
# for library dirs in root
dirs = [] # type: T.List[Path]
subdirs = [] # type: T.List[Path]
for i in root.iterdir():
if i.is_dir() and i.name.startswith('lib'):
dirs += [i]
# Some distros put libraries not directly inside /usr/lib but in /usr/lib/x86_64-linux-gnu
for i in dirs:
for j in i.iterdir():
if j.is_dir() and j.name.endswith('-linux-gnu'):
subdirs += [j]
# Filter out paths that don't match the target arch to avoid finding
# the wrong libraries. See https://github.com/mesonbuild/meson/issues/7110
if not self.arch:
return dirs + subdirs
arch_list_32 = ['32', 'i386']
arch_list_64 = ['64']
raw_list = dirs + subdirs
no_arch = [x for x in raw_list if not any(y in x.name for y in arch_list_32 + arch_list_64)]
matching_arch = [] # type: T.List[Path]
if '32' in self.arch:
matching_arch = [x for x in raw_list if any(y in x.name for y in arch_list_32)]
elif '64' in self.arch:
matching_arch = [x for x in raw_list if any(y in x.name for y in arch_list_64)]
return sorted(matching_arch) + sorted(no_arch)
def filter_libraries(self, libs: T.List[BoostLibraryFile], lib_vers: str) -> T.List[BoostLibraryFile]:
# MSVC is very picky with the library tags
vscrt = ''
try:
crt_val = self.env.coredata.options[mesonlib.OptionKey('b_vscrt')].value
buildtype = self.env.coredata.options[mesonlib.OptionKey('buildtype')].value
vscrt = self.clib_compiler.get_crt_compile_args(crt_val, buildtype)[0]
except (KeyError, IndexError, AttributeError):
pass
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
# mlog.debug(' - static: {}'.format(self.static))
# mlog.debug(' - not explicit static: {}'.format(not self.explicit_static))
# mlog.debug(' - mt: {}'.format(self.multithreading))
# mlog.debug(' - version: {}'.format(lib_vers))
# mlog.debug(' - arch: {}'.format(self.arch))
# mlog.debug(' - vscrt: {}'.format(vscrt))
libs = [x for x in libs if x.static == self.static or not self.explicit_static]
libs = [x for x in libs if x.mt == self.multithreading]
libs = [x for x in libs if x.version_matches(lib_vers)]
libs = [x for x in libs if x.arch_matches(self.arch)]
libs = [x for x in libs if x.vscrt_matches(vscrt)]
libs = [x for x in libs if x.nvsuffix != 'dll'] # Only link to import libraries
# Only filter by debug when we are building in release mode. Debug
# libraries are automatically preferred through sorting otherwise.
if not self.debug:
libs = [x for x in libs if not x.debug]
# Take the abitag from the first library and filter by it. This
# ensures that we have a set of libraries that are always compatible.
if not libs:
return []
abitag = libs[0].abitag
libs = [x for x in libs if x.abitag == abitag]
return libs
def detect_libraries(self, libdir: Path) -> T.List[BoostLibraryFile]:
libs = set() # type: T.Set[BoostLibraryFile]
for i in libdir.iterdir():
if not i.is_file():
continue
if not any(i.name.startswith(x) for x in ['libboost_', 'boost_']):
continue
# Windows binaries from SourceForge ship with PDB files alongside
# DLLs (#8325). Ignore them.
if i.name.endswith('.pdb'):
continue
try:
libs.add(BoostLibraryFile(i.resolve()))
except UnknownFileException as e:
mlog.warning('Boost: ignoring unknown file {} under lib directory'.format(e.path.name))
return [x for x in libs if x.is_boost()] # Filter out no boost libraries
def detect_split_root(self, inc_dir: Path, lib_dir: Path) -> None:
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
boost_inc_dir = None
for j in [inc_dir / 'version.hpp', inc_dir / 'boost' / 'version.hpp']:
if j.is_file():
boost_inc_dir = self._include_dir_from_version_header(j)
break
if not boost_inc_dir:
self.is_found = False
return
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
self.is_found = self.run_check([boost_inc_dir], [lib_dir])
def detect_roots(self) -> None:
roots = [] # type: T.List[Path]
Add boost_root support to properties files (#7210) * Add boost_root support to properties files This commit implements `boost_root`, `boost_includedir`, and `boost_librarydir` variable support to native and cross properties files. The search order is currently environment variables, then these variables, and finally a platform-dependent search. * Add preliminary boost_root / boost_includedir tests Each test contains a fake "version.hpp", as that's how boost detection is currently being done. We look for this file relative to the root directory, which probably shouldn't be allowed (it previously was for BOOST_LIBRARYDIR but not for BOOST_ROOT). It also cannot help with breakage detection in libraries, however it looks like this wasn't getting tested beforehand. I've given the two unique version numbers that shouldn't be present in any stock version of boost (001 and 002). * Add return type to detect_split_root * Return empty list when nothing found in BOOST_ROOT, rather than None * Update boost_root tests * Create nativefile.ini based on location of run_project_tests.py * Add fake libraries to ensure boost_librarydir is being used * Require all search paths for boost to be absolute * Redo boost search ordering To better match things like pkg-config, we now look through native/cross files, then environment variables, then system locations for boost installations. Path detection does not fall back from one method to the next for properties or environment variables--if boost_root, boost_librarydir, or boost_includedir is specified, they must be sufficient to find boost. Likewise for BOOST_ROOT and friends. pkg-config detection is still optional falling back to system-wide detection, for Conan. (Also, fix a typo in test 33's nativefile) * Correct return type for detect_roots * Correct boost dependency search order in documentation * Print debug information for boost library finding, to resolve CI issues * Handle native/cross file templates in a more consistent way All tests can now create a `nativefile.ini.in` if they need to use some parameter that the testing framework knows about but they can't. * Pass str--rather than PosixPath--to os.path.exists, for Python35 * Look for boost minor versions, rather than boost patch versions in test cases * Drop fake dylib versions of boost_regex * Prefer get_env_var to use of os.environ * Correct error reporting for relative BOOST_ROOT paths * Bump version this appears in. Also, change "properties file" to "machine file" as that appears to be the more common language.
4 years ago
# Try getting the BOOST_ROOT from a boost.pc if it exists. This primarily
# allows BoostDependency to find boost from Conan. See #5438
try:
boost_pc = PkgConfigDependency('boost', self.env, {'required': False})
if boost_pc.found():
boost_root = boost_pc.get_pkgconfig_variable('prefix', [], None)
if boost_root:
roots += [Path(boost_root)]
except DependencyException:
pass
# Add roots from system paths
inc_paths = [Path(x) for x in self.clib_compiler.get_default_include_dirs()]
inc_paths = [x.parent for x in inc_paths if x.exists()]
inc_paths = [x.resolve() for x in inc_paths]
roots += inc_paths
# Add system paths
if self.env.machines[self.for_machine].is_windows():
# Where boost built from source actually installs it
c_root = Path('C:/Boost')
if c_root.is_dir():
roots += [c_root]
# Where boost documentation says it should be
prog_files = Path('C:/Program Files/boost')
# Where boost prebuilt binaries are
local_boost = Path('C:/local')
candidates = [] # type: T.List[Path]
if prog_files.is_dir():
candidates += [*prog_files.iterdir()]
if local_boost.is_dir():
candidates += [*local_boost.iterdir()]
roots += [x for x in candidates if x.name.lower().startswith('boost') and x.is_dir()]
else:
tmp = [] # type: T.List[Path]
# Add some default system paths
tmp += [Path('/opt/local')]
tmp += [Path('/usr/local/opt/boost')]
tmp += [Path('/usr/local')]
tmp += [Path('/usr')]
# Cleanup paths
tmp = [x for x in tmp if x.is_dir()]
tmp = [x.resolve() for x in tmp]
roots += tmp
self.check_and_set_roots(roots, use_system=True)
def log_details(self) -> str:
res = ''
if self.modules_found:
res += 'found: ' + ', '.join(self.modules_found)
if self.modules_missing:
if res:
res += ' | '
res += 'missing: ' + ', '.join(self.modules_missing)
return res
def log_info(self) -> str:
if self.boost_root:
return self.boost_root.as_posix()
return ''
def _include_dir_from_version_header(self, hfile: Path) -> BoostIncludeDir:
# Extract the version with a regex. Using clib_compiler.get_define would
# also work, however, this is slower (since it the compiler has to be
# invoked) and overkill since the layout of the header is always the same.
assert hfile.exists()
raw = hfile.read_text(encoding='utf-8')
m = re.search(r'#define\s+BOOST_VERSION\s+([0-9]+)', raw)
if not m:
mlog.debug(f'Failed to extract version information from {hfile}')
return BoostIncludeDir(hfile.parents[1], 0)
return BoostIncludeDir(hfile.parents[1], int(m.group(1)))
def _extra_compile_args(self) -> T.List[str]:
# BOOST_ALL_DYN_LINK should not be required with the known defines below
return ['-DBOOST_ALL_NO_LIB'] # Disable automatic linking
# See https://www.boost.org/doc/libs/1_72_0/more/getting_started/unix-variants.html#library-naming
# See https://mesonbuild.com/Reference-tables.html#cpu-families
boost_arch_map = {
'aarch64': 'a64',
'arc': 'a32',
'arm': 'a32',
'ia64': 'i64',
'mips': 'm32',
'mips64': 'm64',
'ppc': 'p32',
'ppc64': 'p64',
'sparc': 's32',
'sparc64': 's64',
'x86': 'x32',
'x86_64': 'x64',
}
#### ---- BEGIN GENERATED ---- ####
# #
# Generated with tools/boost_names.py:
# - boost version: 1.73.0
# - modules found: 159
# - libraries found: 43
#
class BoostLibrary():
def __init__(self, name: str, shared: T.List[str], static: T.List[str], single: T.List[str], multi: T.List[str]):
self.name = name
self.shared = shared
self.static = static
self.single = single
self.multi = multi
class BoostModule():
def __init__(self, name: str, key: str, desc: str, libs: T.List[str]):
self.name = name
self.key = key
self.desc = desc
self.libs = libs
# dict of all know libraries with additional compile options
boost_libraries = {
'boost_atomic': BoostLibrary(
name='boost_atomic',
shared=['-DBOOST_ATOMIC_DYN_LINK=1'],
static=['-DBOOST_ATOMIC_STATIC_LINK=1'],
single=[],
multi=[],
),
'boost_chrono': BoostLibrary(
name='boost_chrono',
shared=['-DBOOST_CHRONO_DYN_LINK=1'],
static=['-DBOOST_CHRONO_STATIC_LINK=1'],
single=['-DBOOST_CHRONO_THREAD_DISABLED'],
multi=[],
),
'boost_container': BoostLibrary(
name='boost_container',
shared=['-DBOOST_CONTAINER_DYN_LINK=1'],
static=['-DBOOST_CONTAINER_STATIC_LINK=1'],
single=[],
multi=[],
),
'boost_context': BoostLibrary(
name='boost_context',
shared=['-DBOOST_CONTEXT_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_contract': BoostLibrary(
name='boost_contract',
shared=['-DBOOST_CONTRACT_DYN_LINK'],
static=['-DBOOST_CONTRACT_STATIC_LINK'],
single=['-DBOOST_CONTRACT_DISABLE_THREADS'],
multi=[],
),
'boost_coroutine': BoostLibrary(
name='boost_coroutine',
shared=['-DBOOST_COROUTINES_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_date_time': BoostLibrary(
name='boost_date_time',
shared=['-DBOOST_DATE_TIME_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_exception': BoostLibrary(
name='boost_exception',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_fiber': BoostLibrary(
name='boost_fiber',
shared=['-DBOOST_FIBERS_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_fiber_numa': BoostLibrary(
name='boost_fiber_numa',
shared=['-DBOOST_FIBERS_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_filesystem': BoostLibrary(
name='boost_filesystem',
shared=['-DBOOST_FILESYSTEM_DYN_LINK=1'],
static=['-DBOOST_FILESYSTEM_STATIC_LINK=1'],
single=[],
multi=[],
),
'boost_graph': BoostLibrary(
name='boost_graph',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_iostreams': BoostLibrary(
name='boost_iostreams',
shared=['-DBOOST_IOSTREAMS_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_locale': BoostLibrary(
name='boost_locale',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_log': BoostLibrary(
name='boost_log',
shared=['-DBOOST_LOG_DYN_LINK=1'],
static=[],
single=['-DBOOST_LOG_NO_THREADS'],
multi=[],
),
'boost_log_setup': BoostLibrary(
name='boost_log_setup',
shared=['-DBOOST_LOG_SETUP_DYN_LINK=1'],
static=[],
single=['-DBOOST_LOG_NO_THREADS'],
multi=[],
),
'boost_math_c99': BoostLibrary(
name='boost_math_c99',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_math_c99f': BoostLibrary(
name='boost_math_c99f',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_math_c99l': BoostLibrary(
name='boost_math_c99l',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_math_tr1': BoostLibrary(
name='boost_math_tr1',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_math_tr1f': BoostLibrary(
name='boost_math_tr1f',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_math_tr1l': BoostLibrary(
name='boost_math_tr1l',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_mpi': BoostLibrary(
name='boost_mpi',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_nowide': BoostLibrary(
name='boost_nowide',
shared=['-DBOOST_NOWIDE_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_prg_exec_monitor': BoostLibrary(
name='boost_prg_exec_monitor',
shared=['-DBOOST_TEST_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_program_options': BoostLibrary(
name='boost_program_options',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_random': BoostLibrary(
name='boost_random',
shared=['-DBOOST_RANDOM_DYN_LINK'],
static=[],
single=[],
multi=[],
),
'boost_regex': BoostLibrary(
name='boost_regex',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_serialization': BoostLibrary(
name='boost_serialization',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_stacktrace_addr2line': BoostLibrary(
name='boost_stacktrace_addr2line',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_stacktrace_backtrace': BoostLibrary(
name='boost_stacktrace_backtrace',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_stacktrace_basic': BoostLibrary(
name='boost_stacktrace_basic',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_stacktrace_noop': BoostLibrary(
name='boost_stacktrace_noop',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_stacktrace_windbg': BoostLibrary(
name='boost_stacktrace_windbg',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_stacktrace_windbg_cached': BoostLibrary(
name='boost_stacktrace_windbg_cached',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_system': BoostLibrary(
name='boost_system',
shared=['-DBOOST_SYSTEM_DYN_LINK=1'],
static=['-DBOOST_SYSTEM_STATIC_LINK=1'],
single=[],
multi=[],
),
'boost_test_exec_monitor': BoostLibrary(
name='boost_test_exec_monitor',
shared=['-DBOOST_TEST_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_thread': BoostLibrary(
name='boost_thread',
shared=['-DBOOST_THREAD_BUILD_DLL=1', '-DBOOST_THREAD_USE_DLL=1'],
static=['-DBOOST_THREAD_BUILD_LIB=1', '-DBOOST_THREAD_USE_LIB=1'],
single=[],
multi=[],
),
'boost_timer': BoostLibrary(
name='boost_timer',
shared=['-DBOOST_TIMER_DYN_LINK=1'],
static=['-DBOOST_TIMER_STATIC_LINK=1'],
single=[],
multi=[],
),
'boost_type_erasure': BoostLibrary(
name='boost_type_erasure',
shared=['-DBOOST_TYPE_ERASURE_DYN_LINK'],
static=[],
single=[],
multi=[],
),
'boost_unit_test_framework': BoostLibrary(
name='boost_unit_test_framework',
shared=['-DBOOST_TEST_DYN_LINK=1'],
static=[],
single=[],
multi=[],
),
'boost_wave': BoostLibrary(
name='boost_wave',
shared=[],
static=[],
single=[],
multi=[],
),
'boost_wserialization': BoostLibrary(
name='boost_wserialization',
shared=[],
static=[],
single=[],
multi=[],
),
}
# #
#### ---- END GENERATED ---- ####