macOS使用Clang IDE, Clang编译器交叉编译Linux c++程序失败教训回顾

1 问题背景

macOS已安装CLion,同时Parallels Desktop已安装ubuntu 22.04虚拟机,需要在虚拟机运行c++程序,但是不想在虚拟机上占用空间再次安装CLion,所以在mac上使用交叉编译,程序在虚拟机上运行。

2 各种报错

2.1 c++头文件找不到

按照 CMake交叉编译官方文档,CMakeLists.txt如下:

scss 复制代码
cmake_minimum_required(VERSION 3.25)
project(01_CLionProjects)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(triple arm-linux-gnueabihf)

set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER_TARGET ${triple})

add_executable(01_CLionProjects main.cpp)

因为在CLion的Toolchains选项中已指定编译器的路径,所以该配置与CMake官方文档相比,删除CMAKE_C_COMPILER, CMAKE_CXX_COMPILER设置。

构建项目(构建工具:ninja)时,提示 c++头文件找不到:
fatal error: 'string' file not found

根据CLion External Libraries显示: 可以看出,c++头文件的目录的确是没有包含进来,但是正常编译的情况下,c++头文件又可以找到,为什么会出现这种情况呢 ?也没找到原因,如果读者知道原因的话,请麻烦传授一下。

解决方法:linux上编译libc++,将header,so等拷贝到mac,并修改CMakeLists.txt。

bash 复制代码
target_include_directories(
        01_CLionProjects
        PUBLIC
        /xxx/c++/v1
)

2.2 'features.h' file not found

解决c++头文件找不到的问题后,第二难,紧接登场:
c++/v1/__config:416:14: fatal error: 'features.h' file not found

c++ 头文件__config内容如下:

arduino 复制代码
// Need to detect which libc we're using if we're on Linux.
#  if defined(__linux__)
#    include <features.h>
#    if defined(__GLIBC_PREREQ)
#      define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
#    else
#      define _LIBCPP_GLIBC_PREREQ(a, b) 0
#    endif // defined(__GLIBC_PREREQ)
#  endif   // defined(__linux__)

根据注释可知晓,如果linux平台编译,则需要<features.h>, 该文件属于libc库,但是在mac上也没找到支持交叉编译的libc库。

解决方法:同libc++,linux上编译glibc,拷贝至mac,然后添加头文件目录

不幸的是,仍继续报错: fatal error: 'linux/limits.h' file not found

但是,这次就不用编译库了,只需将linux /usr/include的头文件拷贝过来,修改CMake文件即可。

2.3 error: 'neon_vector_type' attribute is not supported on targets missing 'neon' or 'mve'

完成上述步骤后,头文件找不到的问题可以解决,新的问题来了:
error: '__neon_vector_type__' attribute is not supported on targets missing 'neon' or 'mve'; specify an appropriate -march= or -mcpu=

提示比较明显,参考clang交叉编译指导,修改CMake文件:

ini 复制代码
target_compile_options(
        01_CLionProjects
        PUBLIC
        -march=aarch64
)

屋漏偏逢连夜雨,继续报错: error: unknown type name '__SVFloat32_t'

直到此处,放弃交叉编译。直接在linux虚拟上使用cmake,make等命令编译。

3 教训

其实想到需要在linux上编译glibc,libc++的时候,已经有放弃交叉编译的想法了,可以直接选择在linux上调用cmake,make等命令的方法去执行编译,但是又不甘心,所以继续尝试交叉编译,然而事与愿违,linux上编译libc++的过程也不是一帆风顺,直至看到error: unknown type name '__SVFloat32_t',经过考量,还是放弃交叉编译,因为到此为止,已经与初衷相违背,当初使用CLion是为了提升开发效率,节省直接使用cmake等工具的时间,但是在仅编译简单的,只使用标准库的c++程序时,尝试使用交叉编译的方式已经耗费了很多时间,还需要的努力也是个未知数。

教训:如果仅编译简单的程序,同时目标平台也支持编译,不要使用交叉编译。

4 参考

  1. CMake交叉编译官方指导
  2. Clang交叉编译官方指导
相关推荐
shdkfbbv5 分钟前
【无标题】
linux·运维·服务器
周洲08301 小时前
STM32片内Flash读写深度详解|掉电参数保存、底层原理
linux·前端·stm32
shimly1234561 小时前
比 find + grep 更好用的 nm + addr2line
linux
迷途之人不知返1 小时前
【进程控制】-3-进程等待
linux
_upupup1 小时前
包管理器和vim
linux·服务器
一颗小树x2 小时前
NVIDIA 驱动故障排查实录:内核升级导致 nvidia-smi 失效
linux·服务器·nvidia驱动·启动失败·内核升级
_smart_boy__2 小时前
I.MX6U开发板Uboot无法ping Ubuntu问题解决方案(二)
linux·运维·ubuntu
DianSan_ERP2 小时前
多平台订单自动下载与回传的技术实现:从消息推送到状态闭环引言
java·linux·服务器·前端·网络·架构·自动化
Android系统攻城狮2 小时前
Linux Gstreamer深度解析之gst_audio_decoder_get_parse_state调用流程与实战(四十九)
linux·音视频·gstreamer音视频·gstreamer音视频进阶
~光~~2 小时前
【嵌入式Linux学习】GFP_NOIO / GFP_NOFS(Linux 内核 gfp 分配标志)
linux·运维·学习