Windows with MSVC
Triplets
kmpkg includes triplets for building Windows desktop applications using the MSVC cl.exe compiler.
| Architecture | kmpkg triplets | Community |
|---|---|---|
| x64 | x64-windows | |
| x64-windows-release | Yes | |
| x64-windows-static | ||
| x64-windows-static-md | Yes | |
| x64-windows-static-release | Yes | |
| x86 | x86-windows | |
| x86-windows-static | Yes | |
| x86-windows-static-md | Yes | |
| arm | arm-windows | Yes |
| arm-windows-static | Yes | |
| arm64 | arm64-windows | |
| arm64-windows-static | Yes | |
| arm64-windows-static-md | Yes | |
| arm64-windows-static-release | Yes | |
| arm64ec | arm64ec-windows | Yes |
The static linking triplets are set to use the MSVC Runtime as a static library (i.e. KMPKG_CRT_LINKAGE static).
The static-md linking triplets are set to use the MSVC Runtime as a DLL (i.e. KMPKG_CRT_LINKAGE dynamic). This is the recommended solution for redistributing the MSVC Runtime per Microsoft Learn.
Selecting a MSVC toolset
By default, kmpkg will use the latest version of Visual Studio installed on the system for building code. To select a specific version, create a custom triplet or triplet overlay to set KMPKG_PLATFORM_TOOLSET.
For examples, this would force the use of the Visual Studio 2017 toolset.
set(KMPKG_PLATFORM_TOOLSET v141)
Maintainer notes
CMake projects for these triplets are built using CMAKE_SYSTEM_NAME set to "Windows".
Library author notes
- "Just My Code" debugging can usually be disabled in a library to save code space.
if(MSVC)
target_compile_options(mytarget PRIVATE /JMC-)
endif()
- MSBuild will automatically add some build flags that are not on-by-default in the MSVC compiler itself. To ensure the same behavior with Ninja or other generators, add these build settings.
if(MSVC)
target_compile_options(mytarget PRIVATE /Zc:inline)
endif()
- Recommended build settings for newer versions of MSVC are encouraged for improved code security.
if(MSVC)
target_compile_options(mytarget PRIVATE "$<$<NOT:$<CONFIG:DEBUG>>:/guard:cf>")
target_link_options(mytarget PRIVATE /DYNAMICBASE /NXCOMPAT)
if((CMAKE_SIZEOF_VOID_P EQUAL 4)
AND (NOT (${KMPKG_TARGET_ARCHITECTURE} MATCHES "^arm")))
target_link_options(mytarget PRIVATE /SAFESEH)
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(mytarget PRIVATE "$<$<NOT:$<CONFIG:DEBUG>>:/guard:ehcont>")
target_link_options(mytarget PRIVATE "$<$<NOT:$<CONFIG:DEBUG>>:/guard:ehcont>")
endif()
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(mytarget PRIVATE /sdl)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.24)
target_compile_options(mytarget PRIVATE /ZH:SHA_256)
endif()
if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.27)
AND (NOT (${KMPKG_TARGET_ARCHITECTURE} MATCHES "^arm")))
target_link_options(mytarget PRIVATE /CETCOMPAT)
endif()
endif()
- For improved Standard C/C++ Conformance, use the latest switch settings.
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(mytarget PRIVATE /permissive- /Zc:__cplusplus /Zc:inline)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.26)
target_compile_options(mytarget PRIVATE /Zc:preprocessor)
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28)
target_compile_options(mytarget PRIVATE /Zc:lambda)
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.35)
target_compile_options(mytarget PRIVATE /Zc:templateScope)
endif()
endif()
- To support the use of Whole Program Optimization / Link-Time Code Generation, recommended build settings are as follows:
if((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND CMAKE_INTERPROCEDURAL_OPTIMIZATION)
target_compile_options(${PROJECT_NAME} PRIVATE /Gy /Gw)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.35)
target_compile_options(mytarget PRIVATE /Zc:checkGwOdr)
endif()
endif()
- If enabling Spectre mitigations, use the following guards.
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
if((MSVC_VERSION GREATER_EQUAL 1913) AND (NOT WINDOWS_STORE))
target_compile_options(mytarget PRIVATE "/Qspectre")
endif()
endif()
Note you may want to also provide an explicit CMake build option to control this as well.