diff options
Diffstat (limited to 'project/cmake/toolchain.py')
-rw-r--r-- | project/cmake/toolchain.py | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/project/cmake/toolchain.py b/project/cmake/toolchain.py deleted file mode 100644 index c12ee84..0000000 --- a/project/cmake/toolchain.py +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> -# This file is part of the "cmake-common" project. -# For details, see https://github.com/egor-tensin/cmake-common. -# Distributed under the MIT License. - -# See docs/cmake.md for a more thorough description of my pain. - -import abc -import os.path -import shutil - -import project.mingw -from project.os import on_windows -from project.platform import Platform -from project.toolchain import ToolchainType - - -class Toolchain(abc.ABC): - @abc.abstractmethod - def cmake_args(self): - pass - - @abc.abstractmethod - def build_system_args(self): - pass - - @staticmethod - def detect(hint, platform, build_dir): - if hint is ToolchainType.AUTO: - if on_windows(): - # On Windows, 'auto' means 'msvc', and we need to specify the - # -A parameter. This might break if none of the Visual Studio - # generators are available, but the NMake one is, although I - # don't know how this can be possible normally. - hint = ToolchainType.MSVC - else: - # On Linux, if the platform wasn't specified, auto-detect - # everything. There's no need to set -mXX flags, etc. - if platform is Platform.AUTO: - return Auto() - # If a specific platform was requested, we might need to set - # some CMake/compiler flags, like -m32/-m64. - hint = ToolchainType.GCC - if hint is ToolchainType.MSVC: - return MSVC(platform) - if hint is ToolchainType.GCC: - return GCC.setup(platform, build_dir) - if hint is ToolchainType.MINGW: - return MinGW.setup(platform, build_dir) - if hint is ToolchainType.CLANG: - return Clang.setup(platform, build_dir) - if hint is ToolchainType.CLANG_CL: - return ClangCL.setup(platform, build_dir) - raise NotImplementedError(f'unrecognized toolset: {hint}') - - -class Auto(Toolchain): - def cmake_args(self): - return [] - - def build_system_args(self): - return [] - - -class MSVC(Auto): - def __init__(self, platform): - self.platform = platform - - def cmake_args(self): - # This doesn't actually specify the generator of course, but I don't - # want to implement VS detection logic. - return ['-A', self.platform.msvc_arch()] - - def build_system_args(self): - return [] - - -class Makefile(Toolchain): - def __init__(self, path): - self.path = path - - @staticmethod - def _get_config_path(build_dir): - return os.path.join(build_dir, 'custom_toolchain.cmake') - - @staticmethod - def _get_makefile_generator(): - if on_windows(): - if shutil.which('mingw32-make'): - return 'MinGW Makefiles' - return 'Unix Makefiles' - # On Linux/Cygwin, make all the way: - return 'Unix Makefiles' - - @classmethod - def write_config(cls, build_dir, contents): - path = Makefile._get_config_path(build_dir) - with open(path, mode='w') as file: - file.write(contents) - return cls(path) - - def cmake_args(self): - return [ - '-D', f'CMAKE_TOOLCHAIN_FILE={self.path}', - # The Visual Studio generator is the default on Windows, override - # it: - '-G', self._get_makefile_generator(), - ] - - def build_system_args(self): - return [] - - -class GCC(Makefile): - @staticmethod - def _format(platform): - return f''' -set(CMAKE_C_COMPILER gcc) -set(CMAKE_CXX_COMPILER g++) -{platform.makefile_toolchain_file()}''' - - @staticmethod - def setup(platform, build_dir): - return GCC.write_config(build_dir, GCC._format(platform)) - - -class MinGW(Makefile): - @staticmethod - def _format(platform): - paths = project.mingw.MinGW(platform) - return f''' -set(CMAKE_C_COMPILER {paths.gcc()}) -set(CMAKE_CXX_COMPILER {paths.gxx()}) -set(CMAKE_AR {paths.ar()}) -set(CMAKE_RANLIB {paths.ranlib()}) -set(CMAKE_RC_COMPILER {paths.windres()}) -set(CMAKE_SYSTEM_NAME Windows) -''' - - @staticmethod - def setup(platform, build_dir): - return MinGW.write_config(build_dir, MinGW._format(platform)) - - -class Clang(Makefile): - @staticmethod - def _format(platform): - return f''' -if(CMAKE_VERSION VERSION_LESS "3.15" AND WIN32) - set(CMAKE_C_COMPILER clang-cl) - set(CMAKE_CXX_COMPILER clang-cl) -else() - set(CMAKE_C_COMPILER clang) - set(CMAKE_CXX_COMPILER clang++) -endif() -{platform.makefile_toolchain_file()}''' - - def _get_makefile_generator(self): - if on_windows(): - # MinGW utilities like make might be unavailable, but NMake can - # very much be there. - if shutil.which('nmake'): - return 'NMake Makefiles' - return super()._get_makefile_generator() - - @staticmethod - def setup(platform, build_dir): - return Clang.write_config(build_dir, Clang._format(platform)) - - -class ClangCL(Clang): - @staticmethod - def _format(platform): - return f''' -set(CMAKE_C_COMPILER clang-cl) -set(CMAKE_CXX_COMPILER clang-cl) -set(CMAKE_SYSTEM_NAME Windows) -{platform.makefile_toolchain_file()}''' - - @staticmethod - def setup(platform, build_dir): - return ClangCL.write_config(build_dir, ClangCL._format(platform)) |