2012-04-11 146 views
31

我遵循CMake FAQ條目"How can I build my MSVC application with a static runtime?"中的說明來集中選擇一堆嵌套CMake項目的MSVC運行時(它們被拉入Git子模塊並添加到主項目中CMake的find_package()指令)。在CMake中設置MSVC運行時

所以,我寫這個的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之前的任何add_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解決方案:

,我得到了以下成果:現在

-- 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++,代碼生成」項目屬性,我看到「運行時庫「設置與shell中打印的選項不一致。在「Release」,「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項目文件,則發現「Debug」配置沒有爲「Tool」元素的「RuntimeLibrary」屬性設置「Name = VCCLCompilerTool」屬性。所有其他配置都有明確的設置。

+0

偉大的解決方案! – mattiash 2015-11-09 11:09:17

回答

10

似乎我一直在處理這個問題,但我忘了刪除我想要替換的錯誤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運行時生成的標誌覆蓋的結果。

對不起,麻煩!

+0

您真的用我的解決方案爲我保存了強制靜態運行時庫! – linello 2012-09-10 19:27:17

5

我把你的代碼推廣到每一個現有的配置,而不僅僅是Debug/Release/RelWithDebInfo/MinSizeRel。

我也使它與海灣合作委員會也 - 檢查出來here

+0

是否可以指定(或覆蓋是否已指定)靜態或動態CRT從命令行鏈接?只是爲了避免修改第三方庫構建腳本 – 2016-12-16 16:52:57

+0

@AndyT你可以創建一個代理CMakeLists.txt,其中'''add_subdirectory''ies是第三方庫 - 你可以在那裏設置運行時間 - 但是如果第三方庫設置它自己的運行時間,它應該有一個選項... ... – onqtam 2016-12-17 10:44:27