Ich verwende CMake unter Windows mit dem Windows SDK und NMake Makefiles.
Standardmäßig wird es mit dem /MD
Compiler-Schalter kompiliert .
Wie kann ich es ändern, um es /MT
stattdessen mit dem Switch zu kompilieren ?
Antworten:
Sie können die CMAKE_CXX_FLAGS_<Build Type>
und / oder CMAKE_C_FLAGS_<Build Type>
Variablen ändern :
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
Wenn Ihre CMake-Flags bereits enthalten sind /MD
, können Sie sicherstellen, dass die obigen Befehle nach dem Einfügepunkt ausgeführt werden /MD
(das spätere Hinzufügen /MT
überschreibt die widersprüchliche vorhandene Option), oder Sie können die Flags von Grund auf neu setzen:
set(CMAKE_CXX_FLAGS_RELEASE "/MT")
set(CMAKE_CXX_FLAGS_DEBUG "/MTd")
Oder alternativ können Sie die bestehenden ersetzen /MD
und /MDd
Werte mit /MT
und /MTd
jeweils durch etwas zu tun , wie:
set(CompilerFlags
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
string(REPLACE...)
Befehl gemacht - er ist jetzt behoben.
CMake hat dies in Version 3.15 mit der Zieleigenschaft endlich richtig unterstützt MSVC_RUNTIME_LIBRARY
:
cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0091 NEW)
project(my_project)
add_executable(foo foo.c)
set_property(TARGET foo PROPERTY
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
Sie können auch einen globalen Standard angeben, indem Sie CMAKE_MSVC_RUNTIME_LIBRARY
stattdessen die Variable festlegen .
cmake_policy(SET CMP0091 NEW)
auf 3.16.3, ist es wirklich erforderlich?
cmake_minimum_required
, müssen Sie das neue Verhalten nicht explizit anfordern , wenn es neu genug ist. Ich habe die Richtlinie größtenteils in die Antwort aufgenommen, damit die Benutzer wissen, dass für diese Funktion eine Richtlinie vorhanden ist, und sie nachschlagen, wenn sie sich um die Auswirkungen auf die Kompatibilität kümmern.
Es scheint , dass für Visual Studio 15 2017 und CMake 3.12 die Art und Weise zu ersetzen /MD
durch , /MT
indem Sie diesen Schnipsel in die CMakeLists.txt Datei ist:
if(MSVC)
add_compile_options(
$<$<CONFIG:>:/MT> #---------|
$<$<CONFIG:Debug>:/MTd> #---|-- Statically link the runtime libraries
$<$<CONFIG:Release>:/MT> #--|
)
endif()
Ich habe diese Lösung im offiziellen CMake-Repository gefunden: https://gitlab.kitware.com/cmake/cmake/issues/18390
add_executable
oderadd_library
Ich muss verwenden set( ... CACHE ... FORCE)
, um den Standard-Cache von MSVC zu überschreiben.
Wenn ich diese Methode nicht verwende, gibt MSVC weiterhin /MD
Optionen aus.
set(CompilerFlags
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELWITHDEBINFO
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
set(${CompilerFlag} "${${CompilerFlag}}" CACHE STRING "msvc compiler flags" FORCE)
message("MSVC flags: ${CompilerFlag}:${${CompilerFlag}}")
endforeach()
Überprüfen Sie ucm_set_runtime - dieses Makro ersetzt die Flags für die statische oder dynamische Laufzeit - um die Auswirkungen zu sehen, verwenden Sie ucm_print_flags ( überprüfen Sie auch diese Frage zum Stapelüberlauf ).