Zynq UltraScale+ MPSoC交叉编译armadillo(包括openblas)

         最近在研究如何在Zynq UltraScale+ MPSoC 平台的ARM端运行信号处理相关算法,在x86_Linux端使用了armdillo库完成了算法,目标就是先移植armdillo到ARM端。网上相关资料很少,并且参照了一些博客。并没有成功复现,踩了很多的坑,最后自己仔细阅读官方README文件,研究之后成功移植,这里做一下记录

一.平台介绍和编译环境

        1.使用的Zynq UltraScale+ MPSoC

        核心板使用 XILINX Zynq UltraScale+ EV 芯片 ZU4EV 的解决方案,它采用 Processing System(PS)+Programmable Logic(PL)技术将四核ARM Cortex-A53 和FPGA 可编程逻辑集成在一颗芯片上。另外核心板上 PS 端带有 4 片共 4GB 高速 DDR4 SDRAM 芯片,1 片 8GB的 eMMC 存储芯片和 1 片 256Mb 的 QSPI FLASH 芯片; 核心板上 PL 端带有 1 片 1GB 的DDR4 SDRAM 芯片。使用petalinux2020.2版本在ARM核上构建了Linux镜像系统。

        2.交叉编译环境

        虚拟机:ubuntu18.04.2

        交叉编译工具链: aarch-xilinx-linux-gcc等

        pc工具:GNU Make 4.1    cmake 3.15.3

如何获取交叉编译工具链:

        参考正点原子的教程,使用petalinux构建根文件系统

petalinux-config -c rootfs
petalinux-build -c rootfs
petalinux-build --sdk

        获取sdk.sh后sudo sdk.sh来将工具链安装在目录/opt/petalinux/2020.2/下

        将环境配置environment-setup-aarch64-xilinx-linux放到~/.bashrc中,并source,此时可以取消petalinux的环境

        

之后的环境就是aarch64-xilinx-linux的工具链可以查看$CC $CXX验证

二.交叉编译armadillo的依赖库(lapack openblas)

        因为这两个库实际上是Fortran的库,如果要编译就需要Fortran的交叉编译工具,可是打开arrch64-xilinx-linux的工具没有编译Fortran的,所以这里参考了以下的内容,使用原始的Clapack编译,其中使用了f2c库将Fortran变为了C接口,以便后续支持

Ubuntu中交叉编译armdillo库 - 自学内容网

        但是根据上面的流程,做出来的库是有问题的,首先是编译blas的时候没有关掉f2c的命名Wrapper,导致导出的符号有带有f2c_前缀命名,后续编译出的armdillo库,有undefined reference报错,后面取消了之后,编译出程序运行时使用dgemm函数错误。

        无奈,随后更改方案,按照aramdillo文件中的README.md指引的说法,使用openblas库代替老版本的转换的blas库,以及加上clapack库,成功编译出可以运行程序的armadillo.so库

        1.通过Clapack编译出liblapack.a libf2c.a

        2.仅编译openblas的库

        3.openblas和lapack 编译出 armadillo.so

具体细节:

1.交叉编译Clapak(可参考上面给出的链接)

        路径如下:https://netlib.org/clapack/clapack-3.2.1-CMAKE.tgz

        然后解压,进入clapack-3.2.1-CMAKE路径,应该首先研读README.install

        这里给出我的,make.inc的配置

        但是编译f2c有一个坑,就是在/home/mlh/clapack-3.2.1-CMAKE/F2CLIBS/libf2c的Makefile中,规定了了生成arith.h的是运行一个临时的a.out生成,但是交叉编译出的a.out无法在ubuntu环境中运行

        所以应将这一段在Makefile中删除,手动用gcc实现这一段编译命令,生成arith.h

gcc $(CFLAGS) -DNO_FPINIT arithchk.c -lm ||\
	 gcc -DNO_LONG_LONG $(CFLAGS) -DNO_FPINIT arithchk.c -lm
	./a.out >arith.h
	rm -f a.out arithchk.o

