cmake与交叉编译(x86 to arm)过程和问题全记录

一、背景

公司维护一批c++动态库,由于生产需要,每次更新都要在windows、linux_x86、kylin_arm等多个环境中编译一遍,操作比较麻烦,所以想通过交叉编译的方式在一台机器上边编译多个环境的动态库,减少工作量。考虑到工作难度以及本人水平,决定从官方发布的成品交叉编译工具链中选择合适的版本搭建一个交叉编译环境, 实现在linux_86平台编译linux_arm动态库。

搭建编译环境用ubuntu_x86虚拟机,动态库统一使用cmake构建编译,编译会用到一批第三方依赖库例如boost、opencv等等,既然我要生成能在kylin_arm上运行的动态库,那么这些编译过程中用到的三方库也必须是kylin_arm系统的。现在公司有一个完善的kylin_arm编译环境,所以为了节约成本,我就直接将环境中的三方库拷贝到ubuntu_x86虚拟机中,方便交叉编译的时候直接调用。

cmake中配置交叉编译工具链

, 这个比较简单,cmake可以制定gcc路径,那么我就用CROSS_COMPILE这个参数做一个区分,在编译的时候指定它为true(cmake source/fiename -DCROSS_COMPILE=true)那个cmake就会去交叉编译的路径下边查找gcc.

if(UNIX)
   if(CROSS_COMPILE)
     message(STATUS "CROSS_COMPILE:${CROSS_COMPILE}")
      SET(CMAKE_SYSTEM_NAME Linux)
      SET(CMAKE_SYSTEM_PROCESSOR arm)
      SET(TOOLCHAIN_DIR "$ENV{HOME}/x86ToArm/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu")
      set(CMAKE_C_COMPILER "${TOOLCHAIN_DIR}/bin/aarch64-linux-gnu-gcc")
      set(CMAKE_CXX_COMPILER "${TOOLCHAIN_DIR}/bin/aarch64-linux-gnu-g++")
      set(CMAKE_LINKER "${TOOLCHAIN_DIR}/bin/aarch64-linux-gnu-g++")
   elseif (EXISTS "$ENV{HOME}/local/bin/gcc")
      set(CMAKE_C_COMPILER "$ENV{HOME}/local/bin/gcc")
      set(CMAKE_CXX_COMPILER "$ENV{HOME}/local/bin/g++")
      set(CMAKE_LINKER "$ENV{HOME}/local/bin/g++")
   elseif (EXISTS "/usr/local/bin/gcc")
      set(CMAKE_C_COMPILER /usr/local/bin/gcc)
      set(CMAKE_CXX_COMPILER /usr/local/bin/g++)
      set(CMAKE_LINKER /usr/local/bin/g++)
   endif()
endif()

message(STATUS "CMAKE_C_COMPILER is : ${CMAKE_C_COMPILER}")
message(STATUS "CMAKE_CXX_COMPILER is : ${CMAKE_CXX_COMPILER}")

二、问题1 can’t find “/lib64/libharfbuzz.so”……

在编译的时候报错找不到一批这样的文件,于是我从现有的 kylin_arm里边拷贝过来放在交叉编译工具连里边。但是之后发现只有放在系统/lib64下边才能被找到,这显然还是有问题,我的交叉编译工具链我希望它是可以移植的。于是我考虑是不是我需要在cmake中设置交叉编译的

知识点:
(1)在交叉编译工具连中aarch64-linux-gnu/libc是系统根目录,libc/lib== lib, libc/usr/lib==/usr/lib
(2) 在cmake里边可以通过SET(CMAKE_SYSROOT "${TOOLCHAIN_DIR}/aarch64-linux-gnu/libc") 指定根路径, SET(CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}/lib64" "$ENV{HOME}/YEECOH_LIBS_Arm") 指定搜索路径

问题分析:cmake中设置了各种路径都不起作用,它还是顽强的去/lib64下边寻找,然后忽然发现报错的库都是opencv库间接使用的,那么可以想到/lib64的路径可能是由opencv库中的cmake写死了。检查发现果然在opencv-4.5.1/lib64/cmake/opencv4/OpenCVModules.cmake中opencv将其调用的一些库路径写死了,于是将其修改为"\$<LINK_ONLY:harfbuzz>"(这是opencv中统一的写法,也可将路径直接修改成交叉编译的路径。)

三、问题2 basic_ostringstream未定义的引用

在这里插入图片描述分析:
(1) 交叉编译中自带的glibc版本是libstdc++.so.6.0.24, 麒麟编译使用的版本是0.28.
(2) 使用命令:nm -D /home/x86ToArm/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/libstdc++.so | c++filt | grep basic_ostringstream 查看报错的那个basic_ostringstream发现0.28版本中有定义,而0.24中没有定义。那么基本可以确定是版本不对的问题。 【参考链接:https://blog.csdn.net/Three_dog/article/details/104701644】
在这里插入图片描述(3)检查发现/home/x86ToArm/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/lib64这个路径下边是交叉编译自带的libstdc++.so.6.0.24,交叉编译使用的应该是他, 从现有的kylin_arm环境中将0.28的版本拷贝过来替换掉交叉编译中的libstdc++.so.6.0.24(一套库),这个报错就没有了

