web-dev-qa-db-ja.com

CMakeでMSVCランタイムを設定する

CMake FAQエントリ "静的ランタイムでMSVCアプリケーションをビルドするにはどうすればよいですか?" の指示に従って、MSVCランタイムの選択を集中化します。ネストされたCMakeプロジェクトの束(これらはGitサブモジュールとして取り込まれ、CMakeのfind_package()ディレクティブを使用してマスタープロジェクトに追加されます)。

だから、私はこの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()
_

ルートの先頭でこのマクロを呼び出します_CMakeLists.txt_(beforeanyadd_library()またはadd_executable()呼び出しが行われます)、デバッグ出力を少し追加します:

_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 "")
_

次に、CMakeを実行して、次のようなVisual Studioソリューションを生成します。

_cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=dynamic
_

そして、私は次の出力を取得します:

_-- 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
_

今、問題は、Visual Studioを起動して「C/C++、コード生成」の下のプロジェクトプロパティを調べると、「ランタイムライブラリ」設定がシェルに出力されたオプションと一致しないことがわかります。 [リリース]、[MinSizeRel]、[RelWithDebInfo]の構成では、期待どおりの結果が得られます(「マルチスレッドDLL/MD」ですが、「デバッグ」構成には「マルチ-スレッド/ MT ")。

また、静的にリンクされたランタイムの使用を強制すると、同様の結果が得られます。走ったら

_cmake -G "Visual Studio 9 2008" ..\.. -DMSVC_RUNTIME=static
_

次の出力が得られます。

_-- 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
_

さらに、すべての構成では、「ランタイムライブラリ」設定に対して「マルチスレッド/ MT」値が生成されます。

何が間違っていますか、またはこれがCMake(2.8.7)のバグか何かですか?


価値のあることですが、Visual Studio 2010プロジェクトファイルを生成すると、「デバッグ」構成の値が異なりますが、選択した値は変わりません。

すべての場合において、設定は「デバッグ」構成では通常のフォントで表示されますが、他の構成では太字で表示され、それらがオーバーライドであることを示唆します。さらに、XMLプロジェクトファイルを開くと、「デバッグ」構成には、「名前= VCCLCompilerTool」属性を持つ「ツール」要素の「ランタイムライブラリ」属性の設定がありません。他のすべての構成には明示的な設定があります。

36
André Caron

私がこれに取り組んでいた間、私は交換しようとしている悪いCMake設定を削除するのを忘れていたようです。

ビルドスクリプトのさらに下に、この小さなバグを残しました。

_set(CMAKE_CXX_FLAGS_DEBUG
  "/DWIN32 /D_WINDOWS /EHsc /WX /wd4355 /wd4251 /wd4250 /wd4996"
  CACHE STRING "Debug compiler flags" FORCE
)
_

基本的に、configure_msvc_runtime()マクロによる結果を、MSVCランタイムを設定しなかったビルドフラグでオーバーライドしていました。

12
André Caron

コードを取得し、Debug/Release/RelWithDebInfo/MinSizeRelだけでなく、既存のすべての構成で機能するようにコードを一般化しました。

また、私はgccでも動作するようにしました-それを確認してください ここ

6
onqtam

この機能はcmake-3.15のリリースで改善されます。

CMAKE_MSVC_RUNTIME_LIBRARYを設定することで、たとえば(ドキュメントから)「構成に応じてデバッグ情報の有無にかかわらず、マルチスレッドの静的リンクランタイムライブラリ」を設定する必要があります。

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
1
Harry Mallon