【问题标题】:Option to force either 32-bit or 64-bit build with cmake使用 cmake 强制构建 32 位或 64 位的选项
【发布时间】:2015-09-17 21:06:57
【问题描述】:

我想提供一种方法,始终将我的目标构建为 32 位或始终构建为 64 位可执行文件,使用 cmake 独立于主机系统(为 gcc 添加“-m32”或“-m64”标志,目前还不确定其他编译器该怎么做)。

我可以想到三种方法来做到这一点,我应该使用哪一种?

  1. 一个选项 (-DUSE32bit=true)
  2. 工具链 (-DCMAKE_TOOLCHAIN_FILE=64bit.toolchain)
  3. 构建类型 (-DCMAKE_BUILD_TYPE=release32)

在我的情况下,强制 32 位构建将是默认设置,并且应该易于使用。强制 64 位构建在某些情况下也很有用,应该不会太难。使用主机系统的位宽对于我的情况很少有意义,我不想支持它。

我在这里找到了一个相关的问题 (The proper way of forcing a 32-bit compile using CMake),但答案主要是讨论如何做到这一点,而不是如何最好地使其可配置。

【问题讨论】:

标签: c++ cmake 32bit-64bit


【解决方案1】:

感谢您的所有投入,但在我这边,我最终选择了带有 cmake 的 -m32 hack

# cmake windows 32 bits mode bug: 32 bits link mode must be explicit (otherwise cmake will always guess a 64 bits target)
#  1- run "vcbarsall.bat x86" to setup Visual Studio build profile
#  2- "set cflags=-m32" and "set cxxflags=-m32"
#  3- let the cmake plugin "automatically" guess the target platform

【讨论】:

    【解决方案2】:

    我个人想在 Visual Studio / cmake 配置的同一解决方案中切换到 32/64 位项目。我发现这可以使用

    set_target_properties(${project} PROPERTIES LINK_FLAGS ${PROJ_LINK_FLAGS})
    

    其中PROJ_LINK_FLAGS 可以是/MACHINE:X86/MACHINE:X64,具体取决于编译情况。

    【讨论】:

      【解决方案3】:

      对于 Visual Studio 和每个 https://cmake.org/cmake/help/latest/variable/CMAKE_GENERATOR_PLATFORM.html

      对于带有 VS 2005 及更高版本的 Visual Studio 生成器,这指定了目标体系结构。

      cmake . -DCMAKE_GENERATOR_PLATFORM=x64
      

      【讨论】:

      • @TylerGubala 还没有,不幸的是。 cmake 的文档缺乏解释,但似乎这方面的文档实际上在 -A 标志中:cmake.org/cmake/help/v3.2/manual/cmake.1.html,上面写着VS>8。另请参阅stackoverflow.com/a/28047073/3196753,其中谈到将-m32 标志添加到gcc。请注意,-m32 可能不适用于所有编译器。在 Linux/Unix 上构建 32 位的首选和推荐方法似乎是工具链文件,类似于为交叉编译准备构建环境的方式,也可以在上面的链接中找到。
      • @MitchLindgren CMake 工具链很特别,因为它们是在其他任何事情之前处理的。出于这个原因,SET(CMAKE_GENERATOR_PLATFORM x64)(或者在你的情况下,x86)应该在工具链文件中发挥作用。 -D 参数只是在命令行上设置此值,而不是在 MyToolChain.cmakeCMakeLists.txt 等中设置。免责声明,我尚未在工具链文件中测试此特定变量,但文档确实提到了工具链具体技术。
      • 谢谢,成功了。我必须使用将缓存条目设置为内部(set(CMAKE_GENERATOR_PLATFORM Win32 CACHE INTERNAL "Force 32-bit compilation")),否则如果没有在命令行上指定,它会被覆盖,但一旦我这样做了,它就起作用了。
      • @tresf 是的,我确实需要CACHE 部分,即使我先删除CMakeCache.txt。否则,当我尝试构建时,我会收到此错误:error MSB8013: This project doesn't contain the Configuration and Platform combination of Debug|x64
      • @MitchLindgren 嗯……很有趣。这表明以下情况之一: 1. cmake 存在一个错误,因为文档将其作为一种可行的方法提供。 -- 或者 -- 2. 删除CMakeCache.txt 不足以重置此变量的值,因此最终需要从新构建中设置该值(清除所有缓存的构建文件)。无论如何,您的测试和回复将帮助其他人。感谢您的测试!
      【解决方案4】:

      TL;DR

      使用工具链

      深入

      1. 一个选项 (-DUSE32bit=true)

      我猜这是不可扩展的。那么如果你想构建 N 个项目呢?您必须添加 N 个选项。

      1. 构建类型 (-DCMAKE_BUILD_TYPE=release32)

      这可能会很好。但在我看来,你混合了不相关的东西。此外,我确定您必须通过设置一些 *_ROOT CMake 变量来适应 find_package 行为。使用 CMAKE_BUILD_TYPE 是不可能的(至少,再次以可扩展的方式)。

      1. 工具链 (-DCMAKE_TOOLCHAIN_FILE=64bit.toolchain)

      最好的变种。如果您想构建两个项目 - 只需使用相同的工具链:

      cmake -Hproj-1 -B_builds/proj-1 -DCMAKE_TOOLCHAIN_FILE=/.../64bit.toolchain
      cmake -Hproj-2 -B_builds/proj-2 -DCMAKE_TOOLCHAIN_FILE=/.../64bit.toolchain
      

      如果您想使用 64 位架构构建您的第 3 方 ExternalProject_Add - 只需将工具链传递给 CMAKE_ARGS:

      ExternalProject_Add(
          ...
          CMAKE_ARGS ... -DCMAKE_TOOLCHAIN_FILE=/.../64bit.toolchain
          ...
      )
      

      想要适应 find_package - 只需将任何 CMake 变量添加到工具链文件即可。

      【讨论】:

      • 谢谢。我只有一个项目,没有自己构建的第三方库。我宁愿让调用更简单一些,即,当不带参数调用时,cmake 应该生成 32 位版本。我可以默认使用 32 位工具链还是这种风格不好?
      • @Flogo 您使用-D 调用的所有内容都放入缓存中。您可以利用缓存变量在再次设置时不会被覆盖的事实(CMake 本身对其某些系统变量使用此行为)。所以如果你把例如set(CMAKE_TOOLCHAIN_FILE ... CACHE INTERNAL "") 在您的 project() 命令之前,它将是默认值。
      • @Flogo 但是选择正确的默认工具链可能很困难。您必须使其依赖于使用的CMAKE_GENERATOR
      • @ruslo 我特别想避免默认行为,因为 64 位构建仅在极少数特殊情况下对我的应用程序有意义。我现在倾向于另一种方法:我不会在 cmake 中强制执行任何操作,但会检查 CMAKE_SIZEOF_VOID_P 是否为 4。如果不是,我将检查默认为 false 的选项是否设置为 true。如果该选项也没有设置,我将停止解释情况。这样,每个人都可以选择自己的设置,但必须明确确认 64 位版本。你怎么看?
      猜你喜欢
      • 1970-01-01
      • 2013-11-14
      • 2011-05-01
      • 2011-09-28
      • 2021-12-01
      • 2010-12-01
      • 1970-01-01
      • 2013-09-21
      • 2011-06-26
      相关资源
      最近更新 更多