10 个版本

使用旧的 Rust 2015

0.2.3 2017年6月21日
0.2.2 2017年2月28日
0.2.1 2016年8月28日
0.2.0 2016年4月20日
0.0.1 2015年3月13日

构建工具 中排名 #614

Download history 11700/week @ 2024-03-14 9485/week @ 2024-03-21 23895/week @ 2024-03-28 9836/week @ 2024-04-04 9895/week @ 2024-04-11 12761/week @ 2024-04-18 9921/week @ 2024-04-25 8240/week @ 2024-05-02 9323/week @ 2024-05-09 20288/week @ 2024-05-16 11823/week @ 2024-05-23 7533/week @ 2024-05-30 7620/week @ 2024-06-06 7374/week @ 2024-06-13 7118/week @ 2024-06-20 3826/week @ 2024-06-27

每月下载量 27,441
514 个 crate(5 个直接)中使用

MIT 许可证

5KB
119

已被 https://github.com/rust-windowing/android-ndk-rs 代替,它与 winit master 兼容

Android Glue

Crates.io Crates.io CircleCI

用法

使用 Docker

为 Android 编译最简单的方法是使用 Dockerphilipalldredge/cargo-apk 镜像。

为了构建 APK,只需这样做

docker run --rm -v <path-to-local-directory-with-Cargo.toml>:/root/src philipalldredge/cargo-apk cargo apk build

例如,如果您在 Linux 上,并且想要在当前工作目录中编译项目。

docker run --rm -v "$(pwd):/root/src" -w /root/src philipalldredge/cargo-apk cargo apk build

请勿在 /root 上挂载卷,否则您将删除 Cargo 的本地安装。

构建完成后,您应该在 target/android-artifacts/debug/apk 中获得 Android 包。

手动使用

设置您的环境

在您可以为 Android 编译之前,您需要设置您的环境。这需要在每个系统上只做一次。

  • 安装 rustup
  • 运行 rustup target add <target> 为您想要编译的所有支持的目标。除非通过 Cargo.toml 调整构建目标,否则构建将尝试为所有支持的目标构建。
    • rustuptarget add armv7-linux-androideabi
    • rustuptarget add aarch64-linux-android
    • rustuptarget add i686-linux-android
    • rustuptarget add x86_64-linux-android
  • 安装 Java JRE 或 JDK(在 Ubuntu 上,sudo apt-get install openjdk-8-jdk)。
  • 下载并解压 Android NDK
  • 下载并解压 Android SDK
  • 在SDK中安装一些组件: ./android-sdk/tools/bin/sdkmanager "platform-tools" "platforms;android-29" "build-tools;29.0.0"
  • 使用 cargo install cargo-apk 安装 cargo-apk
  • 设置环境变量 NDK_HOME 为NDK的路径,以及将 ANDROID_HOME 设置为SDK的路径。

编译

在您的Android crate的项目根目录下运行 cargo apk build。您可以与常规的 cargo build 使用相同的选项。

这将构建一个Android包,位于 target/android-artifacts/<debug|release>/apk

编译多个二进制文件

cargo apk build 支持使用与 cargo build 相同的参数构建多个二进制文件和示例。它将为每个二进制文件生成一个APK。

为bin目标构建的Android包位于 target/android-artifacts/<debug|release>/apk

为example目标构建的Android包位于 target/android-artifacts/<debug|release>/apk/examples

在Android模拟器上测试

启动模拟器,然后运行

cargo apk run

这将安装您的应用程序到模拟器,然后运行它。
如果只想安装,请使用 cargo apk install

要显示日志,请运行: cargo apk logcat | grep RustAndroidGlueStdouterr

与Android交互

如果一个应用程序无法访问屏幕、用户输入等,那么它将非常无趣。

android_glue crate提供了与Android环境的外部函数接口(FFI),用于处理不在stdlib中的事物。

它的工作原理

构建过程

构建过程通过以下方式工作:

  • 使用rustc始终将您的crate编译为共享库
    • 创建自定义CMake工具链文件并设置环境变量,这些变量公开了NDK提供的适当构建工具,以便与cccmake crate一起使用。
    • 在crate根目录相同的目录下创建一个临时文件。这个临时文件作为静态库的crate根。它包含原始crate根的内容以及android_main的实现。
    • 编译android_native_app_glue的分支版本。android_native_app_glue最初由NDK提供。它提供了Android的NativeActivity使用的入口点,该入口点调用android_main
    • 使用NDK提供的链接器进行链接。

这一步输出一个共享库,并且针对每个目标架构运行一次。

然后使用共享库、生成的清单文件和Android SDK中的工具构建APK。如果使用C++标准库,则将其添加到APK中。它使用Android开发工具默认的调试密钥库签名APK。如果密钥库不存在,则使用JRE或JDK中的keytool创建它。

支持的[package.metadata.android]条目

# The target Android API level.
# "android_version" is the compile SDK version. It defaults to 29.
# (target_sdk_version defaults to the value of "android_version")
# (min_sdk_version defaults to 18) It defaults to 18 because this is the minimum supported by rustc.
android_version = 29
target_sdk_version = 29
min_sdk_version = 26