之后再改Makefile中的ld,按流程编译出f2c,blas, lapack即可。如果有找不到链接的库的,应该再链接命令后面加上指定sysroot的命令--sysroot=/opt/petalinux/2020.2/sysroots/aarch64-xilinx-linux或者指定lib搜索路径-L/opt/petalinux/2020.2/sysroots/aarch64-xilinx-linux/usr/lib

        因为我们后续使用openblas,所以不用复制libblas.a到交叉编译lib路径下。

2.交叉编译openblas

        在Rrelease版本中选择一个稳定的版本编译Releases · OpenMathLib/OpenBLAS · GitHub

我这里选择的是0.3.29版本,下载源码

        同样进入之后先认真阅读,README.md

        可以看到有给出cross_compile的例子   

        这里我们也可以通过给出的congfiue来配置,先搞清楚我们使用的ARM的架构,CUP是ARM Cortex-A53 ,所以我们的目标平台TARGET = ARMV8

        然后我们只需要oepnblas,没有Fortran编译器区编译lapack,所以我们要加上限定条件NOFORTRAN=1

make BINARY=64 CC=arrch64-xilinx-linux-gcc NOFORTRAN=1 HOSTCC=gcc TARGET=ARMV8

        最后,将编译出的内容安装到指定的文件夹中,可以得到openblas的库文件libopenblas.a

make PREFIX=../openblas_install install

···我们应将编译出的库复制到,交叉编译的路径下/opt/petalinux/2020.2/sysroots/aarch64-xilinx-linux/usr/lib

三.交叉编译armadillo库

1.下载armdillo

Armadillo: C++ library for linear algebra & scientific computing - Download

我这里选择了armadillo-14.0.3版本下载

2.交叉编译

        根据阅读README.md来看,我们需要开启使用openblas库来编译,这里直接使用CMake编译,因为之前已经source好了环境,camke会自动配置工具链

        1)修改CMakeLists.txt
        2)直接cmake
cmake .
        3)修改tests1路径下的CMakeLists.txt

        添加target_link_libraries(smoke_test PRIVATE /opt/petalinux/2020.2/sysroots/aarch64-xilinx-linux/usr/lib/libpthread.so)
target_link_libraries(smoke_test PRIVATE /opt/petalinux/2020.2/sysroots/aarch64-xilinx-linux/usr/lib/libopenblas.a)
target_link_libraries(smoke_test PRIVATE /opt/petalinux/2020.2/sysroots/aarch64-xilinx-linux/usr/lib/liblapack.a)
target_link_libraries(smoke_test PRIVATE /opt/petalinux/2020.2/sysroots/aarch64-xilinx-linux/usr/lib/libf2c.a)       

        4)编译安装

make 
make PREFIX=../armadillo_instll install

就可以编译出armadillo.so库,已经在tests下的smoke_test,库文件和头文件被安装到了指定的目录下~/armadillo_instl,将所有的库文件传输到板子上,并复制到/usr/lib下,在板子上运行smoke_test即可成功。

 4 后续编译方法

        单文件可以,编写Makefile来生成自己的测试文件,需要注意添加库的搜索路径和和头文件的搜所路径。也可以直接把库和头文件都放在交叉编译的路径下,直接添加sysroot

        同时库的链接顺序应该是-lpthread -lopenblas -llapack -lf2c ,保证链接能够找到符号

LIB_FLAGS = -L/home/mlh/armadillo_insall/lib  -larmadillo -L/opt/petalinux/2020.2/sysroots/aarch64-xilinx-linux/usr/lib -lpthread -lopenblas -llapack -lf2c

CXX_FLAGS = -I/home/mlh/armadillo_insall/include/ -std=c++14 -Wshadow -Wall -pedantic -Og

OBJECTS =  music_test.o

%.o :  %.cpp
	$(CXX) $(CXX_FLAGS) -c  $<

music_test: $(OBJECTS)
	$(CXX)   -o music_test  $(OBJECTS) $(LIB_FLAGS)


all: music_test

.PHONY: clean


clean:
	rm -f music_test *.o

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值