四、问题3 libc.so 未定义的引用

在这里插入图片描述
知识点:
(1)libc.so: glibc, 是底层c库; listdc++.so: 底层c++库。
(2) listdc++.so可以直接通过替换动态库文件来升级版本;但是libc.so不能简单替换,由交叉编译工具的制作过程可知,gcc与glibc是强关联的。

分析:
我在编译动态库的过程中是从现有的麒麟arm环境中拷贝了所需的一些底层库, 该麒麟环境有两套gcc: gcc9.3 + libc0.28 + libstdc++ 0.28 、gcc7.3+libc0.24+libstdc++0.24。 其中有两个库是用libc0.28编译的。而我使用的交叉编译工具链是:gcc7.3+ glibc0.24+libstdc++0.24。由于libc不能直接拷贝替换,那就只能考虑使用更高版本的交叉编译工具链。从官网下载了一个比较合适的版本:gcc8.3+libc0.28+libstdc++0.25。将其中的stdc++动态可直接替换成0.28版本的,就可以了。最终生成的动态库可以在现有的麒麟arm环境中运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/472153.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浅谈大模型“幻觉”问题

大模型的幻觉大概来源于算法对于数据处理的混乱&#xff0c;它不像人类一样可以by the book&#xff0c;它没有一个权威的对照数据源。 什么是大模型幻觉 大模型的幻觉&#xff08;Hallucination&#xff09;是指当人工智能模型生成的内容与提供的源内容不符或没有意义的现象。…

Linux——程序地址空间

我们先来看这样一段代码&#xff1a; #include <stdio.h> #include <unistd.h> #include <stdlib.h>int g_val 0;int main() {pid_t id fork();if(id < 0){perror("fork");return 0;}else if(id 0){ //child,子进程肯定先跑完&#xff0c;也…

提升Java编程安全性-代码加密混淆工具的重要性和应用

在Java编程领域中&#xff0c;保护代码安全性和知识产权至关重要。本文旨在探讨代码加密混淆工具在提升代码安全性和保护知识产权方面的重要性。我们将介绍几款流行的Java代码加密混淆工具&#xff0c;如ProGuard、DexGuard、Jscrambler、DashO和ipaguard&#xff0c;并分析它们…

多线程(剩余部分)

Day29 多线程(剩余部分) 十二、线程的礼让 Thread.yield(); 理解&#xff1a;此方法为静态方法&#xff0c;此方法写在哪个线程中&#xff0c;哪个线程就礼让 注意&#xff1a;所谓的礼让是指当前线程退出CPU资源&#xff0c;并转到就绪状态&#xff0c;接着再抢 需求&#x…

浅谈一下对于DDD模式的理解3

浅谈一下对于DDD模式的理解&#xff0c;相互学习交流&#xff0c;不对之处欢迎大家指正。 在说到DDD(Domain-Driven Design)设计模式之前&#xff0c;先要说下我们在对系统进行架构设时需要遵循的几个原则&#xff1a; 单一职责&#xff08;SRP&#xff09; "单一职责原则…

直播预约丨《袋鼠云大数据实操指南》No.1:从理论到实践,离线开发全流程解析

近年来&#xff0c;新质生产力、数据要素及数据资产入表等新兴概念犹如一股强劲的浪潮&#xff0c;持续冲击并革新着企业数字化转型的观念视野&#xff0c;昭示着一个以数据为核心驱动力的新时代正稳步启幕。 面对这些引领经济转型的新兴概念&#xff0c;为了更好地服务于客户…

文献速递:基于SAM的医学图像分割---阶梯式微调方法,用于整合补充网络的自适应矩估计(SAM)

Title 题目 Ladder Fine-tuning approach for SAM integrating complementary network 阶梯式微调方法&#xff0c;用于整合补充网络的自适应矩估计&#xff08;SAM&#xff09; 01 文献速递介绍 医学图像分割在医疗保健中扮演着至关重要的角色。它旨在使用各种医学成像方式…

MS2574/2574T/2574S高速、四通道差动线路驱动器

品简述 MS2574/MS2574T/MS2574S 是一款高速、低功耗的四通道 差动线路驱动芯片&#xff0c;用于平衡或非平衡的数字数据传输。可 以满足 ANSI TIA/EIA-422-B 和 ITU &#xff08;原 CCITT &#xff09;建议 V.11 的要求。 三态输出可提供用于驱动双绞线或平行双线传输线路等…

公司购买阿里云服务器多少钱一年?199元2核4G5M配置

