前言

在部分算法开发过程中需要将C++编写的算法编译到各个平台上进行部署。对于多个目标平台的编译任务而言,可以是一件很麻烦的事情,例如对android和嵌入式linux平台等,需要依赖各种不同的工具链来进行编译,导致工程量大。
而且如果源代码基于cmake构建随后又要部署到使用eclipse等工具的开发环境中的话又是异常痛苦的过程。
所以本文基于Ubuntu20.04+VScode+cmake构建了一个多平台的编译环境,可以同时编译嵌入式Linux、Android和Linux平台的C++库,在此记录分享。


一、环境准备

本文使用的环境

  • 操作系统 Ubuntu 20.0.4 LTS
  • 构建工具 cmake 3.23
  • 嵌入式arm编译器 gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf
  • android C++库编译器 android-ndk-r26b

二、安装步骤

1.GCC编译器安装

这部分负责安装ubunutu的默认编译器,对于一个新系统而言是必要的,所以进行安装:
shift+alt+T 进入终端:

sudo apt update
sudo apt install build-essential

通过运行下面的命令,打印 GCC 版本,来验证 GCC 编译器是否被成功地安装
输出如下内容表示正确安装:

gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0
Copyright © 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

请添加图片描述

2.Arm Linux编译器安装

本文使用的是gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf编译器,具体其他的体系架构的arm编译器可以在linaro官网发布的预编译版本中获取。
https://releases.linaro.org/components/toolchain/binaries/
以本文所使用的gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf为例,搭建构建环境;

创建编译器目录:

mkdir compilers
cd compilers

下载编译器工具链:
https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz

wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz

解压工具链:

tar -xvf ./gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz 

得到已解压的工具链文件夹:
请添加图片描述
进入编译器文件夹,编写toolchain.cmake文件(可选,方便后期命令行使用cmake调用该编译器)
请添加图片描述
toolchain.cmake文件内容为:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
#以下内容需要替换为自己电脑上的编译器位置
set(CMAKE_C_COMPILER  /home/qiyao/compilers/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER  /home/qiyao/compilers/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++)

至此arm linux嵌入式编译器准备完毕。

3.cmake 3.23 编译安装

由于ubuntu20.4默认安装的cmke版本偏低,在使用Android NDK工具链时会提示警告,所以本文使用编译的方式安装3.23版本cmake。
依赖库openssl,提前安装:

sudo apt-get -y install libssl-dev

如果有旧版本的cmake安装,则需要进行卸载:

sudo apt -y remove cmake

随后通过源码下载cmake 3.23版本:

wget https://cmake.org/files/v3.23/cmake-3.23.0.tar.gz

进行解压:

tar -zxvf cmake-3.23.0.tar.gz

进入文件夹

cd cmake-3.23.0/

配置cmake:

./configure

编译并安装,这一部分需要花费一点时间:

sudo make -j
sudo make install

验证是否安装成功,如果看到版本号,表示安装成功!
请添加图片描述

4.Android NDK编译工具链安装

工具链下载页面:https://developer.android.google.cn/ndk/downloads?hl=zh-cn
旧版本工具链下载页面:https://github.com/android/ndk/wiki/Unsupported-Downloads

本文以android-ndk-r26b为例:
下载工具链:

wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip

解压NDK编译工具链:

unzip ./android-ndk-r26b-linux.zip 

得到NDK编译链的文件夹
请添加图片描述

5.VScode 安装

VScode下载页面:https://code.visualstudio.com/Download
选择合适的版本进行下载安装即可

VScode需要安装以下插件:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
安装完cmake tool后侧边栏会出现cmake的图标
在这里插入图片描述

6.编写cmake-tools-kit文件

在VScode中键入 ctrl+shift+P 并输入cmake edit,选择下图所示项:
在这里插入图片描述
默认包含了系统内置的GCC编译器:
在这里插入图片描述

我们需要为其添加其他两个编译器,笔者这边为armv7和aarch64的安卓平台分别配置了两个编译器kit选项,完整文件如下:

[
  {
    "name": "GCC 9.4.0 x86_64-linux-gnu",
    "compilers": {
      "C": "/usr/bin/gcc",
      "CXX": "/usr/bin/g++"
    },
    "isTrusted": true
  },
  {
    "name": "NDK_arm64-v8a",
    "compilers": {
      "C": "/home/qiyao/compilers/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang",
      "CXX": "/home/qiyao/compilers/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++"
    },
    "environmentVariables": {
      "ANDROID_NDK": "/home/qiyao/compilers/android-ndk-r26b"
    },
    "toolchainFile": "/home/qiyao/compilers/android-ndk-r26b/build/cmake/android.toolchain.cmake",
    "cmakeSettings": {
      "CMAKE_INSTALL_PREFIX": "${workspaceFolder}/out/android/${variant:buildType}/${variant:abi}",
      "ANDROID_TOOLCHAIN": "clang",
      "ANDROID_NATIVE_API_LEVEL": 24,
      "ANDROID_STL": "c++_shared",
      "ANDROID_ABI": "arm64-v8a",
      "CMAKE_CXX_FLAGS_RELEASE": "${CMAKE_CXX_FLAGS} -O3 -DNDEBUG ",
      "CMAKE_CXX_FLAGS_MINSIZEREL": "${CMAKE_CXX_FLAGS} -Os -DNDEBUG -s",
      "ANDROID_CPP_FEATURES": "rtti exceptions"
    },
    "isTrusted": true
  },
  {
    "name": "NDK_armeabi-v7a",
    "compilers": {
      "C": "/home/qiyao/compilers/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang",
      "CXX": "/home/qiyao/compilers/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++"
    },
    "environmentVariables": {
      "ANDROID_NDK": "/home/qiyao/compilers/android-ndk-r26b"
    },
    "toolchainFile": "/home/qiyao/compilers/android-ndk-r26b/build/cmake/android.toolchain.cmake",
    "cmakeSettings": {
      "CMAKE_INSTALL_PREFIX": "${workspaceFolder}/out/android/${variant:buildType}/${variant:abi}",
      "ANDROID_TOOLCHAIN": "clang",
      "ANDROID_NATIVE_API_LEVEL": 24,
      "ANDROID_STL": "c++_shared",
      "ANDROID_ABI": "armeabi-v7a",
      "CMAKE_CXX_FLAGS_RELEASE": "${CMAKE_CXX_FLAGS} -O3 -DNDEBUG ",
      "CMAKE_CXX_FLAGS_MINSIZEREL": "${CMAKE_CXX_FLAGS} -Os -DNDEBUG -s",
      "ANDROID_CPP_FEATURES": "rtti exceptions"
    },
    "isTrusted": true
  },
  {
    "name": "gcc-linaro-7.5.0-2019.12-linux",
    "compilers": {
      "C": "/home/qiyao/compilers/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc",
      "CXX": "/home/qiyao/compilers/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++"
    },
    "cmakeSettings": {
      "CMAKE_CXX_FLAGS_RELEASE": "${CMAKE_CXX_FLAGS} -O3 -DNDEBUG ",
      "CMAKE_CXX_FLAGS_MINSIZEREL": "${CMAKE_CXX_FLAGS} -Os -DNDEBUG -s"
    },
    "isTrusted": true
  }
]

将上述文件的路径改为自己的编译器工具链路径即可保存,笔者为了减小Android编译的native库的体积,在MINSIZEREL预设下添加了-s参数用于进行strip操作,减小库的体积。

愉快编译

随后打开一个示例工程,在左侧侧边栏打开cmake tools图标,选择对应的平台工具链进行配置即可进行编译啦!
在这里插入图片描述

笔者在此还提供了一个直接进行Android NDK编译的脚本文件,可以一次性输出两个安卓平台的ReleaseDebug库文件脚本:

#/bin/bash
export ANDROID_NDK=/home/qiyao/compilers/android-ndk-r26b
rm -r build
mkdir build && cd build 
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
	-DANDROID_ABI="arm64-v8a" \
	-DANDROID_NDK=$ANDROID_NDK \
	-DANDROID_PLATFORM=android-24 \
	..
make 
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
	-DANDROID_ABI="armeabi-v7a" \
	-DANDROID_NDK=$ANDROID_NDK \
	-DANDROID_PLATFORM=android-24 \
	..
make
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
	-DANDROID_ABI="armeabi-v7a" \
	-DANDROID_NDK=$ANDROID_NDK \
	-DANDROID_PLATFORM=android-24 \
	-DCMAKE_BUILD_TYPE="Debug"\
	..
make
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
	-DANDROID_ABI="arm64-v8a" \
	-DANDROID_NDK=$ANDROID_NDK \
	-DANDROID_PLATFORM=android-24 \
	-DCMAKE_BUILD_TYPE="Debug"\
	..
make
cd ..

非常优雅!

总结

由此实现了在Ubuntu 20.04系统下多个算法目标平台的工具链的集成,使用vscode+cmake-tools实现了多平台编译器的切换,从此开发变得简单!

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