如何在CMake中仅为32位交叉编译器设置LD_PRELOAD调用编译链接器
我在WSL2中构建多个项目,其中一个项目使用旧版32位交叉编译器。源文件存储在挂载到WSL的Windows文件系统中,该文件系统的inode为64位,无法被32位编译器读取,报错:
cc1plus: error: /mydir/.../source.cpp: Value too large for defined data type
我按照《The 64 bit inode problem》教程构建了inode64.so,并在shell中手动验证:设置LD_PRELOAD后调用32位交叉编译器可正常工作:
export LD_PRELOAD=/mydir/.../inode64.so arm-fsl-linux-gnueabi-g++ source.cpp
但在项目构建脚本中全局设置LD_PRELOAD后执行CMake和make install时出现报错:
ERROR: ld.so: object '/mydir/.../inode64.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.
推测是32位的inode64.so不兼容64位CMake工具,因此想请教:如何在CMake中仅让32位编译器/链接器调用时设置LD_PRELOAD?
可以通过以下几种方式实现仅针对32位交叉编译器设置LD_PRELOAD:
方法1:为编译器命令添加前缀
直接在CMake中修改编译器命令,将环境变量前缀绑定到32位交叉编译器上,只有调用该编译器时才会加载inode64.so,不会影响64位的CMake进程或其他工具:
# 配置C++交叉编译器 set(CMAKE_CXX_COMPILER "env LD_PRELOAD=/mydir/.../inode64.so arm-fsl-linux-gnueabi-g++") # 若需使用C交叉编译器,同理配置 set(CMAKE_C_COMPILER "env LD_PRELOAD=/mydir/.../inode64.so arm-fsl-linux-gnueabi-gcc")
方法2:使用CMake编译器启动器(CMake ≥3.15)
通过自定义脚本包装编译器调用,灵活控制环境变量的加载:
- 创建名为
preload_wrapper.sh的脚本,内容如下:
#!/bin/bash export LD_PRELOAD=/mydir/.../inode64.so exec "$@"
- 给脚本添加执行权限:
chmod +x preload_wrapper.sh
- 在CMake中配置编译器启动器:
set(CMAKE_CXX_COMPILER_LAUNCHER "/path/to/preload_wrapper.sh") set(CMAKE_C_COMPILER_LAUNCHER "/path/to/preload_wrapper.sh")
方法3:针对单个目标设置编译环境
如果只有部分目标需要使用32位编译器,可单独为目标配置环境变量:
add_executable(my_arm_target source.cpp) set_target_properties(my_arm_target PROPERTIES COMPILE_FLAGS "env LD_PRELOAD=/mydir/.../inode64.so" LINK_FLAGS "env LD_PRELOAD=/mydir/.../inode64.so" )
内容的提问来源于stack exchange,提问作者W.S

