cmake_minimum_required(VERSION 3.12 FATAL_ERROR) include(GNUInstallDirs) project(mcl LANGUAGES CXX VERSION 0.1.12) # Determine if we're built as a subproject (using add_subdirectory) # or if this is the master project. set(MASTER_PROJECT OFF) if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(MASTER_PROJECT ON) endif() # Project options option(MCL_WARNINGS_AS_ERRORS "Warnings as errors" ${MASTER_PROJECT}) option(MCL_INSTALL "Enable installation" ${MASTER_PROJECT}) # Default to a Release build if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) message(STATUS "Defaulting to a Release build") endif() # Set hard requirements for C++ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # Warn on CMake API deprecations set(CMAKE_WARN_DEPRECATED ON) # Disable in-source builds set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") message(SEND_ERROR "In-source builds are not allowed.") endif() # Add the module directory to the list of paths list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") # Compiler flags if (MSVC) set(MCL_CXX_FLAGS /std:c++latest /experimental:external /external:W0 /external:anglebrackets /W4 /w44263 # Non-virtual member function hides base class virtual function /w44265 # Class has virtual functions, but destructor is not virtual /w44456 # Declaration of 'var' hides previous local declaration /w44457 # Declaration of 'var' hides function parameter /w44458 # Declaration of 'var' hides class member /w44459 # Declaration of 'var' hides global definition /w44946 # Reinterpret-cast between related types /wd4592 # Symbol will be dynamically initialized (implementation limitation) /permissive- # Stricter C++ standards conformance /MP /Zi /Zo /EHsc /Zc:externConstexpr # Allows external linkage for variables declared "extern constexpr", as the standard permits. /Zc:inline # Omits inline functions from object-file output. /Zc:throwingNew # Assumes new (without std::nothrow) never returns null. /volatile:iso # Use strict standard-abiding volatile semantics /bigobj # Increase number of sections in .obj files /DNOMINMAX) if (MCL_WARNINGS_AS_ERRORS) list(APPEND MCL_CXX_FLAGS /WX) endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") list(APPEND MCL_CXX_FLAGS -Qunused-arguments -Wno-missing-braces) endif() else() set(MCL_CXX_FLAGS -Wall -Wextra -Wcast-qual -pedantic -pedantic-errors -Wfatal-errors -Wno-missing-braces) if (MCL_WARNINGS_AS_ERRORS) list(APPEND MCL_CXX_FLAGS -Werror) endif() endif() # Dependencies if (NOT TARGET Catch2::Catch2) find_package(Catch2 3 QUIET) endif() if (NOT TARGET fmt::fmt) find_package(fmt REQUIRED) endif() # Project files add_subdirectory(src) if (TARGET Catch2::Catch2 AND MASTER_PROJECT) add_subdirectory(tests) endif() # Install instructions if (MCL_INSTALL) include(GNUInstallDirs) include(CMakePackageConfigHelpers) install(TARGETS mcl EXPORT mclTargets) install(EXPORT mclTargets NAMESPACE merry:: DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mcl" ) configure_package_config_file(CMakeModules/mclConfig.cmake.in mclConfig.cmake INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mcl" ) write_basic_package_version_file(mclConfigVersion.cmake COMPATIBILITY SameMajorVersion ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mclConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/mclConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mcl" ) install(DIRECTORY include/ TYPE INCLUDE FILES_MATCHING PATTERN "*.hpp") endif()