2012-04-11 17 views
31

Sto seguendo le istruzioni nella voce FAQ CMake "How can I build my MSVC application with a static runtime?" per centralizzare la selezione del runtime MSVC per un gruppo di progetti CMake nidificati (vengono inseriti come sottomoduli Git e aggiunti al progetto principale utilizzando La direttiva find_package() di CMake).Impostazione del runtime MSVC in CMake

Così, ho scritto questa 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() 

Io chiamo questa macro, all'inizio della mia radice CMakeLists.txt (prima è fatto alcunadd_library() o add_executable() chiamata) e aggiungere un po 'di stampe di debug :

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

Poi, corro CMake per generare una soluzione di Visual Studio in questo modo:

e ottengo le seguenti uscite:

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

Ora, il fatto è che quando inizio Visual Studio ed esaminare le proprietà del progetto sotto "C/C++, Generazione di codice", vedo che il " L'impostazione "Libreria di runtime" non è coerente con le opzioni stampate nella shell. Nelle configurazioni "Release", "MinSizeRel" e "RelWithDebInfo", ottengo i risultati attesi ("DLL/MD multi-thread", ma la configurazione "Debug" visualizza ancora "Multi-threaded/MT".

inoltre, quando forzo uso del runtime collegata in modo statico, ottengo risultati simili Se corro

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

ottengo le seguenti uscite:.

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

eppure tutte le configurazioni produrre il "Multi threaded/MT "valore per l'impostazione" Libreria di runtime ".

Qualcuno può dirmi cosa sto facendo male, o se questo è un bug in CMake (2.8.7) o qualcosa del genere?


Per quello che vale, se genero di Visual Studio 2010 file di progetto, ottengo un valore diverso per la configurazione "Debug", ma ancora non quello che ho selezionato. In tutti i casi, l'impostazione appare nel carattere normale per la configurazione "Debug" mentre appare in grassetto per le altre configurazioni, suggerendo che quelle sono sovrascritture. Inoltre, se apro i file di progetto XML, scopro che la configurazione "Debug" non ha alcuna impostazione per l'attributo "RuntimeLibrary" dell'elemento "Tool" con l'attributo "Name = VCCLCompilerTool". Tutte le altre configurazioni hanno un'impostazione esplicita.

+0

grande soluzione! – mattiash

risposta

10

Sembra che mentre stavo lavorando su questo, ho dimenticato di rimuovere la configurazione CMake male che sto cercando di sostituire.

Proseguendo lungo la script di build, avevo lasciato questo piccolo bastardo:

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

In sostanza, mi è stato sovrascrivendo i risultati di configure_msvc_runtime() dalla macro con le bandiere di build che non ha impostato il runtime MSVC.

Ci scusiamo per il disturbo!

+0

Mi hai davvero salvato con la tua soluzione per forzare le librerie di runtime statiche! – linello

5

Ho preso il codice e lo ho generalizzato per funzionare per ogni configurazione esistente e non solo per Debug/Release/RelWithDebInfo/MinSizeRel.

Inoltre ho fatto per lavorare con gcc troppo - Check it Out here

+0

è possibile specificare (o sovrascrivere se già specificato) il collegamento CRT statico o dinamico dalla riga di comando? Solo per evitare di modificare script di creazione di librerie di terze parti –

+0

@AndyT potresti creare un proxy CMakeLists.txt quale '' 'add_subdirectory'''ies la lib di terze parti - e puoi impostare il runtime lì - ma se i set di lib di terze parti il runtime su proprio allora dovrebbe avere un'opzione per quello ... – onqtam