使用CMake强制32位编译的正确方法
The proper way of forcing a 32-bit compile using CMake
对不起,有许多类似的问题,但我确实发现谷歌搜索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- 有没有一种方法可以在编译时获得作用域类名
- 访问条件类成员的方法不仅在被调用时才编译
- 模板方法访问正向声明的类仅在没有此指针的情况下无法编译
- C++11:模板方法的模板函数调用无法编译?
- 在编译时评估函数开销的通用方法
- VS2017 版本 15.8.3 成功编译内联方法,而不返回所需值
- 在C++中执行 N 阶乘编译时间的 3 种不同/相同方法
- unordered_set .find 方法无法编译的 C++ "expression must have class type"错误
- 如何检查在编译时是否调用了模板化方法?
- C++基于1而不是0的访问数组,方法是在编译时移位
- std::value templated 方法的函数使用 clang 和 g++ 进行编译,但不使用 msvc 进行编译
- CMake + Qt,moc 编译失败,无法实现 QMetaObject 方法(编译器找不到基本 ui 对象的标头?
- 返回实例变量的c++方法可以访问变量中的数据,但不能更改它,但在编译时不会生成错误
- 尝试编译SFINAE检查中使用的方法体时发生编译错误
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 模棱两可的方法编译误差
- 使用内联方法编译简单的标头
- 为什么 boost::enable_if 不会导致重复的重载方法编译错误
- c++向量排序方法编译失败,返回预期表达式
- 模板方法编译错误,从内部类返回实例