我添加了一些boost::asio
的功能,这导致了一些编译器的“警告”:
请适当定义_WIN32_WINNT或_WIN32_WINDOWS。
这个问题在这里得到了解决。我希望CMake能够检测我是否在Windows上构建,并进行相应的定义或命令行参数设置。
我添加了一些boost::asio
的功能,这导致了一些编译器的“警告”:
请适当定义_WIN32_WINNT或_WIN32_WINDOWS。
这个问题在这里得到了解决。我希望CMake能够检测我是否在Windows上构建,并进行相应的定义或命令行参数设置。
在 CMakeLists.txt 文件中,你可以这样做:
IF (WIN32)
# set stuff for windows
ELSE()
# set stuff for other systems
ENDIF()
set(CMAKE_EXE_LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} -linkerflag")
,所以我预计编译器标志也会类似。我还没有学会添加预处理器定义。 - 2NinerRomeo这里有一个简单的解决方案。
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})
Windows Kits\8.1\Include\shared\sdkddkver.h(255): error C2177: constant too big
,请查看下方 @squareskittles 给出的回答。 - Tarc这是 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()
# 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()
endmacro()
get_WIN32_WINNT(ver)
add_definitions(-D_WIN32_WINNT=${ver})
endif()
CMAKE_HOST_WIN32
是设置的变量。
当编译为Windows目标平台时,WIN32
是设置的变量。CMAKE_HOST_WIN32
是正确的标志。在许多情况下,WIN32
和CMAKE_HOST_WIN32
将是等效的,但并非所有情况都是如此。WIN32
,但在CMake执行过程中的某个时候会被隐式取消(我相信是在project
调用内部)。上一次我检查时,在执行toolchain.cmake时设置了WIN32
,但后来没有设置。因此,在这些情况下,该标志可能是危险的,因为其状态在执行过程中会发生变化。你不应该在工具链文件中使用WIN32
!CMAKE_HOST_SYSTEM_NAME
和CMAKE_HOST_SYSTEM_VERSION
变量。MESSAGE("CMAKE_HOST_SYSTEM_NAME ${CMAKE_HOST_SYSTEM_NAME}")
MESSAGE("CMAKE_HOST_SYSTEM_VERSION ${CMAKE_HOST_SYSTEM_VERSION}")
在CMake 3.19.2版本上,我得到了以下输出:
CMAKE_HOST_SYSTEM_NAME Windows
CMAKE_HOST_SYSTEM_VERSION 10.0.19044
还有一个叫做CMAKE_HOST_SYSTEM
的变量,在工具链文件中该变量给了我一个空值,在project
调用之后它会显示"Windows-10.0.19044"
if(WIN32)
进行平台检测。#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
命令来实现这一点。
我通常更喜欢后者,但这主要是个人口味的问题。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_VERSION
是6.3.9600
,导致${ver}=0x060306090000
但这个版本在Windows 10和以后的版本中会失败。必须检查第一个数字是否大于9,并将其转换为正确的十六进制值。
可能是支持Win10的最简洁版本,需要CMake 3.13或更高版本。
macro(get_win_hex outvar)
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)" ${outvar} ${CMAKE_SYSTEM_VERSION})
math(EXPR ${outvar} "(${CMAKE_MATCH_1} << 8) + ${CMAKE_MATCH_2}" OUTPUT_FORMAT HEXADECIMAL)
endmacro()
if(WIN32)
get_win_hex(winver)
add_compile_definitions(_WIN32_WINNT=${winver})
endif()
这是我想出来的:
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的“警告”,可以使用预处理器定义或命令行标志来完成任务。