跳到主要内容

Android 支持

kmpkg 的精选注册表持续集成流程会测试 x64-android、arm-neon-android 和 arm64-android 这三个三元组。

Android 构建要求

  1. 下载 Android NDK(原生开发工具包)

  2. 设置环境变量 ANDROID_NDK_HOME 指向 Android NDK 安装目录,完成 Android 工具链配置。示例:

    export ANDROID_NDK_HOME=/home/your-account/Android/Sdk/ndk-bundle

    或:

    export ANDROID_NDK_HOME=/home/your-account/Android/android-ndk-r26d

注意:针对宿主依赖项,你仍需安装 g++ 或其他可靶向宿主系统的 C++ 编译器。

kmpkg 三元组与对应 Android ABI 映射

Android 包含六种不同的应用二进制接口(ABI),每种接口均对应一个 kmpkg 三元组。下表列出了 kmpkg 架构与 Android 架构的映射关系:

KMPKG_TARGET_TRIPLET(kmpkg 目标三元组)ANDROID_ABI(Android 应用二进制接口)ANDROID_ARM_NEON
arm64-androidarm64-v8a-
arm-androidarmeabi-v7aOFF
arm-neon-androidarmeabi-v7aON
x64-androidx86_64-
x86-androidx86-
armv6-androidarmeabi-

在 Docker 容器中构建 Android 库

你可以在 Ubuntu Docker 容器中构建 jsoncpp 等 Android 库。

步骤 1:创建 Dockerfile

新建 Dockerfile 文件,写入以下内容:

FROM ubuntu:22.04

ENV DEBIAN_FRONTEND noninteractive

RUN \
apt-get update && \
apt-get -y upgrade

RUN \
apt-get -y --no-install-recommends install git g++ wget curl zip vim pkg-config tar cmake unzip ca-certificates

# 下载 Android NDK
RUN \
wget https://dl.google.com/android/repository/android-ndk-r26d-linux.zip && \
unzip android-ndk-r26d-linux.zip && \
rm -rf android-ndk-r26d-linux.zip

ENV ANDROID_NDK_HOME /android-ndk-r26d

RUN git clone https://github.com/kumose/kmpkg
WORKDIR kmpkg
RUN ./bootstrap-kmpkg.sh

ENV PATH "/kmpkg:$PATH"
ENV KMPKG_ROOT "/kmpkg"

WORKDIR /project

步骤 2:构建镜像并启动容器

docker build . -t "kmpkg-android"
docker run -it "kmpkg-android" bash

步骤 3:配置并构建库

在容器中创建 /project/kmpkg.json 文件:

{
"dependencies": [
"jsoncpp"
],
"builtin-baseline": "1e68748a7c6914642ed686b2e19c3d688bca150a"
}

执行以下命令为 Android 构建 jsoncpp

kmpkg install --triplet x64-android

使用 Vulkan SDK

kmpkg 提供 vulkan,可通过 find_package(Vulkan) 调用 Vulkan。使用前需设置 VULKAN_SDK 环境变量:

export VULKAN_SDK=/usr/local
./kmpkg install vulkan

NDK 已内置各架构的 Vulkan 头文件和 libvulkan.so 二进制文件。为避免每次安装都手动设置 VULKAN_SDK,可在三元组文件中添加如下配置:

NDK 21.3.6528147 及更早版本

# 示例:arm64-android.cmake
set(KMPKG_CMAKE_SYSTEM_NAME Android)
# API 级别 30 时,libvulkan.so 路径为 $ENV{ANDROID_NDK_HOME}/platforms/android-30/arch-arm64/usr/lib
set(ENV{VULKAN_SDK} $ENV{ANDROID_NDK_HOME}/sysroot/usr)

NDK 22 及更高版本(sysroot 路径变更)

macOS 示例:

