cartographer的交叉编译总结

it2023-06-30  74

思考: 对交叉编译不熟悉,一些事后感觉很简单的问题事前烦恼了很久。源代码的编译大致可以分为三个类,用cmake的, 用make的, 用脚本的。用cmake的最好改,其次是用脚本的,一般文档写得全。用make的往往是很简陋的,没文档,相关资料也少。 总结: 一.cartographer的Gmock GTest Glog模块的交叉编译 首先下载Gmock GTest Glog的源码,Gmock和GTest在github上的一个仓库中 修改cmakelist中修改 cmakelist中的设置 #告知当前使用的是交叉编译方式,必须配置 SET(CMAKE_SYSTEM_NAME Linux) SET(TOOLCHAIN_DIR "/home/gzpeite/pettoolchain") #指定编译工具,一定要设置 #或交叉编译器使用绝对地址 SET(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabi-gcc) #指定C++交叉编译器 SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabi-g++) #不一定需要设置 #指定交叉编译环境安装目录... SET(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR}) #从来不在指定目录下查找工具程序 SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) #只在指定目录下查找库文件 SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) #只在指定目录下查找头文件 SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 二cartographer中的boost的iostream,首先在boost官网下载boost版本 我下的是boost_1.6的版本,不同的版本,流程不一样, [http://www.b<wbr>oost.org](http://www.boost.org) 编译过程 1.首先运行boost解压目录下的 **./bootstrap.sh** 2.修改生成的**project-config.jam**文件 修改: using gcc : arm : arm-none-linux-gnueabi-gcc ; 修改(这边不改也没事): option.set prefix :(交叉编译器所在位置); option.set exec-prefix :(交叉编译器所在位置)/bin ; option.set libdir :(交叉编译器所在位置)/lib ; option.set includedir :(交叉编译器所在位置)/include ; 如果编译boost时出现以下问题,按照如下流程可解决 看前面的 pkgconfig 。 就是他的东西。 pkgconfig 是一个命令程序,他通过一个通用的参数从 .pc 文件里面获取一些数据来帮助调用某个函数库的程序得到正确的编译参数。这是开发用的程序,如果你不需要开发编译程序。这部分都是 *-devel 包里面的数据。这些包卸载即可。 其实 pkg-config 就是个二传手而已。不过他提供了一个通用的参数获取方式,很多软件还是比较喜欢给他准备一个配置数据文件的。 网上给的建议 这是因为boost的iostream库依赖于zlib和bzip2,所以您应该首先安装zlib和bzip2,然后运行,这两个包佩特科技给的库里有,但是要正确的指定路径 tar --bzip2 -xf /path/to/boost_1_67_0.tar.bz2 ./bootstrap.sh --prefix = path / to / installation / prefix ./b2 ./b2安装 请参见页面中的【5.4如果发生构建错误】:[https]([https://www.<wbr>boost.org/do<wbr>c/libs/1_67_<wbr>0/more/getti<wbr>ng_started/u<wbr>nix-variants<wbr>.html](https://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html)) : //[www.boost.or<wbr>g/doc/libs/1<wbr>_67_0/more/g<wbr>etting_start<wbr>ed/unix-vari<wbr>ants.html](http://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html)[]([https://www.<wbr>boost.org/do<wbr>c/libs/1_67_<wbr>0/more/getti<wbr>ng_started/u<wbr>nix-variants<wbr>.html](https://www.boost.org/doc/libs/1_67_0/more/getting_started/unix-variants.html)) 请注意,当您运行./b2时,应该看到以下结果(没有这两个的boost的iostream,在cartographer中运行会报错): * zib:是(已缓存) * bzip2:是(已缓存) 通过,这样boost就能找到zlib,zlib好像又需要bzip2,通过下面这两个就将他们弄进boost_iostreams了,有zlib的iostreams是需要bzip2的 bzip2的的名字是bzlip2, 但是写路径要写bzip2,提示给我错误是bzlip2 这个有点坑,但是注意一点,找lib包的路径的名字和lib包的名字一定是相关的 ./b2 -j8 --with-iostreams -s BZIP2_LIBRARY_PATH="/home/gzpeite/pettoolchain/lib" -s BZIP2_INCLUDE="/home/gzpeite/pettoolchain/include" -s ZLIB_LIBRARY_PATH="/home/gzpeite/gittestarm/boost_1_71_0/zlib/save/usr/local/lib" -s ZLIB_INCLUDE="/home/gzpeite/gittestarm/boost_1_71_0/zlib/save/usr/local/include" 3.测试编译效果 三,cartographer中的ceres的交叉编译 在github上下载ceres的2018年的版本,因为新的版本用些新的gcc的特性,导致gcc4.9编译的时候有些东西不识别, ceres依赖suitesparse和tbb tbb暂时没编译成功,但是不影响运行 suitessparse依赖于lapack,lapack依赖于blas blas和lapack我们选择openblas, 它自带了blas和lapack,在github上找到openblas后git下来按照说明文档既可编译armv7下的程序,之后suitesparse和ceres中用到lapack和blas的时候,库的路径都选openblas.a就行 suitesparse的配置选项主要在suitesparse_configure文件夹下的suitesparse.mk中配置,我下载的suitesparse源码是4.0的,更改其中的cc和cxx的路径,具体还是参考虚拟机中的该文件吧, 如果找不到某个文件,可以试着在cxxflags中添加 -L./(path) -m -rt -rpath("path") 如果怎么写都找不到,那就将缺少的那个库编好后放到交叉编译工具文件夹下的所有lib中,也就三四个吧,保管就找的到了。 suitesparse就算编译成功了,其编出的库也可能是残缺的。我的经验是lapack blas libm.so librt.so 这4个库容易少,编译完最好往上拉一下。 四,在cartographer中的protobuf的交叉编译 在github上下载protobuf的3.6的版本,最新的3.10版本 一 、 protobuf 安装 下载链接 1\. 确认安装依赖库:automake ,autoconf ,libtool 2\. 下载 protobuf 安装文件,protobuf-cpp-3.6.0.tar.gz , 解压, 第一次编译(获得protoc,根据proto文件生成.c和.h文件。编译在arm上执行的程序也是用这个x86上的protoc) ./autogen.sh ./configure make make check(报错,一般不用管) sudo make install 然后进行第二次编译 先make clean ./configure --host=arm-linux CC=PATH/arm-none-linux-gnueabi-gcc CXX=PATH/arm-none-linux-gnueabi-g++ --disable-protoc --prefix=/usr/local/protobuf-c-arm 得到arm下的库 在make intall中指定安装路径 make install = DESTDIR 但是protoc要用第一次编译的,不要用第二次编译的。注意,不然在linux 编译protoc文件无法编译 五,cartographer下编译lua(注意,makefile文件有很多个,要选有下面这些选项的makefile) 在开发嵌入式项目时,由于嵌入式平台没有lua环境,只能自己移植。先到官网上下载最新的lua源码(点击打开链接)。 接下来按照下面步骤: 1、修改src/Makefile文件内容: 源码包中的原始的Makefile的部分需要更改的内容如下: # Your platform. See PLATS for possible values. PLAT= none CC= gcc -std=gnu99 CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS) LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) LIBS= -lm $(SYSLIBS) $(MYLIBS) AR= ar rcu RANLIB= ranlib RM= rm -f 更改后的内容如下: # Your platform. See PLATS for possible values. PLAT= linux CC=arm-oe-linux-gnueabi-gcc -std=gnu99 -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=$(SDKTARGETSYSROOT) CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS) LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) LIBS= -lm $(SYSLIBS) $(MYLIBS) AR= arm-oe-linux-gnueabi-ar rcu RANLIB= arm-oe-linux-gnueabi-ranlib RM= rm -f SYSCFLAGS= -fexpensive-optimizations -frename-registers -fomit-frame-pointer -ftree-vectorize -Wno-error=maybe-uninitialized -finline-functions -finline-limit=64 -include quectel-features-config.h -fstack-protector-strong -pie -fpie -Wa,--noexecstack SYSLDFLAGS= -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-z,relro,-z,now,-z,noexecstack 修改下面的内容; linux: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" 为: linux: $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl" 同时将luaconf.h文件的64行屏蔽。 2.修改顶层目录的Makefile文件 原始的文件部分内容如下: # Your platform. See PLATS for possible values. PLAT= none # Where to install. The installation starts in the src and doc directories, # so take care if INSTALL_TOP is not an absolute path. See the local target. # You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h. INSTALL_TOP= /usr/local 修改后的内容如下: # Your platform. See PLATS for possible values. PLAT= linux # Where to install. The installation starts in the src and doc directories, # so take care if INSTALL_TOP is not an absolute path. See the local target. # You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h. INSTALL_TOP= 自己想要安装的目录 保存,make,make install 上述只能产生lua的静态库。如果要产生动态库so,则按照下面步骤来: 1、在顶层的Makefile中的 TO_LIB= liblua.a 修改为 TO_LIB= liblua.a liblua.so 2、在/src/Makefile中的如下两行之间: ALL_A= $(LUA_A) # Targets start here. 添加如下选项 LUA_SO=liblua.so ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO) $(LUA_SO): $(CORE_O) $(LIB_O) $(CC) -o $@ -shared -fPIC $? -ldl -lm 六,最后编译cartographer时注意事项 1,将根目录下的cmakelsit中test相关和main相关全部注释掉,这样就用不到gmock和gtest了,也少了一些错,编译起来速度也快些。 2,在FindXXX.cmake中通过set写绝对路径,具体参考虚拟机中的 3,如果少了什么库,但是你也编了,就通过target_linked_libraris来强制指定,写绝对路径,具体参考虚拟机中的。一般需要添加的都是suitesparse中的相关库,因为系统的FindCeres.cmake可能帮你去找了这些库 但是你自己写的FindCeres.cmake可能就没写这些,但是没关系,通过target_linked_liraries将suitesparse编译后产生的库都链接上,运行时,ceres就能找到了 七 一些有用的技巧 1 objdump -s --section=.comment xxx 可以看文件的编译器和含有什么库 2makefile中 修改cc和cxx的路径一般就是 CC= ..../arm-gcc CXX= ..../arm-g++ 添加动态库一般 -l(例如math库就是-lm pthread库就是-pthread) 通过-L./ 和rpath=("")来强制动态库的路径 写在CXXFLAGS CFLAGS 有的库要用到特殊的编辑器比如fortron啥的,路径就改为交叉编译工具中的arm-fortron路径 LIBS 用绝对路径来指定相应库 用warning 来打印消息 3在cmake中 用message来打印消息 通过cmakecache来查看你编译的这个库在编译时候产生了哪些变量,一般是路径相关的变量 4 undefined reference的错误一般就是找不到实现,找不到实现有两种情况,一是找不到库,二是找到的库里没有实现相因的函数。 库里没有相应函数的实现的原因有 库是残缺的,譬如编译的suitesparse库就会出现这种情况,选的blas不对,boost库编译没有配置zlib等。 库的版本不对应,譬如r16提供的gcc才4.9 比较落后,很多实现没有,所以用的ceres protobuf boost不能太新了,选2018及之前的。 5 unrecognaiz file 一般就是编译项目用的编译器  和 其依赖的库被编译时用的编译器 不一致产生的
最新回复(0)