# Specifies the array of targets to build for.
# Defaults to "armv7-linux-androideabi", "aarch64-linux-android", "i686-linux-android".
build_targets = [ "armv7-linux-androideabi", "aarch64-linux-android", "i686-linux-android", "x86_64-linux-android" ]

# The following values can be customized on a per bin/example basis. See multiple_targets example
# If a value is not specified for a secondary target, it will inherit the value defined in the `package.metadata.android`
# section unless otherwise noted.
#

# The Java package name for your application.
# Hyphens are converted to underscores.
# Defaults to rust.<target_name> for binaries. 
# Defaults to rust.<package_name>.example.<target_name> for examples.
# For example: for a binary "my_app", the default package name will be "rust.my_app"
# Secondary targets will not inherit the value defined in the root android configuration.
package_name = "rust.cargo.apk.advanced"

# The user-friendly name for your app, as displayed in the applications menu.
# Defaults to the target name
# Secondary targets will not inherit the value defined in the root android configuration.
label = "My Android App"

# Internal version number used to determine whether one version is more recent than another. Must be an integer.
# Defaults to 1
# See https://developer.android.com.cn/guide/topics/manifest/manifest-element
version_code = 2

# The version number shown to users.
# Defaults to the cargo package version number
# See https://developer.android.com.cn/guide/topics/manifest/manifest-element
version_name = "2.0"

# Path to your application's resources folder.
# If not specified, resources will not be included in the APK
res = "path/to/res_folder"

# Virtual path your application's icon for any mipmap level.
# If not specified, an icon will not be included in the APK.
icon = "@mipmap/ic_launcher"

# Path to the folder containing your application's assets.
# If not specified, assets will not be included in the APK
assets = "path/to/assets_folder"

# If set to true, makes the app run in full-screen, by adding the following line
# as an XML attribute to the manifest's <application> tag :
#     android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen
# Defaults to false.
fullscreen = false

# The maximum supported OpenGL ES version , as claimed by the manifest.
# Defaults to 2.0.
# See https://developer.android.com.cn/guide/topics/graphics/opengl.html#manifest
opengles_version_major = 3
opengles_version_minor = 2

# Adds extra arbitrary XML attributes to the <application> tag in the manifest.
# See https://developer.android.com.cn/guide/topics/manifest/application-element.html
[package.metadata.android.application_attributes]
"android:debuggable" = "true"
"android:hardwareAccelerated" = "true"

# Adds extra arbitrary XML attributes to the <activity> tag in the manifest.
# See https://developer.android.com.cn/guide/topics/manifest/activity-element.html
[package.metadata.android.activity_attributes]
"android:screenOrientation" = "unspecified"
"android:uiOptions" = "none"

# Adds a uses-feature element to the manifest
# Supported keys: name, required, version
# The glEsVersion attribute is not supported using this section. 
# It can be specified using the opengles_version_major and opengles_version_minor values
# See https://developer.android.com.cn/guide/topics/manifest/uses-feature-element
[[package.metadata.android.feature]]
name = "android.hardware.camera"

[[package.metadata.android.feature]]
name = "android.hardware.vulkan.level"
version = "1"
required = false

# Adds a uses-permission element to the manifest.
# Note that android_version 23 and higher, Android requires the application to request permissions at runtime.
# There is currently no way to do this using a pure NDK based application.
# See https://developer.android.com.cn/guide/topics/manifest/uses-permission-element
[[package.metadata.android.permission]]
name = "android.permission.WRITE_EXTERNAL_STORAGE"
max_sdk_version = 18

[[package.metadata.android.permission]]
name = "android.permission.CAMERA"

环境变量

Cargo-apk设置环境变量,这些变量用于将适当的C和C++构建工具暴露给构建脚本。主要目的是支持构建具有使用cccmake crate的构建脚本的crate。

  • CC:NDK提供的针对适当目标和android平台的clang包装器的路径。
  • CXX:NDK提供的针对适当目标和android平台的clang++包装器的路径。
  • AR:NDK提供的ar的路径。
  • CXXSTDLIB:使用NDK提供的完整功能的C++标准库。
  • CMAKE_TOOLCHAIN_FILE:生成CMake工具链的路径。此工具链设置ABI,覆盖任何指定的目标,并包含NDK提供的目标链。
  • CMAKE_GENERATOR:Unix Makefiles默认为Unix Makefiles,而不是使用CMake的默认设置,这取决于平台可能不合适。
  • CMAKE_MAKE_PROGRAM:NDK提供的make的路径。

C++标准库兼容性问题

当crate链接到C++标准库时,使用NDK提供的共享库版本。不幸的是,依赖项加载问题会导致应用程序在较旧的Android版本上崩溃。一旦所有平台上的lld链接器问题得到解决,cargo apk将更新为链接到静态C++库。这应该解决兼容性问题。

没有运行时依赖项