交叉编译c++给android调用

NDK及其作用

NDK(Native Development Kit)是一个由 Google 提供的工具集,用于在 Android 平台上开发 C++ 或其他本机代码。NDK 的主要作用是允许开发人员使用 C、C++ 和其他本机语言编写代码,并将其编译为能够在 Android 设备上运行的本机代码(通常是共享库 .so 文件)。

NDK 的主要作用:

  1. 本机代码开发:NDK 允许开发人员使用 C、C++ 或其他本机语言编写 Android 应用的部分或全部代码。这对于需要高性能计算、直接访问硬件功能或跨平台兼容性的应用程序非常有用。

  2. 性能优化:通过使用本机代码,开发人员可以更好地优化应用程序的性能,特别是对于需要执行计算密集型任务或需要更高控制权的应用程序。

  3. 复用现有代码:NDK 允许开发人员将现有的 C、C++ 代码或库集成到 Android 应用中,这样可以更好地复用现有的代码资产。

  4. 访问底层硬件:通过本机代码,开发人员可以更容易地访问设备的底层硬件功能,如相机、传感器等,以及执行更高级别的硬件控制。

  5. 跨平台兼容性:使用 NDK,开发人员可以更轻松地将现有的跨平台 C、C++ 代码移植到 Android 平台,从而实现跨平台兼容性。

  6. 加密和安全性:通过将关键部分的代码编译为本机代码,可以提高应用程序的安全性,因为本机代码更难被逆向工程或篡改。

NDK下载

NDK下载方式有两种:

  1. 通过官网链接下载对应操作系统的NDK
  2. 笔者另一篇博文(AndroidSDK下载(不通过AndroidStudio))提到的通过命令行工具进行下载

下载后目录结构大致如下:

├─build
│  ├─cmake
│  │  └─hooks
│  │      ├─post
│  │      └─pre
│  ├─core
│  │  └─toolchains
│  │      ├─aarch64-linux-android-clang
│  │      ├─arm-linux-androideabi-clang
│  │      ├─riscv64-linux-android-clang
│  │      ├─x86-clang
│  │      └─x86_64-clang
│  ├─gmsl
│  └─tools
├─meta
├─prebuilt
│  └─windows-x86_64
├─python-packages
├─shader-tools
│  └─windows-x86_64
├─simpleperf
├─sources
├─toolchains
│  └─llvm
│      └─prebuilt
│          └─windows-x86_64
└─wrap.sh

交叉编译示例

示例一

opencv编译

  1. 下载opencv源码
  2. 在包含CMakeLists.txt的根目录中新建编译目录build
  3. 打开build目录
  4. 执行cmake命令如下:

    cmake -G"Ninja"
    -DCMAKE_ANDROID_NDK="xxx/android-ndk"
    -DCMAKE_MAKE_PROGRAM="xxx/ninja.exe"
    -DCMAKE_TOOLCHAIN_FILE="xxx/android-ndk/build/cmake/android.toolchain.cmake" -DCMAKE_INSTALL_PREFIX="../install"
    -DCMAKE_SYSTEM_NAME="Android"
    -DANDROID_NATIVE_API_LEVEL="25"
    -DANDROID_PLATFORM="android-25"
    -DCMAKE_ANDROID_ARCH_ABI="arm64-v8a"
    -DCMAKE_ANDROID_STL_TYPE="c++_shared"
    -DBUILD_ANDROID_PROJECTS=OFF ..

  5. 其中关键的配置CMAKE_ANDROID_NDK用于配置ndk所在目录,CMAKE_TOOLCHAIN_FILE用于配置工具链文件,此文件包含了编译过程中所需的工具、库、及平台选项。CMAKE_SYSTEM_NAME告诉cmake编译的操作系统为android, ANDROID_PLATFORM用于指定与Android SDK匹配的版本,ANDROID_NATIVE_API_LEVEL指定 NDK版本的API级别,CMAKE_ANDROID_ARCH_ABI用于指定cpu架构, 最后-G用于指定构建系统, 由于笔者是在Windows 上编译, 所以指定了Ninja, Linux一般指定为Unix Makefiles
  6. 由于笔者选择的构建系统为Ninja, 所以调用Ninja开始编译, 最后通过调用Ninja install进行安装。 与make类似

重要的编译选项为ANDROID_PLATFORMCMAKE_ANDROID_ARCH_ABICMAKE_TOOLCHAIN_FILE

可根据不同的操作系统选择不同的构建系统, 如Linux一般为Unix Makefiles, Windows一般为NinjaVisual Studio

示例二

结合vscode编译一个自己写的so库

代码的部分就省略了, 主要看关键配置CMakePresets.json文件:

{
    "version": 8,
    "configurePresets": [
        {
            "name": "android compile",
            "displayName": "android compile",
            "description": "Sets Ninja generator, build and install directory",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/out/build/${presetName}",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug",
                "CMAKE_ANDROID_NDK": "xxx/android-ndk",
                "CMAKE_MAKE_PROGRAM": "xxx/ninja.exe",
                "ANDROID_ABI": "arm64-v8a",
                "ANDROID_PLATFORM": "android-21",
                "CMAKE_ANDROID_STL_TYPE":"c++_shared",
                "CMAKE_TOOLCHAIN_FILE": "xxx/build/cmake/android.toolchain.cmake",
                "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
            }
        }
    ]
}

然后编辑自己的CMakeLists.txt文件, 与本机编译(对应交叉编译)没什么不同。

通过CMakePresets.json达到了示例一相同的效果, 只是方式不一样。 编译选项都是一样的。

posted @ 2024-10-10 23:36  汗牛充栋  阅读(3)  评论(0编辑  收藏  举报