# 示例:arm64-android.cmake
set(KMPKG_CMAKE_SYSTEM_NAME Android)
# API 级别 30 时,libvulkan.so 路径为 $ENV{ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/aarch64-linux-android/30
set(ENV{VULKAN_SDK} $ENV{ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr)

配置完成后,即可安装 vulkan 及其依赖包(如 vulkan-hpp):

执行示例:kmpkg install vulkan-hpp:arm64-android
user@host$ ./kmpkg install vulkan-hpp:arm64-android
Computing installation plan...
The following packages will be built and installed:
* vulkan[core]:arm64-android -> 1.1.82.1-1
vulkan-hpp[core]:arm64-android -> 2019-05-11-1
Additional packages (*) will be modified to complete this operation.
Detecting compiler hash for triplet arm64-android...
...
Starting package 1/2: vulkan:arm64-android
Building package vulkan[core]:arm64-android...
-- Using community triplet arm64-android. This triplet configuration is not guaranteed to succeed.
-- [COMMUNITY] Loading triplet configuration from: /.../kmpkg/triplets/community/arm64-android.cmake
-- Querying VULKAN_SDK Environment variable
-- Searching /.../Library/Android/sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/vulkan/ for vulkan.h
-- Found vulkan.h
-- Performing post-build validation
-- Performing post-build validation done
...
Building package vulkan[core]:arm64-android... done
Installing package vulkan[core]:arm64-android...
Installing package vulkan[core]:arm64-android... done
Elapsed time for package vulkan:arm64-android: 35.9 ms
Starting package 2/2: vulkan-hpp:arm64-android
Building package vulkan-hpp[core]:arm64-android...
-- Using community triplet arm64-android. This triplet configuration is not guaranteed to succeed.
-- [COMMUNITY] Loading triplet configuration from: /.../kmpkg/triplets/community/arm64-android.cmake
-- Using cached /.../kmpkg/downloads/KhronosGroup-Vulkan-Hpp-5ce8ae7fd0d9c0543d02f33cfa8a66e6a43e2150.tar.gz
-- Cleaning sources at /.../kmpkg/buildtrees/vulkan-hpp/src/e6a43e2150-4f344cd911.clean. Use --editable to skip cleaning for the packages you specify.
-- Extracting source /.../kmpkg/downloads/KhronosGroup-Vulkan-Hpp-5ce8ae7fd0d9c0543d02f33cfa8a66e6a43e2150.tar.gz
-- Using source at /.../kmpkg/buildtrees/vulkan-hpp/src/e6a43e2150-4f344cd911.clean
-- Performing post-build validation
-- Performing post-build validation done
...
Building package vulkan-hpp[core]:arm64-android... done
Installing package vulkan-hpp[core]:arm64-android...
Installing package vulkan-hpp[core]:arm64-android... done
Elapsed time for package vulkan-hpp:arm64-android: 144.5 ms

Total elapsed time: 1.013 s

The package vulkan-hpp:arm64-android is header only and can be used from CMake via:

find_path(VULKAN_HPP_INCLUDE_DIRS "vulkan/vulkan.hpp")
target_include_directories(main PRIVATE ${VULKAN_HPP_INCLUDE_DIRS})

示例 Android 项目

docs/examples/kmpkg_android_example_cmake 目录提供了可运行的示例,实现了一个依赖 jsoncpp 库的 Android 库:

核心文件说明

  • CMakeLists.txt:仅通过 find_packagetarget_link_library 完成依赖配置;
  • compile.sh:支持选择任意“Android ABI/kmpkg 三元组”组合并测试编译;
  • my_lib.cpp:测试用代码,演示 jsoncpp 的基本使用。
信息

本示例仅聚焦 Android 库的编译,完整 Android 应用的编译超出本文档范围。

简化配置示例:kmpkg_android.cmake

kmpkg_android_example_cmake_script 目录提供了相同示例,并通过 kmpkg_android.cmake 脚本简化配置流程:

关键配置

CMakeLists.txt 中,设置 KMPKG_TARGET_ANDROID 标志后会加载专用配置脚本:

if (KMPKG_TARGET_ANDROID)
include("cmake/kmpkg_android.cmake")
endif()
注意

上述代码需放在 project() 调用之前。

编译示例

通过 compile.sh 脚本可快速完成编译,例如:

cmake .. -DKMPKG_TARGET_ANDROID=ON -DANDROID_ABI=armeabi-v7a