本文档涉及到的目标硬件为海思3516D,但是对其他Arm芯片也有一定的借鉴意义,只需要更换交叉编译链即可。因为Caffe的编译需要使用开启C++11,所以GCC版本需要大于等于4.8才可以正常进行编译

参考文档

  1. 移植caffe到hi3519

开发环境介绍

主机操作系统:Ubuntu14.04 64位

目标板硬件:海思3516D

交叉编译器:arm-hisiv400-linux,海思提供的定制GCC 4.8.3交叉编译工具

编译注意事项

为了使Caffe部署时的体积最小化,需要如下几个注意事项

  1. Caffe的ARM编译只涉及到最后的推理部署,所以建议关闭lmdb、leveldb、snappy和opencv的编译
  2. Caffe及其依赖库都编译成静态库的版本,编译静态库时都要添加-ffunction-sections -fdata-sections的编译选项
  3. 在测试工程链接Caffe及其依赖库的时候,添加链接选项-Wl,--gc-sections(用于扔掉没有用到的静态库函数)
  4. 裁剪最后生成的可执行文件,通过arm-hisiv400-linux-gnueabi-strip命令

设置交叉编译链

# 在/etc/bash.bashrc的最后增加如下指令
# HISI Hi3516D V400 cross compiler
export ARCH=arm
export PATH=/opt/arm-hisiv400-linux/bin/:$PATH
export CROSS_COMPILE=arm-hisiv400-linux-gnueabi-
export CC=/opt/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-gcc    
export CXX=/opt/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-g++    
export LD=/opt/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-ld
export AR=/opt/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-ar
export AS=/opt/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-as
export RANLIB=/opt/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-ranlib
# 修改完成之后需要重启命令行才能生效
# 你可以通过如下指令来确认交叉编译链是否已经设置好
echo $CC 
# 当显示/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-gcc时表示交叉编译链已经设置好
# 当需要更换为本机编译时屏蔽上面的指令即可

下载依赖库

依赖库 版本 下载地址
glog 0.3.5 https://github.com/google/glog
gflags 2.2.1 https://github.com/gflags/gflags
opencv 3.2.0 https://github.com/opencv/opencv
protobuf 3.2.0 https://github.com/google/protobuf
openblas 0.2.20 https://github.com/xianyi/OpenBLAS
hdf5 5.1.8.20 https://support.hdfgroup.org/downloads/index.html
boost 1.59.0 http://www.boost.org/

在这里提供了所有依赖库的源代码打包下载地址:https://pan.baidu.com/s/1bp2OgNl

编译Opencv

修改CMakeLists.txt

# 强制打开NEON开关
# OCV_OPTION(ENABLE_NEON "Enable NEON instructions" "${NEON}" IF CMAKE_COMPILER_IS_GNUCXX AND (ARM OR AARCH64 OR IOS) )
OCV_OPTION(ENABLE_NEON   "Enable NEON instructions"           ON )

修改cmake/OpenCVCompilerOptions.cmake

# 将ENABLE_NEON开启之后的gcc参数修改为海思3516D推荐的参数"-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=softfp"
if(ENABLE_NEON)
    add_extra_compiler_option("-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=softfp")

新建cmake Build目录

cd opencv-3.2.0
mkdir _install

使用cmake-gui进行配置

选择Specify options for cross-compiling,进入交叉编译链设置界面

# 设置交叉编译相关参数
# 本文使用的是海思3516D SDK 提供的 V400 工具链,存放位置为/opt/arm-hisiv400-linux/(更改为你正在使用的目录)
# 设置Operating System 为 arm-linux 
# 设置C编译器为 /opt/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-gcc
# 设置C++编译器为 /opt/arm-hisiv400-linux/bin/arm-hisiv400-linux-gnueabi-g++
# 设置System Root 为 /opt/arm-hisiv400-linux/target

点击Configure生成配置选项,并且打开Advancd选项

修改设置选项:

