2012-03-16 13 views
14

Ive ha aggiunto alcune funzionalità da boost :: asio, che ha precipitato alcuni compilatore "avvertimenti":rilevamento della piattaforma in cmake

Si prega di definire _WIN32_WINNT o _WIN32_WINDOWS in modo appropriato.

Questo problema è stato risolto con here. Quello che mi piacerebbe fare è che CMake rileva quando sto costruendo su Windows e faccio le definizioni appropriate o gli argomenti della riga di comando.

+0

trovato un po 'miniera d'oro sul wiki cmake: http://www.cmake.org/Wiki/CMake_Useful_Variables .. – 2NinerRomeo

risposta

19

Ecco una soluzione semplice.

macro(get_WIN32_WINNT version) 
    if (WIN32 AND CMAKE_SYSTEM_VERSION) 
     set(ver ${CMAKE_SYSTEM_VERSION}) 
     string(REPLACE "." "" ver ${ver}) 
     string(REGEX REPLACE "([0-9])" "0\\1" ver ${ver}) 

     set(${version} "0x${ver}") 
    endif() 
endmacro() 

get_WIN32_WINNT(ver) 
add_definitions(-D_WIN32_WINNT=${ver}) 
+0

bello e semplice! +1 –

+0

if (WIN32) se true anche se si esegue una compilazione incrociata in Windows per qualcosa di diverso da Windows. Finirai con -D_WIN32_WINNT anche se stai costruendo qualcos'altro. – robUx4

+2

Per problemi di Windows 10, come 'Kit di Windows \ 8.1 \ Include \ shared \ sdkddkver.h (255): errore C2177: costante troppo grande', controllare la risposta di @squareskittles sotto. – Tarc

17

All'interno del CMakeLists.txt file che si può fare:

IF (WIN32) 
    # set stuff for windows 
ELSE() 
    # set stuff for other systems 
ENDIF() 
+0

Questo è parzialmente lì, sto rovistando per come definire le definizioni del preprocessore e la linea di comando del compilatore bandiere. Penso che la sintassi del linker sia come questo 'set (CMAKE_EXE_LINK_FLAGS" $ {CMAKE_EXE_LINK_FLAGS} -linkerflag ")' quindi mi aspetto che sia simile per i flag del compilatore. Inoltre, non ho imparato ad aggiungere definizioni del preprocessore. – 2NinerRomeo

4

Come karlphilip sottolineato, è possibile utilizzare per la rilevazione if(WIN32) piattaforma.

Avrete una serie di possibilità per il passaggio preprocessore definisce l'applicazione:

  • utilizzare un'intestazione di configurazione che viene pre-elaborata da CMake di configure_file. Questo approccio ha il vantaggio che tutti gli #define s sono effettivamente parte del codice e non dell'ambiente di compilazione. Lo svantaggio è che richiede una fase di pre-elaborazione (automatica) da parte di CMake
  • Utilizzare add_definitions. Questo aggiungerà il flag del preprocessore per tutti i file sorgente nel progetto, quindi è più un approccio rapido e sporco.
  • Utilizzare la proprietà COMPILE_DEFINITIONS. Questo permette di controllo a grana fine nel corso degli definisce per ogni singolo file (e persino per-config) Base: set_property(SOURCE ${YOUR_SOURCE_FILES} APPEND PROPERTY COMPILE_DEFINITIONS YOUR_FLAG1 YOUR_FLAG2)

    Nelle moderne versioni CMake (2.8.12 e superiori) è anche possibile utilizzare il più conveniente target_compile_definitions comando per questo .

Di solito preferisco quest'ultimo, ma è principalmente una questione di gusto personale.

-3

Questo è quello che ho messo a punto:

if(${WIN32}) 
#this method adds the necessary compiler flag 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WIN32_WINNT=0x0501") 
#this adds a preprocessor definition to the project 
add_definitions(-D_WIN32_WINNT=0x0501) 
endif() 

Per trattare con il boost :: asio "warning" o la definizione del preprocessore o il flag della riga di comando ottiene il lavoro fatto.

+0

Questo è sbagliato. Stai aggiungendo '_WIN32_WINNT' a due volte, e stai anche correggendo la versione di Windows su XP. – cmannett85

+0

Grazie. Sono così contento che altri hanno escogitato soluzioni superiori da quando ho postato questa domanda. Dato che hai attirato la mia attenzione su di esso, ho cambiato la mia risposta accettata. – 2NinerRomeo

1

Una versione migliorata del KneLLs risposta:

macro(get_WIN32_WINNT version) 
    if (WIN32 AND CMAKE_SYSTEM_VERSION) 
     set(ver ${CMAKE_SYSTEM_VERSION}) 
     string(REGEX REPLACE "^([0-9])[.]([0-9]).*" "0\\10\\2" ver ${ver}) 
     set(${version} "0x${ver}") 
    endif() 
endmacro() 

get_WIN32_WINNT(ver) 
add_definitions(-D_WIN32_WINNT=${ver}) 

versione KneLLs non lavorava nel mio caso, perché CMAKE_SYSTEM_VERSION era 6.3.9600 che ha provocato ${ver}=0x060306090000

Questa versione non riuscirà per Windows 10 e dopo, però. Si deve controllare se il primo numero è più grande di 9 e convertirlo nel valore esadecimale corretto.

8

Ecco una versione estesa della risposta di KneLL, che controlla anche per Windows 10.

if (WIN32) 
    macro(get_WIN32_WINNT version) 
     if (CMAKE_SYSTEM_VERSION) 
      set(ver ${CMAKE_SYSTEM_VERSION}) 
      string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver}) 
      string(REGEX MATCH "^([0-9]+)" verMajor ${ver}) 
      # Check for Windows 10, b/c we'll need to convert to hex 'A'. 
      if ("${verMajor}" MATCHES "10") 
       set(verMajor "A") 
       string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver}) 
      endif ("${verMajor}" MATCHES "10") 
      # Remove all remaining '.' characters. 
      string(REPLACE "." "" ver ${ver}) 
      # Prepend each digit with a zero. 
      string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver}) 
      set(${version} "0x${ver}") 
     endif(CMAKE_SYSTEM_VERSION) 
    endmacro(get_WIN32_WINNT) 

    get_WIN32_WINNT(ver) 
    add_definitions(-D_WIN32_WINNT=${ver}) 
endif(WIN32) 
+1

Posso confermare questo funziona per Windows 10 (stava usando @ KneLL ma si è rotto quando ho aggiornato il mio sistema). – Tarc

Problemi correlati