web-dev-qa-db-fra.com

Définition du runtime MSVC dans CMake

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.

36
André Caron

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.

12
André Caron

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

6
onqtam

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>")
1
Harry Mallon