阿里云服务器ECS u1实例&#xff0c;2核4G&#xff0c;5M固定带宽&#xff0c;80G ESSD Entry盘优惠价格199元一年&#xff0c;性能很不错&#xff0c;CPU采用Intel Xeon Platinum可扩展处理器&#xff0c;购买限制条件为企业客户专享&#xff0c;实名认证信息是企业用户即可&a…

基于机器视觉的太阳能电池片异物遮挡检测含数据集

分享链接见文末 近年来&#xff0c;随着太阳能发电技术的快速发展&#xff0c;太阳能电池片的应用越来越广泛。然而&#xff0c;太阳能电池片在实际运行过程中常常会受到各种异物的遮挡&#xff0c;如树叶、灰尘等&#xff0c;导致发电效率下降甚至损坏设备。因此&#xff0c;…

python 基于 websocket 的简单将视频推流到网页

本来有一台设备是要搞成无线的形式的&#xff0c;设备的摄像头的数据可以在一台局域网连接的平板上查看&#xff0c;因为试着使用 RTMP 推流&#xff0c;感觉延时太大了&#xff0c;而 Webrtc 感觉有太麻烦了&#xff0c;所以一开始看到这篇文章使用 UDP 协议进行推流&#xff…

竞赛 - 基于机器视觉的图像拼接算法

前言 图像拼接在实际的应用场景很广&#xff0c;比如无人机航拍&#xff0c;遥感图像等等&#xff0c;图像拼接是进一步做图像理解基础步骤&#xff0c;拼接效果的好坏直接影响接下来的工作&#xff0c;所以一个好的图像拼接算法非常重要。 再举一个身边的例子吧&#xff0c;…

“比特币跌至8900美元”?逢低买入信号闪现!亚洲投资者需求正持续增长!

3月19日&#xff0c;美股三大指数集体收涨&#xff0c;美联储正在召开为期两天的货币政策会议&#xff0c;周三公布结果&#xff0c;市场普遍预计美联储将按兵不动。 然而&#xff0c;比特币近几日却面临显著的价格回调&#xff0c;昨早再次从6.7万美元水平快速下滑&#xff0c…

学习vue3第九节(新加指令 v-pre/v-once/v-memo/v-cloak )

1、v-pre 作用&#xff1a;防止编译器解析某个特定的元素及其内容&#xff0c;即v-pre 会跳过当前元素以及其子元素的vue语法解析&#xff0c;并将其保持原样输出&#xff1b; 用于&#xff1a;vue 中一些没有指令和插值表达式的节点的元素&#xff0c;使用 v-pre 可以提高 Vu…

【Linux】shell命令运行原理---认识Linux基本指令

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;Linux_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.shell命令以及运行原理 1.1 shell命令 1.2 Linux内核权限 1.3 图示Linux shell和bash的区别 2.认识Linux基本指令 2.1 指令的…

选马桶别再犯错,这7点要注意!福州中宅装饰,福州装修

在众多卫浴品牌中&#xff0c;各种型号尺寸和性能的马桶更是层出不穷&#xff0c;在选购的时候总是陷入难题&#xff0c;那么接下来就给大家讲讲马桶应该怎么选购&#xff1a; ①高效冲水系统&#xff1a;高效的冲水系统&#xff0c;不仅能确保每一次冲洗都干净彻底&#xff0c…

【RabbitMQ】【Docker】基于docker-compose构建rabbitmq容器

本文通过docker-compose构建一个单体的rabbtimq容器。 1&#xff0c;docker、docker-compose环境 首先需要有docker和docker-compose环境&#xff0c;docker安装[1]&#xff0c;docker-compose安装[2]。 通过下列命令确定docker、docker-compose是否安装成功。 [root192 ge…

春暖花开,一起来看看2024年品牌春分海报吧!

春分&#xff08;Vernal equinox&#xff09;已至&#xff0c;春花烂漫、燕子归来、百草回芽。 今天我们要分享的是2024年品牌发布的春分节气海报合集&#xff0c;快来随我们一起感受这昂扬、蓬勃的春意吧! &#xff08;1&#xff09;泸州老窖 &#xff08;2&#xff09;BD…

语义分割基础知识

1、什么是语义分割 目标检测&#xff1a; 检测出图像中目标位置和类别&#xff0c;使用锚框框出目标位置 实例分割&#xff1a; 将前景物体分割开来&#xff0c;并且每一个物体有不同的id&#xff08;颜色&#xff09; 语义分割&#xff1a; 和实例分割相似&#xff0c;但…

nginx介绍及搭建

架构模型 Nginx是由一个master管理进程、多个worker进程组成的多进程模型。master负责管理worker进程&#xff0c;worker进程负责处理网络事件&#xff0c;整个框架被设计为一种依赖事件驱动、异步、非阻塞的模式。 优势&#xff1a; 1、充分利用多核&#xff0c;增强并发处理…