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++程序时,尝试使用交叉编译的方式已经耗费了很多时间,还需要的努力也是个未知数。
教训:如果仅编译简单的程序,同时目标平台也支持编译,不要使用交叉编译。