diff options
Diffstat (limited to 'project/platform.py')
-rw-r--r-- | project/platform.py | 105 |
1 files changed, 98 insertions, 7 deletions
diff --git a/project/platform.py b/project/platform.py index d25827b..b19c93a 100644 --- a/project/platform.py +++ b/project/platform.py @@ -6,19 +6,29 @@ import argparse from enum import Enum import platform +import os.path +from project.os import on_windows -class Platform(Enum): - '''I only build for x86(-64), so here it goes.''' +class Platform(Enum): + # I only build for x86(-64), so here it goes. X86 = 'x86' X64 = 'x64' + # 'auto' means that no additional arguments will be passed to either + # Boost's b2 nor CMake (except on Windows, see below). + AUTO = 'auto' def __str__(self): return str(self.value) @staticmethod - def native(): + def windows_native(): + # On Windows, no explicit platform would mean x64 for VS 2019 and x86 + # for VS 2017. To account for this discrepancy, it is assumed that + # Windows builds can only target either x86 or x64 (which I don't think + # is true?), and we default to x64 most of the time. + # # Source: https://stackoverflow.com/a/12578715/514684 if platform.machine().endswith('64'): return Platform.X64 @@ -26,30 +36,111 @@ class Platform(Enum): @staticmethod def all(): - return tuple(Platform) + return Platform.X86, Platform.X64, @staticmethod def parse(s): try: if s == 'Win32': - # AppVeyor convention: + # Visual Studio/AppVeyor convention: return Platform.X86 return Platform(s) except ValueError as e: raise argparse.ArgumentTypeError(f'invalid platform: {s}') from e - def get_address_model(self): + def mingw_prefix(self): + if self is Platform.AUTO: + if on_windows(): + # On Windows, use the host architecture. + return Platform.windows_native().mingw_prefix() + # On Linux, assume that the target is x64. + return Platform.X64.mingw_prefix() + if self is Platform.X86: + return 'i686' + if self is Platform.X64: + return 'x86_64' + raise NotImplementedError(f'unsupported platform: {self}') + + def address_model(self): '''Maps to Boost's address-model.''' + if self is Platform.AUTO: + if on_windows(): + # On Windows, use the host architecture. + return Platform.windows_native().address_model() + # On Linux, assume that the target is x64. + raise RuntimeError('cannot determine address model unless the target platform is specified explicitly') if self is Platform.X86: return 32 if self is Platform.X64: return 64 raise NotImplementedError(f'unsupported platform: {self}') - def get_cmake_arch(self): + def stagedir(self, configuration): + '''Path to the built libraries inside the Boost build directory.''' + if self is Platform.AUTO: + if on_windows(): + # On Windows, use the host architecture. + return Platform.windows_native().stagedir(configuration) + # On Linux, the libraries are stored in stage/auto/CONFIGURATION/lib. + return os.path.join('stage', str(self), str(configuration)) + + def boost_librarydir(self, configuration): + '''Same as above, but for CMake; adds /lib/ at the end.''' + return os.path.join(self.stagedir(configuration), 'lib') + + def b2_address_model(self): + if self is Platform.AUTO and not on_windows(): + # On Linux, don't specify the architecture explicitly (it is + # assumed that the host architecture will be targeted). + return [] + return [f'address-model={self.address_model()}'] + + def b2_stagedir(self, configuration): + return [f'--stagedir={self.stagedir(configuration)}'] + + def b2_args(self, configuration): + args = [] + args += self.b2_address_model() + args += self.b2_stagedir(configuration) + return args + + def makefile_toolchain_file(self): + # For Makefile generators, we make a special toolchain file that + # specifies the -m32/-m64 flags, etc. + if self is Platform.AUTO: + # Let the compiler decide. + return '' + if self is Platform.X86: + address_model = 32 + elif self is Platform.X64: + address_model = 64 + else: + raise NotImplementedError(f'unsupported platform: {self}') + return f''' +set(CMAKE_C_FLAGS -m{address_model}) +set(CMAKE_CXX_FLAGS -m{address_model}) +''' + + def msvc_arch(self): '''Maps to CMake's -A argument for MSVC.''' + if self is Platform.AUTO: + if on_windows(): + # On Windows, use the host architecture. + return Platform.windows_native().msvc_arch() + # I don't think the -A argument is supported on any generators + # except the Visual Studio ones. + raise RuntimeError('-A parameter is only supported for Visual Studio generators') if self is Platform.X86: return 'Win32' if self is Platform.X64: return 'x64' raise NotImplementedError(f'unsupported platform: {self}') + + def cmake_msvc_arch(self): + return ['-A', self.msvc_arch()] + + def cmake_msvc_args(self): + # When using the MSVC toolset, pass the appropriate -A flag. + args = [] + args += self.cmake_msvc_arch() + return args |