diff options
Diffstat (limited to '')
-rw-r--r-- | project/cmake/build.py | 3 | ||||
-rw-r--r-- | project/cmake/toolset.py | 159 |
2 files changed, 1 insertions, 161 deletions
diff --git a/project/cmake/build.py b/project/cmake/build.py index 6c5c68c..7513336 100644 --- a/project/cmake/build.py +++ b/project/cmake/build.py @@ -26,10 +26,9 @@ import os import sys import tempfile -from project.cmake.toolset import Toolset from project.configuration import Configuration from project.platform import Platform -from project.toolset import ToolsetHint +from project.toolset import Toolset, ToolsetHint from project.utils import normalize_path, mkdir_parent, run, setup_logging diff --git a/project/cmake/toolset.py b/project/cmake/toolset.py deleted file mode 100644 index f996d6b..0000000 --- a/project/cmake/toolset.py +++ /dev/null @@ -1,159 +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.toolset import ToolsetHint - - -class Toolset(abc.ABC): - def cmake_args(self, build_dir, platform): - return [] - - def build_system_args(self): - return [] - - @staticmethod - def detect(hint): - if hint is ToolsetHint.AUTO: - return Auto - if hint is ToolsetHint.MSVC: - return MSVC - if hint is ToolsetHint.GCC: - return GCC - if hint is ToolsetHint.MINGW: - return MinGW - if hint is ToolsetHint.CLANG: - return Clang - if hint is ToolsetHint.CLANG_CL: - return ClangCL - raise NotImplementedError(f'unrecognized toolset: {hint}') - - @staticmethod - def make(hint, platform): - cls = Toolset.detect(hint) - if cls is MinGW: - return MinGW(platform) - return cls() - - -class Auto(Toolset): - def cmake_args(self, build_dir, platform): - 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. - return MSVC().cmake_args(build_dir, platform) - # 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 [] - # If a specific platform was requested, we might need to set some - # CMake/compiler flags, like -m32/-m64. - return GCC().cmake_args(build_dir, platform) - - -class MSVC(Auto): - def cmake_args(self, build_dir, platform): - # This doesn't actually specify the generator of course, but I don't - # want to implement VS detection logic. - return ['-A', platform.msvc_arch()] - - -class Makefile(Toolset): - @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' - - @staticmethod - def _write_config(build_dir, contents): - path = Makefile._get_config_path(build_dir) - with open(path, mode='w') as file: - file.write(contents) - return path - - @abc.abstractmethod - def format_cmake_toolset_file(self, platform): - pass - - def cmake_args(self, build_dir, platform): - contents = self.format_cmake_toolset_file(platform) - config_path = self._write_config(build_dir, contents) - return [ - '-D', f'CMAKE_TOOLCHAIN_FILE={config_path}', - # The Visual Studio generator is the default on Windows, override - # it: - '-G', self._get_makefile_generator(), - ] - - -class GCC(Makefile): - def format_cmake_toolset_file(self, platform): - return f''' -set(CMAKE_C_COMPILER gcc) -set(CMAKE_CXX_COMPILER g++) -{platform.makefile_toolset_file()}''' - - -class MinGW(Makefile): - def __init__(self, platform): - self.paths = project.mingw.MinGW(platform) - - def format_cmake_toolset_file(self, platform): - return f''' -set(CMAKE_C_COMPILER {self.paths.gcc()}) -set(CMAKE_CXX_COMPILER {self.paths.gxx()}) -set(CMAKE_AR {self.paths.ar()}) -set(CMAKE_RANLIB {self.paths.ranlib()}) -set(CMAKE_RC_COMPILER {self.paths.windres()}) -set(CMAKE_SYSTEM_NAME Windows) -''' - - -class Clang(Makefile): - def format_cmake_toolset_file(self, 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_toolset_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() - - -class ClangCL(Clang): - def format_cmake_toolset_file(self, platform): - return f''' -set(CMAKE_C_COMPILER clang-cl) -set(CMAKE_CXX_COMPILER clang-cl) -set(CMAKE_SYSTEM_NAME Windows) -{platform.makefile_toolset_file()}''' |