# 去掉勾选为FLASE 勾选为TRUE
BUILD_SHARED_LIBS                 # FLASE为编译静态库 TRUE为编译动态库
CMAKE_BUILD_TYPE                  # Release
CMAKE_CXX_FLAGS                   # -fPIC
CMAKE_C_FLAGS                     # -fPIC
CMAKE_EXE_LINKER_FLAGS            # -lrt -lpthread    
CMAKE_INSTALL_PREFIX              # 自定义安装目录
WITH_CUDA                         # FLASE 禁用CUDA
WITH_CUFFT                        # FLASE 禁用CUFFT
WITH_EIGEN                        # FLASE 禁用EIGEN
WITH_FFMPEG                       # FLASE 禁用FFMPEG
WITH_OPENCL                       # FLASE 禁用OPENCL
WITH_OPENCLAMDBLAS                # FLASE 禁用OPENCLAMDBLAS
WITH_OPENCLAMDFFT                 # FLASE 禁用OPENCLAMDFFT
WITH_OPENCL_SVM                   # FLASE 禁用OPENCL_SVM

# 可选配置(根据需要进行配置)
WITH_TIFF
WITH_1394
WITH_GSTREAMER
WITH_JASPER      
WITH_LAPACK
WITH_MATLAB
WITH_WEBP

修改第三库CMakeLists.txt

