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交叉编译官方指导
相关推荐
有趣的我36 分钟前
linux上实现ose
linux·c++
圣心36 分钟前
Ollama Linux 部署指南
linux·数据库·mysql
黄昏难掩秋色23151 小时前
SpringMVC的基本使用
linux·windows·microsoft
蛊明1 小时前
VMware安装CentOS 10
linux·运维·centos
m0_715646761 小时前
无名管道、有名管道、信号、信号处理
java·linux·网络·数据结构·算法·嵌入式·标准io
461K.2 小时前
linux 编辑器
java·linux·运维·服务器·ide·scala·intellij-idea
厦门德仔2 小时前
【Docker】如何在Linux、Windows、MacOS中安装Docker
linux·macos·docker
ckanhw2 小时前
ubuntu windows双系统踩坑
linux·运维·ubuntu
byte轻骑兵2 小时前
【嵌入式Linux应用开发基础】进程间通信(2):消息队列
linux·c语言·嵌入式软件
Koma_zhe4 小时前
【搭建SigNoz性能监控平台】在Ubuntu上快速搭建高效的SigNoz性能监控平台与远程使用技巧
linux·运维·ubuntu