使用CMake强制32位编译的正确方法

The proper way of forcing a 32-bit compile using CMake

本文关键字:方法 编译 CMake 强制 32位 使用      更新时间:2023-10-16

对不起,有许多类似的问题,但我确实发现谷歌搜索CMake查询总是产生类似但不相同的场景,冲突的CMake命令等等!

我需要强制我的项目构建32位二进制文件,因为我必须链接到一个仅作为32位可用的库。我是根据如下错误信息诊断的:

/usr/bin/ld: i386 architecture of input file `*external-32bit-lib*' is incompatible with i386:x86-64 output
根据我收集到的信息,我应该使用:
set (CMAKE_CXX_FLAGS "-m32")

这确实改变了事情-我现在得到几个错误,如:

/usr/bin/ld: i386 architecture of input file `*project-output-lib*' is incompatible with i386:x86-64 output

AND对于外部库也会得到相同的错误。我认为这是因为-m32使gcc生成32位二进制文件,但ld仍在尝试64位输出?进一步谷歌搜索这个问题没有给任何成功,所以如果有人能验证我是对的,并给出正确的方法,我将非常感激!

多谢!

如果您想使用cmake编译和链接32位,请使用此命令创建库和二进制文件:

创建库:

add_library(mylib SHARED my_source.c)
set_target_properties(mylib PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
创建可执行文件:

add_executable(mybin sources.c)
set_target_properties(mybin PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")

即使这看起来像是额外的工作,我认为在这种情况下使用工具链文件是一个正确的解决方案。比如:

# the name of the target operating system
set(CMAKE_SYSTEM_NAME Linux)
# which compilers to use for C and C++
set(CMAKE_C_COMPILER gcc)
set(CMAKE_C_FLAGS -m32)
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_FLAGS -m32)
# here is the target environment located
set(CMAKE_FIND_ROOT_PATH   /usr/i486-linux-gnu )
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

用法很简单:

$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake /path/to/source

这里的重要部分是,现在可以指定一个根目录路径(CMAKE_FIND_ROOT_PATH),该路径应该用于搜索第三方库。事实上,你的编译器可能不够聪明,不知道在x86_64系统上去哪里搜索x86 Qt库。

有一个工具链文件允许一个人在一个不同的编译器的基础上指定一个不同的工具链文件,当在windows环境下以32位编译时,你应该能够调整这个选项。

现在这是额外的工作,因为从x86_64 Linux操作系统编译32位非常微不足道,但这个解决方案将适用于其他更奇特的设置。

有关工具链文件的更多信息,可以查看如下示例:

  • https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/cross_compiling/Mingw

CMAKE_CXX_FLAGS仅影响c++编译器。您可能还必须为C编译器设置标志:

set (CMAKE_C_FLAGS "-m32")

听起来好像您也没有将m32传递给LFLAGS,或者有旧的obj文件在隐藏。一定要先打扫干净。

这个问题类似于你的:cmake, gcc, cuda和-m32

使用以下来源的TRY_RUN命令

size.cpp:

#include <cstdlib>
int main( int argc, char** argv )
{
  size_t size = sizeof(void*);
  if ( size == 4 )
    return 0;
  return 1;
}

CMakeLists.txt:

TRY_RUN(RUN_RESULT_VAR COMPILE_RESULT_VAR ${your_temp_dir} size.cpp RUN_OUTPUT_VARIABLE IS_64_SYSTEM)
IF(IS_64_SYSTEM)
  MESSAGE(FATAL_ERROR "64 compiling not allowed!")
ENDIF(IS_64_SYSTEM)

我使用malat的方法制作了一个Toolchain文件。

我有一个工具链文件,可以在一些Linux操作系统上工作,也许它会给你灵感。它可以为您工作,或者您可能需要其他丑陋的hack来获得您依赖的其他cmake脚本或w/e:

https://github.com/visualboyadvance-m/visualboyadvance-m/blob/master/cmake/Toolchain-cross-m32.cmake