Je suis les instructions de l'entrée CMake FAQ "Comment puis-je créer mon application MSVC avec un runtime statique?" pour centraliser la sélection du runtime MSVC pour un groupe de projets CMake imbriqués (ils sont extraits en tant que sous-modules Git et ajoutés au projet maître à l'aide de la directive find_package()
de CMake).
J'ai donc écrit cette macro CMake:
macro(configure_msvc_runtime)
if(MSVC)
# Default to statically-linked runtime.
if("${MSVC_RUNTIME}" STREQUAL "")
set(MSVC_RUNTIME "static")
endif()
# Set compiler options.
set(variables
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
if(${MSVC_RUNTIME} STREQUAL "static")
message(STATUS
"MSVC -> forcing use of statically-linked runtime."
)
foreach(variable ${variables})
if(${variable} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}")
endif()
endforeach()
else()
message(STATUS
"MSVC -> forcing use of dynamically-linked runtime."
)
foreach(variable ${variables})
if(${variable} MATCHES "/MT")
string(REGEX REPLACE "/MT" "/MD" ${variable} "${${variable}}")
endif()
endforeach()
endif()
endif()
endmacro()
J'appelle cette macro au début de ma racine CMakeLists.txt
(Avant any add_library()
or add_executable()
appel est fait) et ajoutez un peu d'impressions de débogage:
configure_msvc_runtime()
set(variables
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
message(STATUS "Initial build flags:")
foreach(variable ${variables})
message(STATUS " '${variable}': ${${variable}}")
endforeach()
message(STATUS "")
Ensuite, j'exécute CMake pour générer une solution Visual Studio comme ceci:
cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=dynamic
et j'obtiens les sorties suivantes:
-- MSVC -> forcing use of dynamically-linked runtime.
-- Initial build flags:
-- 'CMAKE_C_FLAGS_DEBUG': /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
-- 'CMAKE_C_FLAGS_MINSIZEREL': /MD /O1 /Ob1 /D NDEBUG
-- 'CMAKE_C_FLAGS_RELEASE': /MD /O2 /Ob2 /D NDEBUG
-- 'CMAKE_C_FLAGS_RELWITHDEBINFO': /MD /Zi /O2 /Ob1 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_DEBUG': /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
-- 'CMAKE_CXX_FLAGS_MINSIZEREL': /MD /O1 /Ob1 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_RELEASE': /MD /O2 /Ob2 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_RELWITHDEBINFO': /MD /Zi /O2 /Ob1 /D NDEBUG
Maintenant, le fait est que lorsque je démarre Visual Studio et examine les propriétés du projet sous "C/C++, génération de code", je vois que le paramètre "Runtime Library" n'est pas cohérent avec les options imprimées dans le shell. Sous les configurations "Release", "MinSizeRel" et "RelWithDebInfo", j'obtiens les résultats attendus ("Multi-threaded DLL/MD", mais la configuration "Debug" affiche toujours "Multi- fileté/MT ").
De plus, lorsque je force l'utilisation du runtime lié statiquement, j'obtiens des résultats similaires. Si je cours
cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=static
J'obtiens les sorties suivantes:
-- MSVC -> forcing use of statically-linked runtime.
-- Initial build flags:
-- 'CMAKE_C_FLAGS_DEBUG': /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1
-- 'CMAKE_C_FLAGS_MINSIZEREL': /MT /O1 /Ob1 /D NDEBUG
-- 'CMAKE_C_FLAGS_RELEASE': /MT /O2 /Ob2 /D NDEBUG
-- 'CMAKE_C_FLAGS_RELWITHDEBINFO': /MT /Zi /O2 /Ob1 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_DEBUG': /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1
-- 'CMAKE_CXX_FLAGS_MINSIZEREL': /MT /O1 /Ob1 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_RELEASE': /MT /O2 /Ob2 /D NDEBUG
-- 'CMAKE_CXX_FLAGS_RELWITHDEBINFO': /MT /Zi /O2 /Ob1 /D NDEBUG
Et pourtant, toutes les configurations produisent la valeur "Multi-threaded/MT" pour le paramètre "Runtime Library".
Qu'est-ce que je fais mal, ou si c'est un bogue dans CMake (2.8.7) ou quelque chose?
Pour ce que ça vaut, si je génère des fichiers de projet Visual Studio 2010, j'obtiens une valeur différente pour la configuration "Debug", mais toujours pas celle que j'ai sélectionnée.
Dans tous les cas, le paramètre apparaît en police normale pour la configuration "Debug" alors qu'il apparaît en police en gras pour les autres configurations, laissant entendre qu'il s'agit de remplacements. De plus, si j'ouvre les fichiers de projet XML, je trouve que la configuration "Debug" n'a pas de réglage pour l'attribut "RuntimeLibrary" de l'élément "Tool" avec l'attribut "Name = VCCLCompilerTool". Toutes les autres configurations ont un paramètre explicite.
Il semble que pendant que je travaillais dessus, j'ai oublié de supprimer la mauvaise configuration de CMake que j'essaie de remplacer.
Plus bas dans le script de construction, j'avais laissé ce petit enculé:
set(CMAKE_CXX_FLAGS_DEBUG
"/DWIN32 /D_WINDOWS /EHsc /WX /wd4355 /wd4251 /wd4250 /wd4996"
CACHE STRING "Debug compiler flags" FORCE
)
Fondamentalement, je remplaçais les résultats de la macro by configure_msvc_runtime()
avec des indicateurs de build qui ne définissaient pas le runtime MSVC.
J'ai pris votre code et l'ai généralisé pour qu'il fonctionne pour chaque configuration existante et pas seulement pour Debug/Release/RelWithDebInfo/MinSizeRel.
Je l'ai aussi fait fonctionner avec gcc aussi - vérifiez-le ici
Cette fonctionnalité sera améliorée avec la sortie de cmake-3.15.
Il devrait s'agir de définir CMAKE_MSVC_RUNTIME_LIBRARY
, par exemple (à partir de la documentation) pour définir "une bibliothèque d'exécution à liens statiques multithread avec ou sans informations de débogage en fonction de la configuration":
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")