Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CMake中的平台检测_C++_Cmake_Boost Asio - Fatal编程技术网

C++ CMake中的平台检测

C++ CMake中的平台检测,c++,cmake,boost-asio,C++,Cmake,Boost Asio,我从boost::asio中添加了一些功能,这引发了一些编译器“警告”: 请适当地定义_WIN32\u WINNT或_WIN32\u窗口 这个问题已经解决了。我想让CMake在我在Windows上构建时进行检测,并生成适当的定义或命令行参数。在CMakeLists.txt文件中,您可以执行以下操作: IF (WIN32) # set stuff for windows ELSE() # set stuff for other systems ENDIF() 正如karlphilip指出

我从
boost::asio
中添加了一些功能,这引发了一些编译器“警告”:

请适当地定义_WIN32\u WINNT或_WIN32\u窗口


这个问题已经解决了。我想让CMake在我在Windows上构建时进行检测,并生成适当的定义或命令行参数。

在CMakeLists.txt文件中,您可以执行以下操作:

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

正如karlphilip指出的,您可以使用
if(WIN32)
进行平台检测

将预处理器定义传递给应用程序有多种可能性:

  • 使用由CMake预处理的配置标头。这种方法的优点是,所有的
    #define
    实际上都是代码的一部分,而不是构建环境的一部分。缺点是它需要CMake(自动)预处理步骤
  • 使用。这将为项目中的所有源文件添加预处理器标志,因此这更像是一种快速而肮脏的方法
  • 使用属性。这允许在每个文件(甚至每个配置)的基础上对定义进行细粒度控制:
    set_属性(SOURCE${YOUR_SOURCE_FILES}APPEND属性
    编译\u定义您的\u标志1您的\u标志2)

    在现代CMake版本(2.8.12及更高版本)中,您也可以使用更方便的命令进行此操作


我通常更喜欢后者,但这主要是个人品味的问题。

这就是我想到的:

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“警告”,预处理器定义或命令行标志都可以完成任务

这里有一个简单的解决方案

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

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_版本
6.3.9600
,这导致
${ver}=0x060306090000


不过,对于Windows 10及更高版本,此版本将失败。必须检查第一个数字是否大于9,并将其转换为正确的十六进制值。

这里是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()

这是其中的一部分,我正在探索如何定义预处理器定义和编译器命令行标志。我认为链接器语法是这样的
set(CMAKE_EXE_LINK_FLAGS“${CMAKE_EXE_LINK_FLAGS}-linkerflag”)
,因此我希望编译器标志也会类似。我还没有学会添加预处理器定义。在cmake wiki上发现了一个小金矿:…2NinerRomeo:该页面已移动到这是错误的。您正在添加两次定义的
\u WIN32\u WINNT
,并且您还在XP上修复Windows版本。谢谢。自从我发布这个问题以来,我很高兴其他人提出了更好的解决方案。既然您引起了我的注意,我已经更改了我接受的答案。if(WIN32)if true,即使您在Windows下交叉编译的对象不是Windows。即使你是为其他东西而构建,你最终也会得到-D_WIN32_WINNT。对于Windows 10问题,例如
Windows Kits\8.1\Include\shared\sdkddkver.h(255):错误C2177:常量太大
,请检查下面@squareskittles的答案。我可以确认这对Windows 10有效(使用@KneLL's,但在我更新系统时它坏了)。如果CMAKE_SYSTEM_版本恰好比SDK版本更新(例如,CMAKE_SYSTEM_版本对应于Windows 10,但您只有随Visual Studio 2010安装的Windows SDK),这可能会导致将_WIN32_WINNT定义为SDK不显式支持的值。这本身可能不是问题,但如果您碰巧根据_WIN32_WINNT的值进行了进一步的检查,相应的功能可能在生成过程中不可用。请确认这是适用于Windows 10的正确方法。@fr4nk是,从今天起,CMake不提供任何现成的获取WINNT十六进制版本的方法,因此需要这样的解决方案来支持Windows 10和更旧的Windows版本(请参阅全部)。当然,如果您只需要支持Windows 10,它会简单得多:
-D_WIN32_WINNT=0x0A00