如何使用cmake检测64位MSVC?

时间:2016-08-31 20:13:03

标签: visual-studio cmake

我有一个使用cmake的项目,一个目标设置为仅使用MSVC构建:

 if (MSVC)
     add_library(test SHARED source.cpp) 
 endif()

现在另一个问题是此目标仅适用于MSVC 32位。那么如何检测到生成器是MSVC64并跳过此目标呢?

7 个答案:

答案 0 :(得分:26)

检查是否为64位架构生成的常用方法是测试CMAKE_SIZEOF_VOID_P

if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    # 64 bits
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
    # 32 bits
endif()

答案 1 :(得分:18)

有几种方法 - 也被CMake本身使用 - 将检查"而不是64Bit":

if(NOT "${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
    ...
endif()

if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
    ...
endif()

if(NOT CMAKE_CL_64)
   ...
endif()

<强>参考

答案 2 :(得分:2)

在最新版本的CMake / Visual Studio中,位数是通过CMAKE_GENERATOR_PLATFORM选择的,可以在命令行上使用-A选项进行指定:

cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_BUILD_TYPE=Release ..

因此,基于此功能,您可以从CMakeLists.txt中查询值:

if(NOT ("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "Win64"))
    ...
ENDIF()

答案 3 :(得分:1)

这是我最初开始编写的脚本,用于检测目标是x86(32位x86)还是amd64(64位x86)。然后,我找到了Jake Petroules的脚本,并继续吸收了从Internet上搜出的多个源中的点点滴滴,通常使用C编译器来检测目标体系结构。有许多不同的C编译器,它们给出的答案不一致。该脚本旨在处理所有这些问题(理论上),并赋予CMake更高的检测保真度。它通过使用预处理器传达回CMake脚本来工作。将其放入您的CMake模块文件夹中,并至少include()放入您的项目中一次(它具有包含保护,因此可以包含多个包含物)。然后,您在CMAKE_CPU_ARCHITECTURES此脚本所在的文件夹以及所有子文件夹中将有一个变量included()。此变量是一个列表(因为XCode项目文件可以一次针对多个体系结构)。您应该检查一下所需列表中是否有该列表。

if("amd64" IN_LIST CMAKE_CPU_ARCHITECTURES) # I am targeting 64-bit x86.
...
if("x86" IN_LIST CMAKE_CPU_ARCHITECTURES) # I am targeting 32-bit x86.
...

它将是x86(32位)或amd64(64位)。这只是目标架构(即CPU芯片)。要检测操作系统,生成器,编译器等是另一回事,但是您可以使用嵌套在各种其他if语句中的体系结构检查,例如if(WIN32)(令人困惑的意思是只针对某种Windows,不一定是32位)或if(MSVC)(如果您对编译器感兴趣)等等,依此类推,独立地。

(我有一个用于检查特定操作系统的类似脚本,它能够检测特定的事物并返回诸如watchOSiOSmacOS或{{1 }},依此类推,但这是另一回事了。

detect_cpu_architectures.cmake:

Windows CE

答案 4 :(得分:0)

可选的解决方案是基于使用的编译器名称构建条件。

if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")

答案 5 :(得分:0)

我自己也遇到了类似的问题,并发现了CMAKE_VS_PLATFORM_NAME,它是根据生成器计算的,我认为值得一提。

我使用-GVisual Studio 15 2017-GVisual Studio 15 2017 Win64-GVisual Studio 15 2017 -Ax64在cmake 3.16.1(根据文档从3.1.3开始可用)中进行了尝试,并将其设置为:分别为Win32x64x64。因此,对于这种情况,我认为应针对Win32进行检查,例如

if ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
    ...
endif ()

答案 6 :(得分:-1)

此示例在cmake 3.17.0上对我有效:

if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "x64")
  ....
endif()

if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "Win32")
  ...
endif()