导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

    交叉编译NumCpp到ARM上的方法(以全志V853为例)

    V Series
    1
    1
    1027
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • livpo
      livpo LV 6 最后由 编辑

      前段时间,在电脑上安装了Ubuntu/Windows系统双系统,现在拿Ubuntu系统试试水。

      NumCpp是类似Numpy的C++版本,可以方便的进行一些矩阵的操作,现在我们来把它交叉编译到ARM上去。

      1. 获取源码

      要交叉编译NumCpp,首先要获取依赖库boost源代码以及NumCpp的源代码。

      在这里我使用的是boost1.68,可以从下面这个网址下载。
      https://www.boost.org/

      Boost C++ Libraries
      https://www.boost.org/
      

      NumCpp可以从GitHub上clone下来
      https://github.com/dpilger26/NumCpp

      GitHub - dpilger26/NumCpp: C++ implementation of the Python Numpy library
      C++ implementation of the Python Numpy library. Contribute to dpilger26/NumCpp development by creating an account on GitHub.
      https://github.com/dpilger26/NumCpp
      

      2. 交叉编译boost

      将下载好的压缩包解压。

      cd boost_1_68_0
      ./bootstrap.sh --with-libraries=all --with-toolset=gcc
      

      其中,--with-libraries可以选择自己想要安装的库。

      执行完这一步之后,打开新生成的project-config.jam,修改下面这几行中的gcc部分。一定要注意空格!(每一个空格缺一不可),其中的arm-openwrt-linux-gcc的路径可以换成你的交叉编译器的路径

      if ! gcc in [ feature.values <toolset> ]
      {
          using gcc : arm : /home/xinzhe/toolchains/rootfsbuilt/arm/toolchain-sunxi-musl-gcc-830/toolchain/bin/arm-openwrt-linux-gcc ; 
      }
      

      之后执行

      ./b2
      

      检查输出的log中的编译器是否已经是交叉编译器,然后再执行

      ./b2 install --prefix=/home/xinzhe/Documents/boost_arm
      

      其中--prefix后面是你想要的boost库安装路径。

      安装完成后,检查安装的boost库是否为ARM版本。

      3.交叉编译NumCpp

      Clone完成NumCpp之后,进入NumCpp文件夹。

      由于我之前编译过x86-64版本的NumCpp,因此在编译ARM版本的时候,需要修改CMakeLists.txt,让cmake找到ARM版本的boost库。

      在CMakeLists.txt中寻找Boost有关代码的上方加入

      set(CMAKE_FIND_ROOT_PATH /home/xinzhe/Documents/boost_arm)
      
      set(CMAKE_FIND_ROOT_PATH /home/xinzhe/Documents/boost_arm)
       
       
       
      if(NUMCPP_NO_USE_BOOST)
          target_compile_definitions(${ALL_INTERFACE_TARGET} INTERFACE -DNUMCPP_NO_USE_BOOST)
      else()
          find_package(Boost 1.68.0 REQUIRED 
              COMPONENTS 
              date_time
          )
          target_link_libraries(${ALL_INTERFACE_TARGET} INTERFACE 
              Boost::boost
              $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:Boost::date_time>
          )
      endif()
      

      同时,在NumCpp文件夹里,创建一个Compile.cmake文件,来指定交叉编译器。内容如下:

      set(CMAKE_SYSTEM_NAME Linux)
      set(TOOLCHAIN_PATH /home/xinzhe/toolchains/rootfsbuilt/arm/toolchain-sunxi-musl-gcc-830/toolchain/arm-openwrt-linux-muslgnueabi)
      set(CMAKE_C_COMPILER /home/xinzhe/toolchains/rootfsbuilt/arm/toolchain-sunxi-musl-gcc-830/toolchain/bin/arm-openwrt-linux-gcc)
      set(CMAKE_CXX_COMPILER /home/xinzhe/toolchains/rootfsbuilt/arm/toolchain-sunxi-musl-gcc-830/toolchain/bin/arm-openwrt-linux-g++)
      

      其中的TOOLCHAIN_PATH、CMAKE_C_COMPILER、CMAKE_CXX_COMPILER替换成自己的交叉编译工具。

      然后在NumCpp文件夹下执行下面的操作

      mkdir build
      cd build
      cmake .. -DCMAKE_TOOLCHAIN_FILE=../Compile.cmake
      

      然后检查输出的log中,C编译工具是否为交叉编译工具,以及找到的boost库是否为我们刚刚创建的ARM版本的。

      检查完毕后,修改/NumCpp/build目录下的cmake_install.cmake,修改其中的CMAKE_INSTALL_PREFIX为自己想要安装的目录。

      # Install script for directory: /home/xinzhe/Documents/NumCpp
       
      # Set the install prefix
      if(NOT DEFINED CMAKE_INSTALL_PREFIX)
        set(CMAKE_INSTALL_PREFIX "/home/xinzhe/Documents/boost_arm")
      endif()
      string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
      

      然后执行:

      cmake --build . --target install
      

      我们就在boost_arm下得到了ARM版本的boost和ARM版本的NumCpp的编译结果文件

      4. 编译自己的代码

      创建NumCpp_arm文件夹,放入自己的main.cpp,并创建Compile.cmake(同上),CMakeLists.txt。

      其中CMakeLists.txt代码如下:

      cmake_minimum_required(VERSION 3.20)
       
      project("HelloWorld" CXX)
       
      add_executable(${PROJECT_NAME} main.cpp)
      set(CMAKE_FIND_ROOT_PATH /home/xinzhe/Documents/boost_arm)
      set(CMAKE_CXX_STANDARD 17)
      set(CMAKE_CXX_FLAGS "-g  -std=c++17 -lstdc++fs")
      find_package(NumCpp 2.10.1 REQUIRED)
      target_link_libraries(${PROJECT_NAME}
          NumCpp::NumCpp
          stdc++fs
      )
      

      其中的CMAKE_CXX_FLAGS的设置,以及stdc++fs添加到target_link_libraries里,是为了防止一下的报错。

      xinzhe@xinzhe-G3-3590:~/Documents/NumCpp/examples/NumCpp_arm/build$ make
      Consolidate compiler generated dependencies of target HelloWorld
      [ 50%] Linking CXX executable HelloWorld
      CMakeFiles/HelloWorld.dir/main.cpp.o: In function `std::filesystem::exists(std::filesystem::__cxx11::path const&)':
      main.cpp:(.text._ZNSt10filesystem6existsERKNS_7__cxx114pathE[_ZNSt10filesystem6existsERKNS_7__cxx114pathE]+0x1c): undefined reference to `std::filesystem::status(std::filesystem::__cxx11::path const&)'
      CMakeFiles/HelloWorld.dir/main.cpp.o: In function `std::filesystem::__cxx11::path::path<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::filesystem::__cxx11::path>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::filesystem::__cxx11::path::format)':
      main.cpp:(.text._ZNSt10filesystem7__cxx114pathC2INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES1_EERKT_NS1_6formatE[_ZNSt10filesystem7__cxx114pathC5INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES1_EERKT_NS1_6formatE]+0x60): undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()'
      collect2: error: ld returned 1 exit status
      make[2]: *** [CMakeFiles/HelloWorld.dir/build.make:98: HelloWorld] Error 1
      make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/HelloWorld.dir/all] Error 2
      make: *** [Makefile:91: all] Error 2
      

      然后,我们执行一下操作

      mkdir build
      cd build
      cmake .. -DCMAKE_TOOLCHAIN_FILE=../Compile.cmake
      

      检查输出的log,交叉编译工具对不对,boost与NumCpp是否为ARM版本。

      最后执行

      make
      

      下面的是我的编译结果,可以看到编译成功

      xinzhe@xinzhe-G3-3590:~/Documents/NumCpp/examples/NumCpp_arm/build$ make
      [ 50%] Building CXX object CMakeFiles/HelloWorld.dir/main.cpp.o
      [100%] Linking CXX executable HelloWorld
      [100%] Built target HelloWorld
      

      检查一下生成的可执行文件是够为ARM版本。

      xinzhe@xinzhe-G3-3590:~/Documents/NumCpp/examples/NumCpp_arm/build$ file HelloWorld
      HelloWorld: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-armhf.so.1, with debug_info, not stripped
      

      5.移植到V853上

      将HelloWorld文件和boost_arm整个文件夹push到板子上

      xinzhe@xinzhe-G3-3590:~/Documents/NumCpp/examples/NumCpp_arm/build$ adb push HelloWorld /root
      HelloWorld: 1 file pushed. 3.6 MB/s (2607428 bytes in 0.684s)
      

      然后到HelloWorld所在目录下执行

      root@TinaLinux:~# export LD_LIBRARY_PATH=/root/boost_arm/lib:$LD_LIBRARY_PATH
      

      可以看到我的HelloWorld正常执行

      root@TinaLinux:~# ./HelloWorld
      [[0.452916, 0.119087, -0.459488, -0.733428, 0.374606, 0.244954, -0.237323, -0.109258, 0.907443, -0.413274, -0.157849, 0.158918, 0.0474297, -0.519952, 1.38254, -0.174767, -0.911914, -0.812675, -0.506005, -0.222257, -0.192745, -1.04207, 0.424627, 0.217617, 0.277484, -0.0261248, -0.0865481, -0.371074, -0.275607, 0.937942,
      

      到这里,交叉编译就完成啦,希望各位小伙伴也能顺利进行!

      原文链接:https://blog.csdn.net/where_are_u/article/details/129863901

      1 条回复 最后回复 回复 引用 分享 1
      • 1 / 1
      • First post
        Last post

      Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

      行为准则 | 用户协议 | 隐私权政策