# 如果你在上述的Cmake GUI界面开启了PNG的编译并且没有强制开启ENABLE_NEON选项,即
EWITH_PNG                          # TRUE 开启PNG
编译Opencv时将会出现如下链接错误(可能是Opencv3.2版本专有的Bug):
libopencv_imgcodecs.so: undefined reference to `png_init_filter_functions_neon'
解决方法如下:
进入到3rdparty/libpng,在CMakeLists.txt最顶端增加:
set(ENABLE_NEON ON)

点击Generate生成Makefile

进入_install目录&编译

cd _install
make -j8 
make install

编译Glog

cd glog-0.3.5
./configure --host=arm-linux CFLAGS="-ffunction-sections -fdata-sections -O2 -fPIC" \
    CXXFLAGS="-ffunction-sections -fdata-sections -O2 -fPIC" \
    --prefix=/usr/local/HI3516D/v400/glog-0.3.5
make -j8
make install

编译gflags

新建cmake Build目录

cd gflags-2.2.1
mkdir _install

使用cmake-gui进行配置

参考编译opencv时的cmake交叉工具链配置

# 修改Cmake设置选项
CMAKE_INSTALL_PREFIX              # 自定义安装目录
CMAKE_C_FLAGS                     -fPIC
CMAKE_CXX_FLAGS                   -fPIC

点击Generate生成Makefile

编译&安装

cd _install
make -j8 
make install

编译Protobuf

安装软件

sudo apt-get install curl libtool

生成PC版本protoc可执行文件,供编译ARM版本库时使用

# 修改/etc/bash.bashrc 设置为CC/CXX/LD为普通gcc编译器
cd protobuf-3.2.0
./autoconf.sh
./configure --prefix=/usr/local/PC/protobuf-3.2.0

编译ARM版本

# 修改/etc/bash.bashrc 设置为CC/CXX/LD为交叉编译器
cd protobuf-3.2.0
./autoconf.sh
./configure --build=i686-pc-linux --host=arm-linux \
    --with-protoc=/usr/local/PC/protobuf-3.2.0/bin/protoc \
    --prefix=/usr/local/HI3516D/v400/protobuf-3.2.0 CFLAGS="-fPIC" CXXFLAGS="-fPIC -DNDEBUG"

编译&安装

make -j8 
make install

编译OpenBLAS

修改Makefile.arm

# 根据你的ARM处理器版本和操作系统修改对应的CCOMMON_OPT和FCOMMON_OPT
# 本文档针对的是HI3516D,属于armv7架构
ifeq ($(CORE), $(filter $(CORE),ARMV7 CORTEXA9 CORTEXA15))
ifeq ($(OSNAME), Android)
CCOMMON_OPT += -mfpu=neon  -march=armv7-a
FCOMMON_OPT += -mfpu=neon  -march=armv7-a
else
# CCOMMON_OPT += -mfpu=neon  -march=armv7-a
# FCOMMON_OPT += -mfpu=neon  -march=armv7-a
CCOMMON_OPT += -ffunction-sections -fdata-sections -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=softfp 
FCOMMON_OPT += -ffunction-sections -fdata-sections -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=softfp
endif
endif

编译

cd OpenBLAS-0.2.20
# 编译单独的静态库版本
make TARGET=ARMV7 HOSTCC=gcc CROSS=1 CROSS_SUFFIX=arm-hisiv400-linux-gnueabi- BINARY=32 NOFORTRAN=1 libs -j8
# 编译动态库版本
make TARGET=ARMV7 HOSTCC=gcc CROSS=1 CROSS_SUFFIX=arm-hisiv400-linux-gnueabi- BINARY=32 NOFORTRAN=1 libs shared

# 另附上ARMV8芯片的编译命令以供参考
make TARGET=ARMV8 HOSTCC=gcc CROSS=1 CROSS_SUFFIX=aarch64-linux-gnu- BINARY=64 NOFORTRAN=1 libs -j8
make TARGET=ARMV8 HOSTCC=gcc CROSS=1 CROSS_SUFFIX=aarch64-linux-gnu- BINARY=64 NOFORTRAN=1 libs shared -j8

安装

# PREFIX使用您自己的自定义安装目录
make PREFIX=/usr/local/HI3516D/v400/openBLAS-0.2.20 install

编译HDF5

生成H5detect和H5make_libsettings

生成H5Tinit.c和H5lib_settings.c

修改configure文件

# 屏蔽掉所有和交叉编译验证相关的步骤
# 搜索cannot run test program while cross compiling获得具体校验代码位置(共四处)
if test "$cross_compiling" = yes; then :
# { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
# $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
# as_fn_error $? "cannot run test program while cross compiling
# See \`config.log' for more details" "$LINENO" 5; }
else

# 执行配置
./configure --host=arm-linux --prefix=/usr/local/HI3516D/v400/hdf5-1.8.20 CFLAGS="-ffunction-sections -fdata-sections -O2" CXXFLAGS="-ffunction-sections -fdata-sections -O2"

修改Makefile

# 屏蔽掉和H5Tinit.c、H5lib_settings.c生成相关的Makefile代码
H5Tinit.c: H5detect$(EXEEXT)
# LD_LIBRARY_PATH="$$LD_LIBRARY_PATH`echo $(LDFLAGS) |              \
      sed -e 's/-L/:/g' -e 's/ //g'`"                               \
  $(RUNSERIAL) ./H5detect$(EXEEXT) > $@  ||                         \
      (test $$HDF5_Make_Ignore && echo "*** Error ignored") ||      \
      ($(RM) $@ ; exit 1)

H5lib_settings.c: H5make_libsettings$(EXEEXT) libhdf5.settings
# LD_LIBRARY_PATH="$$LD_LIBRARY_PATH`echo $(LDFLAGS) |              \
      sed -e 's/-L/:/g' -e 's/ //g'`"                               \
  $(RUNSERIAL) ./H5make_libsettings$(EXEEXT) > $@  ||               \
      (test $$HDF5_Make_Ignore && echo "*** Error ignored") ||      \
      ($(RM) $@ ; exit 1)

编译&安装

make 
make install

编译Boost

生成编译脚本

cd boost_1_59_0
./bootstrap.sh --prefix=/usr/local/HI3516D/v400/boost-1.59.0

修改编译脚本project-config.jam

if ! gcc in [ feature.values <toolset> ]
{
    using gcc : arm : arm-hisiv400-linux-gnueabi-gcc ; # 注意中间的多处空格
}

编译&生成

./bjam install toolset=gcc-arm --layout=togged --build-type=complete --prefix=/usr/local/HI3516D/v400/boost-1.59.0

编译Caffe

修改Makefile和Makefile.config

#

编译&生成

# 
make all 
# 
make all -j8
make install

results matching ""

    No results matching ""