aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/project
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2021-03-23 20:39:06 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2021-03-23 20:49:39 +0300
commitf2806f803c62f25b2435e03aaaf6652c4650633e (patch)
treefdd55107590f960345fbb241e2e10cc0b7ec5608 /project
parentproject: minor refactoring (diff)
downloadcmake-common-f2806f803c62f25b2435e03aaaf6652c4650633e.tar.gz
cmake-common-f2806f803c62f25b2435e03aaaf6652c4650633e.zip
project.boost: refactoring
The extremely convoluted BoostBuildToolset situation is no more.
Diffstat (limited to 'project')
-rw-r--r--project/boost/archive.py8
-rw-r--r--project/boost/toolchain.py127
-rw-r--r--project/utils.py5
3 files changed, 70 insertions, 70 deletions
diff --git a/project/boost/archive.py b/project/boost/archive.py
index 5316005..e15e457 100644
--- a/project/boost/archive.py
+++ b/project/boost/archive.py
@@ -75,7 +75,9 @@ class TemporaryStorage(ArchiveStorage):
@contextmanager
def write_archive(self, version, contents):
- tmp = temp_file(contents, prefix=f'boost_{version}_',
+ tmp = temp_file(prefix=f'boost_{version}_',
suffix=version.archive_ext, dir=self._dir)
- with tmp as path:
- yield path
+ with tmp as archive_path:
+ with open(archive_path, mode='wb') as fd:
+ fd.write(contents)
+ yield archive_path
diff --git a/project/boost/toolchain.py b/project/boost/toolchain.py
index cd1a422..1f6ae5e 100644
--- a/project/boost/toolchain.py
+++ b/project/boost/toolchain.py
@@ -169,74 +169,72 @@ def _full_exe_name(exe):
return os.path.basename(path)
-class BoostBuildToolset:
- CUSTOM = 'custom'
+class CustomToolchain(Toolchain):
+ COMPILER_VERSION = 'custom'
- def __init__(self, compiler, path, options):
+ def __init__(self, platform, config_path):
+ super().__init__(platform)
+ self.config_path = config_path
+ compiler = self.get_compiler()
if not compiler:
raise RuntimeError('compiler type is required (like gcc, clang, etc.)')
self.compiler = compiler
- self.version = BoostBuildToolset.CUSTOM
- path = path or ''
+ version = CustomToolchain.COMPILER_VERSION
+ self.version = version
+ path = self.get_compiler_path() or ''
path = path and _full_exe_name(path)
self.path = path
- options = options or []
- self.options = options
- @property
+ @abc.abstractmethod
+ def get_compiler(self):
+ pass
+
+ def get_compiler_version(self):
+ return CustomToolchain.COMPILER_VERSION
+
+ @abc.abstractmethod
+ def get_compiler_path(self):
+ pass
+
+ @abc.abstractmethod
+ def get_build_options(self):
+ pass
+
+ def format_build_options(self):
+ return ''.join(f'\n <{name}>{val}' for name, val in self.get_build_options())
+
def toolset(self):
if self.version:
return f'{self.compiler}-{self.version}'
return self.compiler
def b2_toolset(self):
- return f'toolset={self.toolset}'
-
- def b2_args(self):
- return [self.b2_toolset()]
-
- def _format_using_options(self):
- return ''.join(f'\n <{name}>{val}' for name, val in self.options)
+ return f'toolset={self.toolset()}'
- def format_using(self):
+ def format_config(self):
version = self.version and f'{self.version} '
path = self.path and f'{self.path} '
- return f'''using {self.compiler} : {version}: {path}:{self._format_using_options()}
+ return f'''using {self.compiler} : {version}: {path}:{self.format_build_options()}
;'''
-
-class CustomToolchain(Toolchain):
- def __init__(self, platform, config_path, toolset):
- super().__init__(platform)
- self.config_path = config_path
- self.toolset = toolset
-
- @staticmethod
- @abc.abstractmethod
- def get_toolset(platform):
- pass
-
- @staticmethod
- @abc.abstractmethod
- def format_config(toolset):
- pass
-
@classmethod
@contextmanager
def setup(cls, platform):
- toolset = cls.get_toolset(platform)
- config = cls.format_config(toolset)
- logging.info('Using user config:\n%s', config)
- tmp = temp_file(config, mode='w', prefix='user_config_', suffix='.jam')
- with tmp as path:
- yield cls(platform, path, toolset)
+ config_file = temp_file(prefix='user_config_', suffix='.jam')
+ with config_file as config_path:
+ toolset = cls(platform, config_path)
+ config = toolset.format_config()
+ logging.info('Using user config:\n%s', config)
+ with open(config_path, mode='w') as fd:
+ fd.write(config)
+ yield toolset
def b2_args(self, configuration):
# All the required options and the toolset definition should be in the
# user configuration file.
args = super().b2_args(configuration)
+ args.append(self.b2_toolset())
args.append(f'--user-config={self.config_path}')
- args += self.toolset.b2_args()
return args
@@ -245,8 +243,13 @@ class GCC(CustomToolchain):
# MinGW-flavoured GCC on Windows.
COMPILER = 'gcc'
- @staticmethod
- def get_options():
+ def get_compiler(self):
+ return GCC.COMPILER
+
+ def get_compiler_path(self):
+ return 'g++'
+
+ def get_build_options(self):
return [
# TODO: this is a petty attempt to get rid of build warnings in
# older Boost versions. Revise and expand this list or remove it?
@@ -256,33 +259,30 @@ class GCC(CustomToolchain):
('cxxflags', '-Wno-parentheses'),
]
- @staticmethod
- def get_toolset(platform):
- return BoostBuildToolset(GCC.COMPILER, 'g++', GCC.get_options())
-
- @staticmethod
- def format_config(toolset):
- return toolset.format_using()
-
class MinGW(GCC):
# It's important that Boost.Build is actually smart enough to detect the
# GCC prefix (like "x86_64-w64-mingw32" and prepend it to other tools like
# "ar").
- @staticmethod
- def get_toolset(platform):
- paths = project.mingw.MinGW(platform)
+ def get_compiler_path(self):
+ paths = project.mingw.MinGW(self.platform)
compiler = paths.gxx()
- return BoostBuildToolset(MinGW.COMPILER, compiler, MinGW.get_options())
+ return compiler
-class Clang(CustomToolchain):
+class Clang(GCC):
COMPILER = 'clang'
- @staticmethod
- def get_toolset(platform):
- options = [
+ def get_compiler(self):
+ return Clang.COMPILER
+
+ def get_compiler_path(self):
+ return 'clang++'
+
+ def get_build_options(self):
+ options = super().get_build_options()
+ options += [
('cxxflags', '-DBOOST_USE_WINDOWS_H'),
# TODO: this is a petty attempt to get rid of build warnings in
# older Boost versions. Revise and expand this list or remove it?
@@ -290,17 +290,16 @@ class Clang(CustomToolchain):
('cxxflags', '-Wno-unused-local-typedef'),
# error: constant expression evaluates to -105 which cannot be narrowed to type 'boost::re_detail::cpp_regex_traits_implementation<char>::char_class_type' (aka 'unsigned int')
('cxxflags', '-Wno-c++11-narrowing'),
- ] + GCC.get_options()
+ ]
if project.os.on_windows():
# Prefer LLVM binutils:
if shutil.which('llvm-ar') is not None:
options.append(('archiver', 'llvm-ar'))
if shutil.which('llvm-ranlib') is not None:
options.append(('ranlib', 'llvm-ranlib'))
- return BoostBuildToolset(Clang.COMPILER, 'clang++', options)
+ return options
- @staticmethod
- def format_config(toolset):
+ def format_config(self):
# To make clang.exe/clang++.exe work on Windows, some tweaks are
# required. I borrowed them from CMake's Windows-Clang.cmake [1].
# Adding them globally to Boost.Build options is described in [2].
@@ -315,7 +314,7 @@ class Clang(CustomToolchain):
<target-os>windows,<runtime-link>shared,<variant>debug:<cxxflags>"-D_DLL -Xclang --dependent-lib=msvcrtd"
<target-os>windows,<runtime-link>shared,<variant>release:<cxxflags>"-D_DLL -Xclang --dependent-lib=msvcrt"
;
-{toolset.format_using()}
+{super().format_config()}
'''
diff --git a/project/utils.py b/project/utils.py
index c63b8a4..8485dfa 100644
--- a/project/utils.py
+++ b/project/utils.py
@@ -68,7 +68,7 @@ def delete(path):
@contextmanager
-def temp_file(contents, **kwargs):
+def temp_file(**kwargs):
'''Make NamedTemporaryFile usable on Windows.
It can't be opened a second time on Windows, hence this silliness.
@@ -76,8 +76,7 @@ def temp_file(contents, **kwargs):
tmp = tempfile.NamedTemporaryFile(delete=False, **kwargs)
with tmp as file, delete_on_error(file.name):
path = file.name
- logging.info('Writing temporary file: %s', path)
- file.write(contents)
+ logging.info('Created temporary file: %s', path)
with delete(path):
yield path