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交叉编译官方指导
相关推荐
yyy00020035 分钟前
压缩和归档 文件传输
linux·运维·服务器
STCNXPARM42 分钟前
深度剖析Linux内核无线子系统架构
linux·运维·系统架构·wifi·无线子系统
烟雨书信2 小时前
LINUX中Docker Swarm的介绍和使用
java·linux·docker
代码的余温2 小时前
Linux内核调优实战指南
linux·服务器·数据库
m0_694845573 小时前
教你使用服务器如何搭建数据库
linux·运维·服务器·数据库·云计算
空灵之海3 小时前
Ubuntu Server 22.04.5系统安装教程
linux·运维·ubuntu
gamers3 小时前
rock linux 9 安装mysql 5.7.44
linux·mysql·adb
二进制_博客4 小时前
给CentOS的虚拟机扩容
linux·运维·centos
千钰v4 小时前
Tcpdump: The Basics Tcpdump 基础
linux·运维·网络·tcpdump·tryhackme
kk5794 小时前
【Ubuntu】sudo apt update出现E :仓库***没有Release文件
linux·运维·ubuntu