From d61ac21d871bc38840d48b02bd61a4fa00f8d4f4 Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Tue, 17 Dec 2024 12:19:36 -0800 Subject: [PATCH] Refactored CMake --- CMakeLists.txt | 82 ++----------------- build/CompilerAndLinker.cmake | 144 ++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 74 deletions(-) create mode 100644 build/CompilerAndLinker.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 79ab67c..98a85df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,29 +23,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") -if(DEFINED VCPKG_TARGET_ARCHITECTURE) - set(DIRECTX_ARCH ${VCPKG_TARGET_ARCHITECTURE}) -elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Ww][Ii][Nn]32$") - set(DIRECTX_ARCH x86) -elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Xx]64$") - set(DIRECTX_ARCH x64) -elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Aa][Rr][Mm]$") - set(DIRECTX_ARCH arm) -elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Aa][Rr][Mm]64$") - set(DIRECTX_ARCH arm64) -elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Aa][Rr][Mm]64EC$") - set(DIRECTX_ARCH arm64ec) -elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Ww][Ii][Nn]32$") - set(DIRECTX_ARCH x86) -elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Xx]64$") - set(DIRECTX_ARCH x64) -elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Aa][Rr][Mm]$") - set(DIRECTX_ARCH arm) -elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Aa][Rr][Mm]64$") - set(DIRECTX_ARCH arm64) -elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Aa][Rr][Mm]64EC$") - set(DIRECTX_ARCH arm64ec) -endif() +include(build/CompilerAndLinker.cmake) add_executable(${PROJECT_NAME} WIN32 ddraw.cpp @@ -75,39 +53,14 @@ if(BUILD_WITH_NEW_DX12) endif() if(MSVC) - target_compile_options(${PROJECT_NAME} PRIVATE /W4 /GR- "$<$>:/guard:cf>") - target_link_options(${PROJECT_NAME} PRIVATE /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO) - - if((CMAKE_SIZEOF_VOID_P EQUAL 4) AND (NOT ${DIRECTX_ARCH} MATCHES "^arm")) - target_link_options(${PROJECT_NAME} PRIVATE /SAFESEH) - endif() - - if((MSVC_VERSION GREATER_EQUAL 1924) - AND ((NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0))) - target_compile_options(${PROJECT_NAME} PRIVATE /ZH:SHA_256) - endif() - - if((MSVC_VERSION GREATER_EQUAL 1928) - AND (CMAKE_SIZEOF_VOID_P EQUAL 8) - AND ((NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0))) - target_compile_options(${PROJECT_NAME} PRIVATE "$<$>:/guard:ehcont>") - target_link_options(${PROJECT_NAME} PRIVATE "$<$>:/guard:ehcont>") - endif() -else() - target_compile_definitions(${PROJECT_NAME} PRIVATE $,_DEBUG,NDEBUG>) + target_compile_options(${PROJECT_NAME} PRIVATE /W4 /GR-) endif() -if(NOT ${DIRECTX_ARCH} MATCHES "^arm") - if(${CMAKE_SIZEOF_VOID_P} EQUAL "4") - set(ARCH_SSE2 $<$:/arch:SSE2> $<$>:-msse2>) - else() - set(ARCH_SSE2 $<$>:-msse2>) - endif() - - target_compile_options(${PROJECT_NAME} PRIVATE ${ARCH_SSE2}) -endif() +target_compile_definitions(${PROJECT_NAME} PRIVATE ${COMPILER_DEFINES}) +target_compile_options(${PROJECT_NAME} PRIVATE ${COMPILER_SWITCHES}) +target_link_options(${PROJECT_NAME} PRIVATE ${LINKER_SWITCHES}) -if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) +if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|IntelLLVM" ) target_compile_options(${PROJECT_NAME} PRIVATE "-Wpedantic" "-Wextra" "-Wno-c++98-compat" "-Wno-c++98-compat-pedantic" @@ -115,26 +68,8 @@ if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) "-Wno-missing-field-initializers") target_compile_options(${PROJECT_NAME} PRIVATE ${WarningsEXE}) elseif ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" ) - target_compile_options(${PROJECT_NAME} PRIVATE /sdl /permissive- /JMC- /Zc:__cplusplus /Zc:inline) - if(ENABLE_CODE_ANALYSIS) - target_compile_options(${PROJECT_NAME} PRIVATE /analyze) - endif() - - if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.26) - target_compile_options(${PROJECT_NAME} PRIVATE /Zc:preprocessor /wd5105) - endif() - - if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.27) AND (NOT (${DIRECTX_ARCH} MATCHES "^arm"))) - target_link_options(${PROJECT_NAME} PRIVATE /CETCOMPAT) - endif() - - if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28) - target_compile_options(${PROJECT_NAME} PRIVATE /Zc:lambda) - endif() - - if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.35) - target_compile_options(${PROJECT_NAME} PRIVATE /Zc:checkGwOdr $<$:/Zc:templateScope>) + target_compile_options(${PROJECT_NAME} PRIVATE /analyze /WX) endif() endif() @@ -147,14 +82,13 @@ if(WIN32) set(WINVER 0x0601) endif() - target_compile_definitions(${PROJECT_NAME} PRIVATE _MBCS _WIN32_WINNT=${WINVER}) + target_compile_definitions(${PROJECT_NAME} PRIVATE _WIN32_WINNT=${WINVER}) endif() set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME}) install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - if(WIN32) if(${DIRECTX_ARCH} STREQUAL "x86") set(NUGET_ARCH win32) diff --git a/build/CompilerAndLinker.cmake b/build/CompilerAndLinker.cmake new file mode 100644 index 0000000..166ea84 --- /dev/null +++ b/build/CompilerAndLinker.cmake @@ -0,0 +1,144 @@ +# This modules provides variables with recommended Compiler and Linker switches +# +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +set(COMPILER_DEFINES "") +set(COMPILER_SWITCHES "") +set(LINKER_SWITCHES "") + +#--- Determines target architecture if not explicitly set +if(DEFINED VCPKG_TARGET_ARCHITECTURE) + set(DIRECTX_ARCH ${VCPKG_TARGET_ARCHITECTURE}) +elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Ww][Ii][Nn]32$") + set(DIRECTX_ARCH x86) +elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Xx]64$") + set(DIRECTX_ARCH x64) +elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Aa][Rr][Mm]$") + set(DIRECTX_ARCH arm) +elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Aa][Rr][Mm]64$") + set(DIRECTX_ARCH arm64) +elseif(CMAKE_GENERATOR_PLATFORM MATCHES "^[Aa][Rr][Mm]64EC$") + set(DIRECTX_ARCH arm64ec) +elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Ww][Ii][Nn]32$") + set(DIRECTX_ARCH x86) +elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Xx]64$") + set(DIRECTX_ARCH x64) +elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Aa][Rr][Mm]$") + set(DIRECTX_ARCH arm) +elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Aa][Rr][Mm]64$") + set(DIRECTX_ARCH arm64) +elseif(CMAKE_VS_PLATFORM_NAME_DEFAULT MATCHES "^[Aa][Rr][Mm]64EC$") + set(DIRECTX_ARCH arm64ec) +endif() + +#--- Determines host architecture +if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "[Aa][Rr][Mm]64|aarch64|arm64") + set(DIRECTX_HOST_ARCH arm64) +else() + set(DIRECTX_HOST_ARCH x64) +endif() + +#--- This legacy tool still uses MB instead of UNICODE +if(WIN32) + list(APPEND COMPILER_DEFINES _MBCS) +endif() + +#--- General MSVC-like SDL options +if(MSVC) + list(APPEND COMPILER_SWITCHES "$<$>:/guard:cf>") + list(APPEND LINKER_SWITCHES /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO) + + if((${DIRECTX_ARCH} STREQUAL "x86") + OR ((CMAKE_SIZEOF_VOID_P EQUAL 4) AND (NOT (${DIRECTX_ARCH} MATCHES "^arm")))) + list(APPEND LINKER_SWITCHES /SAFESEH) + endif() + + if((MSVC_VERSION GREATER_EQUAL 1928) + AND (CMAKE_SIZEOF_VOID_P EQUAL 8) + AND (NOT (TARGET OpenEXR::OpenEXR)) + AND ((NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang|IntelLLVM")) OR (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0))) + list(APPEND COMPILER_SWITCHES "$<$>:/guard:ehcont>") + list(APPEND LINKER_SWITCHES "$<$>:/guard:ehcont>") + endif() +else() + list(APPEND COMPILER_DEFINES $,_DEBUG,NDEBUG>) +endif() + +#--- Target architecture switches +if(NOT (${DIRECTX_ARCH} MATCHES "^arm")) + if((${DIRECTX_ARCH} STREQUAL "x86") OR (CMAKE_SIZEOF_VOID_P EQUAL 4)) + set(ARCH_SSE2 $<$:/arch:SSE2> $<$>:-msse2>) + else() + set(ARCH_SSE2 $<$>:-msse2>) + endif() + + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + list(APPEND ARCH_SSE2 -mfpmath=sse) + endif() + + list(APPEND COMPILER_SWITCHES ${ARCH_SSE2}) +endif() + +#--- Compiler-specific switches +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|IntelLLVM") + if(MSVC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)) + list(APPEND COMPILER_SWITCHES /ZH:SHA_256) + endif() +elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel") + list(APPEND COMPILER_SWITCHES /Zc:__cplusplus /Zc:inline /fp:fast /Qdiag-disable:161) +elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + list(APPEND COMPILER_SWITCHES /sdl /Zc:inline /fp:fast) + + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + message(STATUS "Building using Whole Program Optimization") + list(APPEND COMPILER_SWITCHES $<$>:/Gy /Gw>) + endif() + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.10) + list(APPEND COMPILER_SWITCHES /permissive-) + endif() + + if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.11) + AND OpenMP_CXX_FOUND) + # OpenMP in MSVC is not compatible with /permissive- unless you disable two-phase lookup + list(APPEND COMPILER_SWITCHES /Zc:twoPhase-) + endif() + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.14) + list(APPEND COMPILER_SWITCHES /Zc:__cplusplus) + endif() + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.15) + list(APPEND COMPILER_SWITCHES /JMC-) + endif() + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.24) + list(APPEND COMPILER_SWITCHES /ZH:SHA_256) + endif() + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.26) + list(APPEND COMPILER_SWITCHES /Zc:preprocessor /wd5104 /wd5105) + endif() + + if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.27) AND (NOT (${DIRECTX_ARCH} MATCHES "^arm"))) + list(APPEND LINKER_SWITCHES /CETCOMPAT) + endif() + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28) + list(APPEND COMPILER_SWITCHES /Zc:lambda) + endif() + + if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29) + AND (NOT VCPKG_TOOLCHAIN)) + list(APPEND COMPILER_SWITCHES /external:W4) + endif() + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.35) + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + list(APPEND COMPILER_SWITCHES $<$>:/Zc:checkGwOdr>) + endif() + + list(APPEND COMPILER_SWITCHES $<$:/Zc:templateScope>) + endif() +endif()