From 8a408b4c95a5e6be2808ef9516bcbebddf8b09a6 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Sat, 28 Mar 2020 19:19:22 +0000 Subject: project.boost: factor out Configuration/Platform/Linkage --- project/boost/build.py | 95 +++++------------------------------------------- project/cmake/build.py | 21 ++--------- project/configuration.py | 42 +++++++++++++++++++++ project/linkage.py | 26 +++++++++++++ project/platform.py | 41 +++++++++++++++++++++ 5 files changed, 121 insertions(+), 104 deletions(-) create mode 100644 project/configuration.py create mode 100644 project/linkage.py create mode 100644 project/platform.py (limited to 'project') diff --git a/project/boost/build.py b/project/boost/build.py index 8da8c9e..14c4b80 100644 --- a/project/boost/build.py +++ b/project/boost/build.py @@ -40,6 +40,10 @@ import sys import tempfile import urllib.request +from project.configuration import Configuration +from project.linkage import Linkage +from project.platform import Platform + @contextmanager def _chdir(path): @@ -70,87 +74,6 @@ def _run_executable(cmd_line): return subprocess.run(cmd_line, check=True) -class Platform(Enum): - X86 = 'x86' - X64 = 'x64' - WIN32 = 'Win32' - - def __str__(self): - return self.value - - @staticmethod - def all(): - return (Platform.X86, Platform.X64) - - def get_address_model(self): - if self is Platform.X86: - return 32 - if self is Platform.X64: - return 64 - if self is Platform.WIN32: - return 32 - raise NotImplementedError(f'unsupported platform: {self}') - - -def _parse_platform(s): - try: - return Platform(s) - except ValueError: - raise argparse.ArgumentTypeError(f'invalid platform: {s}') - - -class Configuration(Enum): - # AFAIK, Boost only supports debug/release, MinSizeRel and RelWithDebInfo - # are for compatibility with CMake, they map to "release". - # The libraries will still reside in stage/PLATFORM/CONFIGURATION/lib, even - # if CONFIGURATION is MinSizeRel/RelWithDebInfo. - DEBUG = 'Debug' - MINSIZEREL = 'MinSizeRel' - RELWITHDEBINFO = 'RelWithDebInfo' - RELEASE = 'Release' - - def normalize(self): - '''Roughly maps CMake's CMAKE_BUILD_TYPE to Boost's variant.''' - if self is Configuration.MINSIZEREL: - return Configuration.RELEASE - if self is Configuration.RELWITHDEBINFO: - return Configuration.RELEASE - return self - - @staticmethod - def all(): - return (Configuration.DEBUG, Configuration.RELEASE) - - def __str__(self): - return self.value - - -def _parse_configuration(s): - try: - return Configuration(s) - except ValueError: - raise argparse.ArgumentTypeError(f'invalid configuration: {s}') - - -class Linkage(Enum): - STATIC = 'static' - SHARED = 'shared' - - @staticmethod - def all(): - return tuple(Linkage) - - def __str__(self): - return self.value - - -def _parse_linkage(s): - try: - return Linkage(s) - except ValueError: - raise argparse.ArgumentTypeError(f'invalid linkage: {s}') - - _Version = namedtuple('_Version', ['major', 'minor', 'patch']) @@ -457,7 +380,7 @@ class BuildParameters: @staticmethod def _variant(configuration): - return f'variant={str(configuration.normalize()).lower()}' + return f'variant={configuration.to_boost_variant()}' def _parse_dir(s): @@ -493,23 +416,23 @@ def _parse_args(argv=None): # subdirectories (to avoid name clashes). build.add_argument('--platform', metavar='PLATFORM', nargs='*', dest='platforms', default=[], - type=_parse_platform, + type=Platform.parse, help=f'target platform ({"/".join(map(str, Platform))})') build.add_argument('--configuration', metavar='CONFIGURATION', nargs='*', dest='configurations', default=[], - type=_parse_configuration, + type=Configuration.parse, help=f'target configuration ({"/".join(map(str, Configuration))})') # This is needed because the default behaviour on Linux and Windows is # different: static & dynamic libs are built on Linux, but only static libs # are built on Windows by default. build.add_argument('--link', metavar='LINKAGE', nargs='*', default=[], - type=_parse_linkage, + type=Linkage.parse, help=f'how the libraries are linked ({"/".join(map(str, Linkage))})') # This is used to omit runtime-link=static I'd have to otherwise use a lot, # plus the script validates the link= and runtime-link= combinations. build.add_argument('--runtime-link', metavar='LINKAGE', - type=_parse_linkage, default=Linkage.STATIC, + type=Linkage.parse, default=Linkage.STATIC, help=f'how the libraries link to the runtime ({"/".join(map(str, Linkage))})') build.add_argument('--build', metavar='DIR', dest='build_dir', diff --git a/project/cmake/build.py b/project/cmake/build.py index 695489b..89ac6da 100644 --- a/project/cmake/build.py +++ b/project/cmake/build.py @@ -43,6 +43,8 @@ import subprocess import sys import tempfile +from project.configuration import Configuration + def _run_executable(cmd_line): logging.info('Running executable: %s', cmd_line) @@ -53,23 +55,6 @@ def _run_cmake(cmake_args): _run_executable(['cmake'] + cmake_args) -class Configuration(Enum): - DEBUG = 'Debug' - MINSIZEREL = 'MinSizeRel' - RELWITHDEBINFO = 'RelWithDebInfo' - RELEASE = 'Release' - - def __str__(self): - return self.value - - -def _parse_configuration(s): - try: - return Configuration(s) - except ValueError: - raise argparse.ArgumentTypeError(f'invalid configuration: {s}') - - @contextmanager def _create_build_dir(args): if args.build_dir is not None: @@ -151,7 +136,7 @@ def _parse_args(argv=None): type=_parse_dir, help='install directory') parser.add_argument('--configuration', metavar='CONFIG', - type=_parse_configuration, default=Configuration.DEBUG, + type=Configuration.parse, default=Configuration.DEBUG, help=f'build configuration ({"/".join(map(str, Configuration))})') parser.add_argument('src_dir', metavar='DIR', type=_parse_dir, diff --git a/project/configuration.py b/project/configuration.py new file mode 100644 index 0000000..50489fa --- /dev/null +++ b/project/configuration.py @@ -0,0 +1,42 @@ +# Copyright (c) 2020 Egor Tensin +# This file is part of the "cmake-common" project. +# For details, see https://github.com/egor-tensin/cmake-common. +# Distributed under the MIT License. + +import argparse +from enum import Enum + + +class Configuration(Enum): + '''Correspond to CMake's default CMAKE_BUILD_TYPE values.''' + + DEBUG = 'Debug' + MINSIZEREL = 'MinSizeRel' + RELWITHDEBINFO = 'RelWithDebInfo' + RELEASE = 'Release' + + def __str__(self): + return self.value + + @staticmethod + def all(): + return tuple(Configuration) + + @staticmethod + def parse(s): + try: + return Configuration(s) + except ValueError: + raise argparse.ArgumentTypeError(f'invalid configuration: {s}') + + def to_boost_variant(self): + '''Roughly maps CMake's CMAKE_BUILD_TYPE to Boost's variant. + + AFAIK, Boost only supports debug/release, MinSizeRel and RelWithDebInfo + are hence mapped to "release". The libraries will still reside in + stage/PLATFORM/CONFIGURATION/lib, if CONFIGURATION is + MinSizeRel/RelWithDebInfo. + ''' + if self in (Configuration.MINSIZEREL, Configuration.RELWITHDEBINFO): + return Configuration.RELEASE.to_boost_variant() + return str(self).lower() diff --git a/project/linkage.py b/project/linkage.py new file mode 100644 index 0000000..7019049 --- /dev/null +++ b/project/linkage.py @@ -0,0 +1,26 @@ +# Copyright (c) 2020 Egor Tensin +# This file is part of the "cmake-common" project. +# For details, see https://github.com/egor-tensin/cmake-common. +# Distributed under the MIT License. + +import argparse +from enum import Enum + + +class Linkage(Enum): + STATIC = 'static' + SHARED = 'shared' + + def __str__(self): + return self.value + + @staticmethod + def all(): + return tuple(Linkage) + + @staticmethod + def parse(s): + try: + return Linkage(s) + except ValueError: + raise argparse.ArgumentTypeError(f'invalid linkage: {s}') diff --git a/project/platform.py b/project/platform.py new file mode 100644 index 0000000..63f6231 --- /dev/null +++ b/project/platform.py @@ -0,0 +1,41 @@ +# Copyright (c) 2020 Egor Tensin +# This file is part of the "cmake-common" project. +# For details, see https://github.com/egor-tensin/cmake-common. +# Distributed under the MIT License. + +import argparse +from enum import Enum + + +class Platform(Enum): + '''I only build for x86(-64), so here it goes. + + Win32 is just Visual Studio convention, it's effectively an alias for x86. + ''' + + X86 = 'x86' + X64 = 'x64' + WIN32 = 'Win32' + + def __str__(self): + return self.value + + @staticmethod + def all(): + return (Platform.X86, Platform.X64) + + @staticmethod + def parse(s): + try: + return Platform(s) + except ValueError: + raise argparse.ArgumentTypeError(f'invalid platform: {s}') + + def get_address_model(self): + if self is Platform.X86: + return 32 + if self is Platform.X64: + return 64 + if self is Platform.WIN32: + return 32 + raise NotImplementedError(f'unsupported platform: {self}') -- cgit v1.2.3