2012-03-16 60 views
14

伊夫加入從升壓一些功能:: ASIO,這已沉澱的一些編譯器「警告」:平臺檢測在CMake的

請限定_WIN32_WINNT或適當_WIN32_WINDOWS。

該問題已得到處理here。我想要做的是當我在windows上構建並進行適當的定義或命令行參數時,CMake會進行檢測。

+0

發現了cmake的維基一點金礦:http://www.cmake.org/Wiki/CMake_Useful_Variables .. – 2NinerRomeo 2012-03-16 18:13:35

回答

19

這是一個簡單的解決方案。

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

不錯,簡單!如果(WIN32)如果爲真,即使您在Windows下針對Windows以外的其他內容進行交叉編譯,也可以使用+1 – 2013-08-21 20:38:39

+0

。即使您正在爲其他內容構建,您也會以-D_WIN32_WINNT結束。 – robUx4 2016-10-19 07:42:31

+2

對於Windows 10問題,例如Windows Kits \ 8.1 \ Include \ shared \ sdkddkver.h(255):錯誤C2177:常量太大,請在下面檢查@squareskittles的答案。 – Tarc 2016-11-25 22:30:50

17

中的CMakeLists.txt文件裏面你可以這樣做:

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

這是中途那裏,我關注着如何定義預處理程序定義和編譯器命令行標誌。我認爲鏈接器的語法就像這個'set(CMAKE_EXE_LINK_FLAGS「$ {CMAKE_EXE_LINK_FLAGS} -linkerflag」)',所以我期望它對於編譯器標誌是相似的。我還沒有學會添加預處理器的定義。 – 2NinerRomeo 2012-03-16 18:09:40

4

由於karlphilip指出的那樣,你可以使用if(WIN32)爲平臺的檢測。

你必須傳遞預處理多種可能性定義了應用程序:

  • 使用該得到由CMake的的configure_file預處理一個配置頭。這種方法的優點是,所有#define實際上都是代碼的一部分,而不是構建環境的一部分。缺點是它需要CMake的(自動)預處理步驟
  • 使用add_definitions。這將爲項目中的所有源文件添加預處理器標誌,因此它更加快速和骯髒。
  • 使用COMPILE_DEFINITIONS屬性。這允許在每個文件(甚至每個配置)基礎上定義細粒度控制: set_property(SOURCE ${YOUR_SOURCE_FILES} APPEND PROPERTY COMPILE_DEFINITIONS YOUR_FLAG1 YOUR_FLAG2)

    在現代CMake的版本(2.8.12及更高版本),你也可以使用更方便target_compile_definitions命令此。

我通常更喜歡後者,但這主要是個人品味的問題。

-3

這是我想出了:

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

對於處理了boost :: ASIO「警告」無論是預處理器定義或命令行標誌幹得不錯。

+0

這是錯誤的。您將兩次添加'_WIN32_WINNT'定義,並且您還在XP上修復Windows版本。 – cmannett85 2015-11-13 08:26:13

+0

謝謝。自從我發佈這個問題以來,我很高興其他人提出了優秀的解決方案。既然你已經引起了我的注意,我已經改變了我接受的答案。 – 2NinerRomeo 2015-11-17 19:30:27

1

KneLLs的改進版本回答:

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

KneLLs版本中那樣在我的情況下,沒有工作,因爲CMAKE_SYSTEM_VERSION6.3.9600這導致${ver}=0x060306090000

這個版本將適用於Windows 10失敗,但後來。必須檢查第一個數字是否大於9並將其轉換爲正確的十六進制值。

8

這是KneLL的答案的擴展版本,也檢查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

我可以確認這適用於Windows 10(正在使用@ KneLL's,但是當我更新我的系統時它已經損壞)。 – Tarc 2016-11-25 22:28:58