前言 2023.7.13 有感记录 ——不耻下问,早日摆脱大白菜
谦虚使人进步,永远不耻下问,你就知道自己是多么渺小。牛逼的人往往虚怀若谷,肤浅的人总是心高气傲
1、CMakeLists.txt
文件中的idlc_generate
在ARM架构是不支持的
2、永远不要在X86
架构下想着运行ARM
架构的东西
比如基于ARM
架构cmake
编译的CycloneDDS
代码在进行ctest
的时候是行不通的,0% tests passed!
,需要上板子
3、交叉编译过程中,因为很多指令或文件是不能使用的,需要事先在x86
架构上生成之后,cp
到ARM
架构去使用。
1 创建build-arm编译目录并且cd进入
2 执行cmake 和 make 指令
Linux
终端输入:
cmake -DCMAKE_TOOLCHAIN_FILE=../arm.cmake -DCMAKE_INSTALL_PREFIX=../install_DDS_ARM -DENABLE_SSL=NO ..
指令解析:
1) -DCMAKE_TOOLCHAIN_FILE=../arm.cmake
该指令的作用是指向arm.cmake
文件的路径,在此处我的arm.cmake
文件放置在
/home/ubuntu/Documents/ARM_C_CycloneDDS/cyclonedds-master/arm.cmake
位置
建议将arm.cmake文件放置在一个固定的地方,自此之后我的arm.cmake文件将会放在统一的/home/ubuntu/Documents/install_ARM
下面
(此时我的AMR(交叉编译工具包)里面包含了两块内容,doc、include、lib、share
包都是ARM下的CUnit
安装,除此之外还有arm.cmake
文件)
2)-DCMAKE_INSTALL_PREFIX=../install_DDS_ARM
这句指令的作用是指定安装位置,我这里的安装位置指定的是/home/ubuntu/Documents/ARM_C_CycloneDDS/cyclonedds-master/install_DDS_ARM
,这一步是在执行make install
的时候安装在这里
3)-DENABLE_SSL=NO ..
这条指令目的是不启用SSL,故后面的参数是NO
这句必须要加上,否则cmake能过,但是make(cmake --build . 的时候过不了,如下图所示)
首先是:cmake -DCMAKE_TOOLCHAIN_FILE=../arm.cmake -DCMAKE_INSTALL_PREFIX=../install_DDS_ARM ..
虽然在这一步没有报错,但是后面make时会报错
由上图可知,编译到98%的时候就会出错:libssl.so:error……
清空编译目录,重新cmake
和make
,当然cmake
不会出错,此时make
也能到100%,安全通过!
3 cmake --build . --target install安装
Linux终端输入:cmake --build . --target install
4 debug版本构建和testing问题处理
在Linux终端输入:
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON ..
此时出现如下错误:
显示could not find Cunit
需要注意 :这个错误的提示是因为没有安装CUnit
,如果你在Linux(默认X86
架构)上安装了,这一步是可以过的
下面这是在Linux操作系统上默认的X86架构上面离线安装CUnit的步骤,请参考:
X86架构的Linux(Ubuntu版本)上离线安装CUnit来解决Could not find CUnit(missing:CUNIT_LIBRARY)问题
这个时候我们通过把解压包进行cmake、make
编译出库文件(.so文件),放在/usr/local/lib
下面,当在编译cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON ..
这一句时会自动会去检索这些库文件,当然也可以通过
-DCMAKE_PREFIX_PATH=……
去引入库文件,下面会有相应的例子
但是你在往下走编译(cmake --build .
)的时候就会报错
因为我们现在实在ARM架构上编译,所以CUnit必须要安装ARM架构上的。
下面这篇文章讲述了Cunit在ARM架构上的安装,也就是编译出来的库文件ARM下的,请戳~:
CUnit在ARM平台上的离线搭建(让CUnit编译安装成功之后的可执行文件.so变成ARM下的—ARM aarch64)(实用篇)
ARM架构上的CUnita编译安装完成之后会产生几个库文件,其实真正起作用的就是这些库文件,我们可以将所有关于交叉编译所需要的文件都放置在一个固定的文件包中,这里在/home/ubuntu/Documents/install_ARM
,install_ARM
是新建的放置交叉编译项的地方,我们将CUnit安装的位置选在这里,或者将CUnit安装后的四个文件包拷贝在这里,于是我们在这步编译的时候,执行如下命令:
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DCMAKE_PREFIX_PATH=//home/ubuntu/Documents/install_ARM ..
,需要将安装包引进来,如何便可构建通过,如下图所示:
由上图可知,会自动去查找指令-DCMAKE_PREFIX_PATH
指定的地方(并且只需要指定到放置安装文件的根目录install_ARM就可,会自动检索)
5 make(或者cmake – build .)编译
6 ctest单元测试
ARM架构的ctest单元测试在电脑上是行不通的,必须要在板子上才可以,所以此步略去
7 构建和运行往返实例(编译examples 下面的roundtrip)
7.1 cd进入./examples/roudtrip,创建build目录并且进入
mkdir build
创建文档的步骤下图中省略
7.2 build目录下进行编译
先来两个错误示例,首先是第一个安装路径的错误指定
cmake -DCMAKE_TOOLCHAIN_FILE=/home/ubuntu/Documents/ARM_C_CycloneDDS/cyclonedds-master/arm.cmake -DENABLE_SSL=NO -DCMAKE_PREFIX_PATH=/home/ubuntu/Documents/install_ARM/ ..
此语句中arm.cmake
文件的引入没问题,但是安装位置有问题,现在的写法是testing
的时候指定ARM
下的CUnit
位置,现在是编译roundtrip,所以指向的安装地址应该是CycloneDDS的安装位置(make install
位置),因此引起下图所示的问题
那么现在将安装路径指向正确
cmake -DCMAKE_TOOLCHAIN_FILE=/home/ubuntu/Documents/ARM_C_CycloneDDS/cyclonedds-master/arm.cmake -DENABLE_SSL=NO -DCMAKE_PREFIX_PATH=/home/ubuntu/Documents/ARM_C_CycloneDDS/cyclonedds-master/install_DDS_ARM ..
依然爆出如下的错误:
显示:Unknow CMake command “idlc_generate”
ARM架构下该指令是不能使用的,那么只有将CMakeLists.txt
文件中的idlc_generate
指令注释掉,然后将该指令干的事情,手动干了。
7.2.1 idlc_generate指令大白话含义总结
想要手动完成idlc_generate
指令的功能,就必须对该指令的功能非常熟悉,下面对该指令的功能进行熟悉。
在CMakeLists.txt
文件中,idlc_generate
命令的作用是生成IDL
(接口描述语言)文件的相关代码。具体来说,该指令用于将IDL文件转换为可用于不同编程语言的代码,以便在分布式系统中进行通信和对象交互。
在给定的例子中,idlc_generate(TARGET RoundTrip_lib FILES RoundTrip.idl)
指令表示生成名为RoundTrip_lib
的目标库,并使用RoundTrip.idl
文件作为输入。
这意味着该指令将根据RoundTrip.idl文件生成与IDL相关的代码,并将其添加到RoundTrip_lib目标库中。
所以总结来讲,该指令的功能可以分为三步:
1、idlc_generate首先会解析指定的RoundTrip.idl文件
2、根据解析的文件生成相应的代码
3、将生成的代码加入到库文件RoundTrip_lib中,使其成为其源文件和目标使用的一部分
最简单的理解方式就是:(极其重要!!!)
拿X86架构下的CycloneDDS(C版本)代码举例子,它在编译安装之后会在我们新建的build目录下生成可执行文件idlc,如下图所示
此可执行文件后面跟上RoundTrip.idl文件会生成源文件和头文件,如下图所示(X86-C-CycloneDDS),生成了RoundTrip.c和RoundTrip.h
恰好我们在编译roundtrip的时候需要这个头文件和源文件,而在X86架构下通过idlc_generate(TARGET RoundTrip_lib FILES RoundTrip.idl)
指令就可以产生
链接关系为:idlc_generate->RoundTrip.idl->RoundTrip.c和RoundTrip.h
现在ARM架构下idlc_generate(TARGET RoundTrip_lib FILES RoundTrip.idl)
指令不可用,所以RoundTrip.c和RoundTrip.h俩文件需要从X86上生成好,拿到ARM架构上(直接将源文件和头文件拷贝过去就行了)
7.2.2 修改roundtrip下的CMakeLists.txt文件配置
如下图所示,idlc_generate(TARGET RoundTrip_lib FILES RoundTrip.idl)
指令不能用,所以注释掉
这样的话不能自动产生RoundTrip.c和RoundTrip.h文件,所以我们需要将这俩文件加入到add_executable里面去
因为idlc_generate(TARGET RoundTrip_lib FILES RoundTrip.idl)
指令指令注销,所以RoundTrip_lib库不能再依赖,也没有必要再去依赖,因为文件已经手动传入了。所以将其从target_link_libraries中删除
7.2.3 将X86的RoundTrip.c和RoundTrip.h文件拷贝到ARM下的roundtrip下
将X86下面的RoundTrip.c
和RoundTrip.h
文件拷贝到ARM的examples/roundtrip/
下面
不要拷贝错了位置,因为RoundTrip.idl文件在此目录下,所以俩文件应该跟它放在一起
如下图所示:
查看ARM下Cyclonedds下的examples/roundtrip
发现文件确实被拷贝过来了
7.2.4 buil目录下执行camke指令生成MakeFile文件
至此,准备工作已经完毕,我们cd进入到build目录下去编译
命令行输入:
cmake -DCMAKE_PREFIX_PATH=/home/ubuntu/Documents/ARM_C_CycloneDDS/cyclonedds-master/install_DS_ARM -DCMAKE_TOOLCHAIN_FILE=/home/ubuntu/Documents/ARM_C_CycloneDDS/cyclonedds-master/arm.cmake -DENABLE_SSL=NO ..
指定arm.cmake
文件位置,DDS安装位置和SSL不启用
7.2.5 make编译产生可执行文件
命令行输入:make
file
命令查看执行文件类型是不死ARM下的
下图所示,可执行文件确实是属于ARM架构下的
完美撒花~