Introduction
What is Crossbow?
The crossbow
project aims to provide a complete toolkit for cross-platform game development in Rust - from project creation to publishing. In addition, the project simplifies the creation, packaging, and signing of Android and iOS applications. We want to make most of our tools - engine agnostic to help rust game developers integrate them into their engines or games.
Why Crossbow?
There are already cargo-apk, cargo-mobile, cargo-xcode, etc. - why do I need another packaging tool?
Project crossbow
is not only a packaging tool for Android and iOS - it's cross-platform build tools and toolkit for Rust! With crossbundle
you can create native .apk/.aab without any Java or setup Gradle project with fancy Crossbow Android plugins (iOS in near future); with crossbundle-tools
you can customize and create new commands; with crossbow-android
you can write your own Android plugins in Java/Kotlin.
A lot of functionality was inspired by Godot, Xamarin, and cargo-apk.
Design Goals
- Customizable: Create new commands with available tools.
- Simple: Easy to install and start hacking but also pretty flexible for strong devs.
- Capable: It's possible to build plain .apk/.aab or .app/.ipa; or with help of Gradle/XCode.
- Rust: Don't leave your Rust code - everything can be configured from
Cargo.toml
. - Plugins: Godot-like plugins for Android (and iOS in future) with Rust wrapper!
Next steps
As the next steps we recommend you to install and setup crossbundle
to be able to build, test, and run your project!
See Getting Started for more information.
Installation
Rust Setup
All crossbow
crates are written in Rust. This means that before we begin, we need to set up our Rust development environment.
Installing Rust
Install Rust by following the Rust Getting Started Guide.
Once this is done, you should have the rustc
compiler and the cargo
build system installed in your path.
Rust Learning Resources
The goal of this book is to learn crossbow
, so it won't serve as a full Rust education. If you would like to learn more about the Rust language, check out the following resources:
- The Rust Book: the best place to learn Rust from scratch.
- Rust by Example: learn Rust by working through live coding examples.
Crossbundle Setup
To begin with crossbow
- you will need to install crossbundle
first. You can do it simply by running the following command:
cargo install --git=https://github.com/dodorare/crossbow crossbundle
Next steps
To complete the installation of all requirements, read the documentation corresponding to your platform:
Android setup on Windows
Install necessary packages
- Use crossbundle install command or download and install Android Studio.
- Start Android Studio, and go through the
Android Studio Setup Wizard
with theCustom
option and install the following (or install them inSDK Manager
):- Android SDK
- NDK (Side by side)
- Android SDK Command-line Tools
- Android SDK Build-Tools
- Android SDK Platform-tools
Install necessary rustup targets
Run the following command:
rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android
Add environment variables
From the Start search bar, enter env
and select Edit environment variables for your account.
Building strategy | Key | Value | Description |
---|---|---|---|
Gradle project, native APK/AAB | ANDROID_SDK_ROOT | <path_to_sdk>\Sdk | Can be replaced with ANDROID_SDK_PATH and ANDROID_HOME. You might not install this env var if you used crossbundle install to set up required packages |
or just want to build native APK or native AAB | |||
Native APK/AAB | ANDROID_NDK_ROOT | <path_to_sdk>\Sdk\ndk<version> | Can be replaced with ANDROID_NDK_PATH and NDK_HOME. You might not install this env var if you used crossbundle install to set up required packages |
Gradle project, native APK/AAB | JAVA_HOME | <path_to_jdk>\bin | Also, we need to make sure we have a java runtime environment (JRE) |
or Java developer kit (JDK) installed. We need jarsigner utility from there | |||
Gradle project | GRADLE_HOME | <path_to_gradle> | Crossbow default build process requires installed Gradle on your PC. You can download it here |
Native AAB | BUNDLETOOL_PATH | <path_to_bundletool> | Download bundletool from the GitHub repository or use crossbundle install |
Or you can install required env via command line accordingly table above. Arguments were provided for example
SETX ANDROID_SDK_ROOT "C:\Users\Username\AppData\Local\Android\Sdk" /M
SETX ANDROID_NDK_ROOT "C:\Users\Username\AppData\Local\Android\Sdk\ndk\23.1.7779620" /M
SETX JAVA_HOME "C:\Program Files\Java\jdk-11.0.15+10" /M
SETX GRADLE_HOME "C:\Gradle\gradle-7.4.2" /M
SETX BUNDLETOOL_PATH "C:\Users\Username\bundletool-all-1.8.2.jar" /M
You have to close and reopen any existing console windows for these changes to take effect.
Set up your Android device
Follow the link to find out how to set up your device or android emulator
Next step
See hello-world to configure your project
After previous steps you can use crossbundle to build gradle project or native APK/AAB. Go to the links:
- Crossbundle build command
- Crossbundle run command
- Crossbundle install command
- Crossbundle new command
Setup Android Environment on Linux
Install necessary packages
- Use crossbundle install command or download and install Android Studio.
- Start Android Studio, and go through the
Android Studio Setup Wizard
with theCustom
option and install the following (or install them inSDK Manager
):- Android SDK
- NDK (Side by side)
- Android SDK Command-line Tools
- Android SDK Build-Tools
- Android SDK Platform-tools
Install necessary rustup targets
Run the following command:
rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android
Add environment variables
From the Start search bar, enter env
and select Edit environment variables for your account.
Building strategy | Key | Value | Description |
---|---|---|---|
Gradle project, native APK/AAB | ANDROID_SDK_ROOT | <path_to_sdk>\Sdk | Can be replaced with ANDROID_SDK_PATH and ANDROID_HOME. You might not install this env var if you used crossbundle install to set up required packages |
or just want to build native APK or native AAB | |||
Native APK/AAB | ANDROID_NDK_ROOT | <path_to_sdk>\Sdk\ndk<version> | Can be replaced with ANDROID_NDK_PATH and NDK_HOME. You might not install this env var if you used crossbundle install to set up required packages |
Gradle project | GRADLE_HOME | <path_to_gradle> | Crossbow default build process requires installed Gradle on your PC. You can download it here |
Native AAB | BUNDLETOOL_PATH | <path_to_bundletool> | Download bundletool from the GitHub repository or use crossbundle install |
For that edit ~/.bash_profile or ~/.bashrc files so they contain those lines:
export ANDROID_SDK_ROOT=$HOME/Android/Sdk
export ANDROID_NDK_ROOT=$HOME/Android/Sdk/ndk/23.1.7779620
export GRADLE_HOME=<path_to_gradle>
export BUNDLETOOL_PATH=<path_to_bundletool>
Also, we need to make sure we have a java runtime environment (JRE) installed. We need a key tool utility from there.
To make sure it's present type this command: ls /usr/lib/jvm/default/bin/ | grep keytool
But please be aware that your path may vary. The above path is for arch-based Linux.
If not, install JRE accordingly to your operating system: Examples:
- Ubuntu:
sudo apt install default-jdk
- Manjaro (Arch):
sudo pacman -S jre11-openjdk-headless jre11-openjdk jdk11-openjdk openjdk11-doc openjdk11-src
Set up your Android device
Follow the link to find out how to set up your device or android emulator
Next step
See hello-world to configure your project
After previous steps you can use crossbundle to build gradle project or native APK/AAB. Go to the links:
- Crossbundle build command
- Crossbundle run command
- Crossbundle install command
- Crossbundle new command
Android setup on MacOS
Install necessary packages
- Use crossbundle install command or download and install Android Studio.
- Start Android Studio, and go through the
Android Studio Setup Wizard
with theCustom
option and install the following (or install them inSDK Manager
):- Android SDK
- NDK (Side by side)
- Android SDK Command-line Tools
- Android SDK Build-Tools
- Android SDK Platform-tools
- Download and install java. Can be installed with
brew
through:
brew tap adoptopenjdk/openjdk
brew install --cask adoptopenjdk8
Install necessary rustup targets
Run the following command:
rustup target add armv7-linux-androideabi aarch64-linux-android i686-linux-android x86_64-linux-android
Add environment variables
From the Start search bar, enter ‘env’ and select Edit environment variables for your account.
Building strategy | Key | Value | Description |
---|---|---|---|
Gradle project, native APK/AAB | ANDROID_SDK_ROOT | <path_to_sdk>\Sdk | Can be replaced with ANDROID_SDK_PATH and ANDROID_HOME. You might not install this env var if you used crossbundle install to set up required packages |
or just want to build native APK or native AAB | |||
Native APK/AAB | ANDROID_NDK_ROOT | <path_to_sdk>\Sdk\ndk<version> | Can be replaced with ANDROID_NDK_PATH and NDK_HOME. You might not install this env var if you used crossbundle install to set up required packages |
Gradle project | GRADLE_HOME | <path_to_gradle> | Crossbow default build process requires installed Gradle on your PC. You can download it here |
Native AAB | BUNDLETOOL_PATH | <path_to_bundletool> | Download bundletool from the GitHub repository or use crossbundle install |
For that edit ~/.bash_profile/~/.bashrc or ~/.zshrc files so they contain those lines:
export ANDROID_SDK_ROOT=$HOME/android/sdk
export ANDROID_NDK_ROOT=$ANDROID_SDK_ROOT/ndk/23.1.7779620
export GRADLE_HOME=<path_to_gradle>
export BUNDLETOOL_PATH=<path_to_bundletool>
Also, we need to make sure we have a java runtime environment (JRE) installed. We will need a key tool utility from there.
To make sure it's present type this command: ls /usr/lib/jvm/default/bin/ | grep keytool
or add to your PATH
env var.
Set up your Android device
Follow the link to find out how to set up your device or android emulator
Next step
See hello-world to configure your project
After previous steps you can use crossbundle to build gradle project or native APK/AAB. Go to the links:
- Crossbundle build command
- Crossbundle run command
- Crossbundle install command
- Crossbundle new command
Android setup on Docker
Build Android with Docker
Pre-requirements:
Clone this repository with this command:
git clone https://github.com/dodorare/crossbow
cd ./crossbow/
To run an example Android application with docker
you will need to following steps:
Download the Docker image:
docker pull ghcr.io/dodorare/crossbundle:latest
Run the following command at the root of crossbow
project:
For unix systems (Bash):
docker run --rm -it -v "$(pwd)/:/src" -w /src/examples/macroquad-permissions ghcr.io/dodorare/crossbundle build android --release
For Windows (PowerShell):
docker run --rm -it -v "${pwd}/:/src" -w /src/examples/macroquad-permissions ghcr.io/dodorare/crossbundle build android --release
Install APK on connected Android phone via USB:
Follow the link to find out how to set up your device or android emulator
adb install ./target/android/macroquad-permissions/gradle/build/outputs/apk/release/gradle-release-unsigned.apk
Or transfer APK file to your phone with any application.
iOS setup on MacOS
Setup on macOS
Install brew
:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Install rust
with default
option:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Source binaries
echo 'source $HOME/.cargo/env' >> ~/.zshrc
source ~/.zshrc
# Or for bash
echo 'source $HOME/.cargo/env' >> ~/.bashrc
source ~/.bashrc
Install iOS targets:
# 64-bit targets (real device & simulator):
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
# 32-bit targets (you probably don't need these & nightly only):
rustup target add armv7-apple-ios armv7s-apple-ios i386-apple-ios
Install ios-deploy
for installing your app on iPhone:
brew install ios-deploy
Install Xcode
from App Store.
Install the necessary Xcode tools
using Xcode
:
- Start
Xcode
. - Choose
Preferences
from theXcode
menu. - In the
Locations
panel, find theCommand Line Tools
field. - Click on the
Command Line Tools
and selectXcode
version (you are asked for your Apple Developer login during the install process).
Login with Free Apple Developer/Apple Developer Program account:
- Start
Xcode
. - Choose
Preferences
from theXcode
menu. - In the
Accounts
panel, click the+
sign (you are asked for your Apple Developer login during the install process). - Click on Apple ID added account and find your name with
(Personal team)
postfix. - Open
Manage Certificates
then click+
andApple Development
. - Close by clicking
Done
and click onDownload Manual Profiles
. iOS setup on MacOS
Install crossbundle
:
cargo install --git=https://github.com/dodorare/crossbow crossbundle
Build Apple app
Now everything is ready to build your application.
To simplify this example we will create a new cargo project by this command:
crossbundle new game --template bevy
cd game/
Now run the build command:
crossbundle build ios --target=x86_64-apple-ios
And if you want to run on the simulator:
crossbundle run ios --target=x86_64-apple-ios
Run your app on a real device
To run your application on a real device you will need to open Xcode
and create a new project
with the same bundle_identifier
as your app. Then you will find a mobileprovision
file
in the ~/Library/MobileDevice/Provisioning\ Profiles
folder (e.x: aec73e2f-c2f9-4e3b-9393-be19cc52fea3.mobileprovision).
With command security find-identity -p codesigning -v
- you will get a similar result:
$ security find-identity -p codesigning -v
1) AF96DABFC5DEE81E339ED8755DA8D1E48A87CBFE "Apple Development: <your-email>@gmail.com (TRGW43YM8W)"
1 valid identities found
The AF96DABFC5DEE81E339ED8755DA8D1E48A87CBFE
value is our sign Identity. Save it for later use.
Copy your code (in our case TRGW43YM8W
) and place it in another command to get Team ID:
$ security find-certificate -c SRGWJ3YM8W -p | openssl x509 -subject
subject= /UID=A9C7ZD8H7F/CN=Apple Development: <your-email>@gmail.com (TRGW43YM8W)/OU=AS9UV719T7/O=<your name>/C=US
-----BEGIN CERTIFICATE-----
MIIFtTCCBJ2...<rest-of-private-key>
Next to OU
- you will find Team ID. (in our case AS9UV719T7
).
Now we are good to install our app on a real device. To run/build app for a real device you will need similar to this command to be run in your cargo project:
crossbundle run ios --release --device --profile-name=aec73e2f-c2f9-4e3b-9393-be19cc52fea3.mobileprovision --team-identifier=AS9UV719T7 --identity=AF96DABFC5DEE81E339ED8755DA8D1E48A87CBFE
Now replace test data (aec73e2f-c2f9-4e3b-9393-be19cc52fea3.mobileprovision
, AS9UV719T7
, AF96DABFC5DEE81E339ED8755DA8D1E48A87CBFE
) - with your own and run command. If everything worked well - you will see new app on your device.
Set up your Android device
To prepare to run your Crossbow
app on an Android device, you need an Android device running Android 4.1 (API level 16) or higher.
- Enable Developer options and USB debugging on your device. Detailed instructions are available in the Android documentation.
- Using a USB cable, plug your phone into your computer. If prompted on your device, authorize your computer to access your device.
Set up the Android emulator
To prepare to run and test your Crossbow app on the Android emulator, follow these steps if you want to install it from the console:
# Run following command to install System Image for Android SDK 31
crossbundle install sdkmanager --install "system-images;android-31;google_apis;x86_64"
# Run this command to create a new Pnone emulator
avdmanager create avd -n Phone -k "system-images;android-31;google_apis;x86_64"
# And finally run this command to start the emulator
emulator -avd=Phone
If you want to install it from the GUI, follow these instructions:
- Enable
VM acceleration
on your machine. - Launch Android Studio, click the AVD Manager icon, and select Create Virtual Device.
- Choose a device definition and select Next.
- Select one or more system images for the Android versions you want to emulate, and select Next. An x86 or x86_64 image is recommended.
- Under Emulated Performance, select Hardware - GLES 2.0 to enable
hardware acceleration
. - Verify the AVD configuration is correct, and select Finish. (For details on the above steps, see
Managing AVDs
) - In Android Virtual Device Manager, click Run in the toolbar. The emulator starts up and displays the default canvas for your selected OS version and device.
Add environment variables
If you will build application with emulator you should add this to environment variables:
Install via command line for for macos and linux:
export PATH=<path_to_sdk>\sdk\emulator:$PATH
export PATH=<path_to_sdk>\sdk\tools\bin:$PATH
Install via command line for windows:
- Add
<path_to_sdk>\sdk\tools\bin
toPATH
variable. - Add
<path_to_sdk>\sdk\emulator
toPATH
variable.
SETX "<path_to_sdk>\sdk\tools\bin" ~PATH~
SETX "<path_to_sdk>\sdk\emulator" ~PATH~
Overview
In this category, you will learn how to use the crossbundle
tool.
- Crossbundle build command
- Crossbundle run command
- Crossbundle install command
- Crossbundle new command
- Crossbundle update command
Crossbundle install command
Setup packages
Use crossbundle
install command to install necessary packages. To find out available commands specify the -h
flag. The -h
flag can be used in all subcommands crossbundle install offers.
crossbundle install -h
crossbundle install command-line-tools -h
Install tools to APK building
We offer to use our command to fast installation all required packages.
crossbundle install --preferred
This command will setup command line tools, Android platforms, build-tools, Android NDK and bundletool for AAB correct working. To provide custom installation read the article below.
Install command-line tools
If you do not need Android Studio, you can download the basic Android command line tools below. You can use the included sdkmanager to download other SDK packages.
These tools are included in Android Studio.
To see all available options use the -h flag. To install command line tools use the command:
crossbundle install command-line-tools
The command will download a zip archive and unzip command line tools into $HOME\AppData\Local\Android\Sdk\cmdline-tools\bin
for windows and $HOME/Local/Android/Sdk/cmdline-tools/bin
for other operating systems.
Note: Android studio install cmdline tools into $SDK_ROOT/cmdline-tools/<version>/bin
.
Install packages
The sdkmanager is a command-line tool that allows you to view, install, update, and uninstall packages for the Android SDK.
Also you can install packages manually. To see all available tools use the -h flag. List installed and available packages:
crossbundle install sdkmanager --list
And then enter the command.
crossbundle install sdkmanager --install "build-tools;31.0.0" "ndk;23.1.7779620" "platforms;android-31"
The command will install packages into $HOME\AppData\Local\Android\Sdk\
for Windows, $HOME/Library/Android/sdk/
for macOS, and $HOME/Android/sdk/
for Linux.
Install bundletool to AAB building
To install bundletool use command below. To see all available options use the -h flag.
crossbundle install bundletool
The command will download bundletool from GitHub repository
and save it into $HOME
. Notice, that you should install Java JDK to open bundletool jar file.
Crossbundle build command
Crossbundle build gradle
Crossbow default build process requires installed Gradle on your PC.
To create a project go to the example you want to build and use the command below. The command belongs to macroquad engine examples building:
crossbundle build android
# To specify custom export gradle directory
crossbundle build android --export-path=./gen/
By default build directory is target/android/<project_name>/gradle
. But you can specify your own build directory via --export-path=<OUT_PATH>
flag. Go to the directory where Gradle project was built and use command below to manually install APK on the device.
gradle installDebug
Also you can replace build
with run
subcommand to build and run APK on your device (it uses installDebug
command under the hood). To see how to set android emulator check install recommendations for linux-android, macos-android, windows-android.
Crossbundle build native AAB/APK
If you don't want to use gradle you can specify it in strategy native-apk:
crossbundle build android -s=native-apk
# or do you need AAB:
crossbundle build android -s=native-aab
To find out available commands specify the -h flag.
crossbundle build android -h
Crossbundle run command
Crossbundle run gradle
Crossbow default run process requires installed Gradle on your PC.
To create a project go to the example you want to build and use the command below. The command belongs to macroquad engine examples building:
crossbundle run android
# To specify custom export gradle directory
crossbundle run android --export-path=./gen/
By default run directory is target/android/<project_name>/gradle
. But you can specify your own build directory via --export-path=<OUT_PATH>
flag.
Crossbundle run native AAB/APK
If you don't want to use gradle you can specify it in strategy native-apk:
crossbundle run android -s=native-apk
# or do you need AAB:
crossbundle run android -s=native-aab
To find out available commands specify the -h flag.
crossbundle run android -h
Crossbundle new command
crossbundle
uses cargo-generate
to generate a new project. This means that you need to install it before we proceed.
cargo install cargo-generate
Then you can create a new project:
crossbundle new project-name
# crossbundle new project-name --template bevy
# crossbundle new project-name --template quad
All supported templates you can watch here
(each branch = template).
Troubleshooting
You can face the problem with Cargo.toml
parsing for the generated project:
Crossbundle Tools error: FailedToFindCargoManifest("...")
To resolve this add your project name to members table of crossbow Cargo.toml
:
[workspace]
members = [
"...",
"example/",
"...",
]
Crossbundle update command
Crossbundle has an inner command that allows to check the version used by the user and compare it with the version in crates.io
.
To check the latest version of crossbundle project in crates.io
use:
crossbundle update --check
If the version found in crates.io
is newer than used now you can enter the command below:
crossbundle update --force
Overview
In this category, you will learn how to use the crossbow
crate.
Project configuration
Сonfiguration through metadata
The easiest way to configure a project is with metadata. Here's an example of Cargo.toml
:
[package]
name = "game"
version = "0.1.0"
authors = ["Example <[email protected]>"]
edition = "2021"
[dependencies]
crossbow = "0.2.3"
[package.metadata]
# The user-friendly application name for your app. Displayed in the applications menu
app_name = "Game"
# Android assets directory path relatively to project path
assets = ["assets"]
# Path to icon with `.png` format that will be provided to generate mipmap resources
icon = "path/to/icon.png"
[package.metadata.android]
# Android application wrapper: supports ndk-glue and sokol. Now ndk-glue used by bevy engine and sokol used by macroquad
app_wrapper = "quad"
# Android targets to build on debug or release.
debug_build_targets = ["aarch64-linux-android"]
release_build_targets = ["aarch64-linux-android"]
# Android resources directory path relatively to project path
resources = ["res/android"]
# Complete support of all AndroidManifest.xml attributes
[package.metadata.android.manifest]
package = "com.example.ExampleProject"
# Adds a uses-permission element to the AndroidManifest.xml.
# Note that android_version 23 and higher, Android requires the application to request permissions at runtime
[[package.metadata.android.manifest.uses_permission]]
name = "android.permission.INTERNET"
# Specifies that an app wants a particular permission, but only if the app is installed on a device running
# Android 6.0 (API level 23) or higher. If the device is running API level 22 or lower, the app does not have the specified permission.
# See https://developer.android.com/guide/topics/manifest/uses-permission-sdk-23-element
[[package.metadata.android.manifest.uses_permission_sdk_23]]
name = "android.permission.WRITE_EXTERNAL_STORAGE"
max_sdk_version = 30
# See https://developer.android.com/guide/topics/manifest/service-element
[[package.metadata.android.manifest.service]]
name = "UpdateService"
intent_filter = []
meta_data = []
# See https://developer.android.com/guide/topics/manifest/queries-element#provider
[[package.metadata.android.manifest.queries.provider]]
authorities = "org.khronos.openxr.runtime_broker;org.khronos.openxr.system_runtime_broker"
# Note: The `name` attribute is normally not required for a queries provider, but is non-optional
# as a workaround for aapt throwing errors about missing `android:name` attribute.
# This will be made optional if/when cargo-apk migrates to aapt2.
name = "org.khronos.openxr"
# See https://developer.android.com/guide/topics/manifest/uses-feature-element
#
# Note: there can be multiple .uses_feature entries.
[[package.metadata.android.manifest.features]]
name = "android.hardware.vulkan.level"
required = true
version = 1
# See https://developer.android.com/guide/topics/manifest/meta-data-element
[[package.metadata.android.manifest.application.meta_data]]
name = "com.oculus.vr.focusaware"
value = "true"
[package.metadata.apple]
release_build_targets = ["aarch64-apple-ios", "x86_64-apple-ios"]
# The user-friendly application name for your app. Displayed in the applications menu
app_name = "Example"
# Apple targets to build on debug or release.
debug_build_targets = ["aarch64-apple-ios"]
release_build_targets = ["aarch64-apple-ios", "x86_64-apple-ios"].
# Apple resources directory path relatively to project path.
resources = ["res/apple"]
Сonfiguration through separate files
But sometimes you need to configure something more complex. For such cases, a more suitable way is to use separate AndroidManifest.xml
or/and Info.plist
files.
To enable this feature, you just need to add this to your Cargo.toml
:
[package.metadata.android]
manifest_path = "/path/to/file"
[package.metadata.apple]
info_plist_path = "/path/to/file"
and then place AndroidManifest.xml
or/and Info.plist
near Cargo.toml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rust.game"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="16"
android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application android:allowBackup="true"
android:hasCode="false"
android:icon="@mipmap/ic_launcher"
android:label="Game"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen">
<activity android:name="com.rust.game.MainActivity"
android:label="Game"
android:configChanges="orientation|keyboardHidden|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
That's it, this config file will be used for your mobile application.
Crossbow permissions
To request permissions with Crossbow you will need to add crossbow
dependency to your Cargo.toml file. And add permissions to AndroidManifest.xml
or Info.plist
:
# This one:
[package.metadata]
permissions = ["camera", "microphone", "photos", "storage-read"]
# Will make the same as this one:
[[package.metadata.android.manifest.uses_permission]]
name = "android.permission.READ_EXTERNAL_STORAGE"
[[package.metadata.android.manifest.uses_permission]]
name = "android.permission.CAMERA"
[[package.metadata.android.manifest.uses_permission]]
name = "android.permission.RECORD_AUDIO"
[package.metadata.apple.info_plist]
NSCameraUsageDescription = "This app needs access to your phone's camera."
NSMicrophoneUsageDescription = "This app needs access to your phone's microphone."
NSPhotoLibraryUsageDescription = "This app needs access to your phone's photo library."
Then invoke request_async
function. This function checks the permission status in the application and will request permission if it's not granted yet:
#![allow(unused)] fn main() { use crossbow::Permission; let res = Permission::Camera.request_async().await?; match res { Permission::Unknown => println!("Permission is in an unknown state"), Permission::Denied => println!("Denied by user"), Permission::Disabled => println!("Feature is disabled on device."), Permission::Granted => println!("Granted by user."), Permission::Restricted => println!("Restricted (only iOS)."), } }
Also, remember to set permissions in through Cargo.toml
or Info.plist
/AndroidManifest.xml
files. List of required permissions for Cross-Platform Permission you can find in Permission
enum.
See usage example.
Also, it's possible to request more permissions with this API:
#[cfg(target_os = "android")]
crossbow::android::permission::*;
let res = request_permission(&AndroidPermission::ReadCalendar).await?;
// or this for iOS:
#[cfg(target_os = "ios")]
crossbow::ios::permission::*;
let res = request_permission(&IosPermission::CaptureDevice(MediaType::Audio)).await;
Maybe useful
Useful commands to debug permission status in Android application using adb:
adb shell pm reset-permissions
adb shell pm list permission-groups
adb shell pm list permissions
adb shell pm grant <app package> <permission name>
adb shell pm revoke <app package> <permission name>
Crossbow Android Plugins
To write new Crossbow Android plugin - we recommend to clone this repository and use crossbow-admob
as template for your plugin.
To do so, run these commands:
git clone https://github.com/dodorare/crossbow
cp -r crossbow/plugins/admob-android ./my-awesome-plugin
cd ./my-awesome-plugin
In Rust project you will need to update Cargo.toml and code in src/ folder.
Now in Android gradle project you will able to write your own Android plugin in Java or Kotlin!
Building
To build Android Gradle plugin you need to run the following command:
gradle build
Testing locally
To import your plugin into your game with Crossbow you can add following in Cargo.toml:
[[package.metadata.android.plugins_local_projects]]
include = ":my-awesome-plugin"
project_dir = "../my-awesome-plugin/android"
It will try to find your plugin by the specified path relative to your Cargo.toml.
Publishing to Github Maven repository
To publish your plugin to Github Maven repository you need to get Personal Access Token from your Github account and update information in your my-awesome-plugin/android/publish.gradle
file.
To read more about Github Maven repository visit Publishing Github Maven packages.
As you setup everything - you can run the following command to publish your plugin to Maven repository:
USERNAME=<NAME> TOKEN=<TOKEN> gradle publish
To publish your plugin to crates.io - you can see this official article.
Using Published plugin
After successfully publishing your plugin you can use it in your game. To do so you will want to import it in Cargo.toml:
[dependencies]
my_awesome_plugin = "0.1.0"
[[package.metadata.android]]
plugins_remote = ["com.crossbow.awesome:my_awesome_plugin:0.1.0"]
That's it, now you can use your plugin in your game!
Overview
In this category, you will learn how to use the crossbundle
tool and crossbow
crate by examples and tutorials.
To get started - open Hello World example to see minimal project setup.
Hello world example
Generate a project
Generate new project with crossbundle new command!
Project overview
The project has been created. Now let's see what the project consists of.
The code below is belong to the native crossbow project with pure rust without android plugins.
To see all possibilities of cargo.toml
see crossbow configutarion tutorial
# Cargo.toml
[package]
name = "project-name"
version = "0.1.0"
authors = ["Example <[email protected]>"]
edition = "2021"
[dependencies]
crossbow = "*"
[package.metadata]
app_name = "My Project"
icon = "path/to/icon.png"
We decided to refuse from lib.rs file for a more convenient project configuration. We need only
main.rs
to deploy our code
// main.rs fn main() { println!("Hello, project-name!"); }
Build an application
Let's build and run our first crossbundle
application. Android commands below will generate gradle project and install apk on your device. See crossbundle run command for additional information.
cd project-name. To attach a logger when application deploys on your device use
--log
flag.
crossbundle run android --log
or
crossbundle run ios --log
If you want to build the application for android as native AAB - add -s=native-aab
flag or add -s=native-apk
to build native APK.
You will see the message: "Hello, project-name!"
In-app updates tutorial
Important: First of all you need to install crossbundle if you haven't already. See documention to install it.
Generate a project
crossbundle
uses cargo-generate
to generate a new project. This means that you need to install it before we proceed.
cargo install cargo-generate
Then you can create a new project:
crossbundle new project-name --template quad
All supported templates you can watch here
(each branch = template).
Installation
Important: Before starting please read more about Google Play Core libraries and In-app updates.
Add Rust dependencies like this:
[dependencies]
crossbow = "0.2.3"
[target.'cfg(target_os = "android")'.dependencies]
play-core = "0.2.3"
And finally, add this to your Crossbow Android configuration:
[package.metadata.android]
plugins_remote = ["com.crossbow.play_core:play_core:0.2.3"]
That's it, now you can start using Play Core!
Usage
First step is plugin initialization. In your rust project, you will need to initialize Crossbow
instance and then get Android plugin:
#![allow(unused)] #![cfg(target_os = "android")] fn main() { use crossbow::android::*; let crossbow = CrossbowInstance::new(); let play_core: play_core::PlayCorePlugin = crossbow.get_plugin()?; }
After plugin initialization you can use supported features. For example to start connection and query purchases you can use:
#![allow(unused)] fn main() { play_core.check_update()?; play_core.in_progress_update()?; }
To read signals that plugin returns:
#![allow(unused)] fn main() { if let Ok(signal) = play_core.get_receiver().recv().await { println!("Signal: {:?}", signal); } }
Complete documentation of plugin you can find here.
Build an application
Let's build and run this application. Android command below will generate gradle project and install apk on your device. See crossbundle run command for additional information.
crossbundle run android
But to be able to test In-app updates - you will need to publish your application to Play Store as Internal testing or any other (Closed testing or Production, etc.).
To publish your app to Play Store - you will want to export gradle project with this command:
crossbundle build android --export-path=./path/
Then in generated project add signing to build.gradle
like this:
signingConfigs {
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
and in gradle.properties
actual values:
MYAPP_UPLOAD_STORE_FILE=my-project.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-project
MYAPP_UPLOAD_STORE_PASSWORD=123456
MYAPP_UPLOAD_KEY_PASSWORD=123456
You can read more here, and here.
Google Play Billing tutorial
Important: First of all you need to install crossbundle if you haven't already. See documention to install it.
Generate a project
crossbundle
uses cargo-generate
to generate a new project. This means that you need to install it before we proceed.
cargo install cargo-generate
Then you can create a new project:
crossbundle new project-name --template quad
All supported templates you can watch here
(each branch = template).
Installation
Important: Before using this plugin please follow instructions on Getting ready Google Play Billing official guide.
Just add Rust dependencies like this:
[dependencies]
crossbow = "0.2.3"
[target.'cfg(target_os = "android")'.dependencies]
play-billing = "0.2.3"
And finally, add this to your Crossbow Android configuration:
[package.metadata.android]
plugins_remote = ["com.crossbow.play_billing:play_billing:0.2.3"]
That's it, now you can start using Play Billing!
Usage
First step is plugin initialization. In your rust project, you will need to initialize Crossbow
instance and then get Android plugin:
#![allow(unused)] #![cfg(target_os = "android")] fn main() { use crossbow::android::*; let crossbow = CrossbowInstance::new(); let play_billing: play_billing::PlayBillingPlugin = crossbow.get_plugin()?; }
After plugin initialization you can use supported features. For example to start connection and query purchases you can use:
#![allow(unused)] fn main() { play_billing.start_connection()?; play_billing.query_purchases("YOUR_TYPE")?; }
To read signals:
#![allow(unused)] fn main() { if let Ok(signal) = play_billing.get_receiver().recv().await { println!("Signal: {:?}", signal); } }
Complete documentation you can find here.
Build an application
Important: Read officialtutorial on how to test Google Play Billing for more information here.
Let's build and run this application. Android command below will generate gradle project and install apk on your device. See crossbundle run command for additional information.
crossbundle run android
But to be able to test In-app purchases - you will need to add Products in Google Play Console. And then build and sign your app with your generated keystore.
To publish your app to Play Store Internal Testing - you will want to export gradle project with this command:
crossbundle build android --export-path=./path/
Then in generated project add signing to build.gradle
like this:
signingConfigs {
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
and in gradle.properties
actual values:
MYAPP_UPLOAD_STORE_FILE=my-project.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-project
MYAPP_UPLOAD_STORE_PASSWORD=123456
MYAPP_UPLOAD_KEY_PASSWORD=123456
You can read more here, and here.
Fastlane automation for Android
We want to make you work less on the hard stuff behind the automation of publishing Rust mobile apps so we prepared some best practices on how you can automate the boring stuff with our creator Fastlane plugin. You can read more about Fastlane
here.
Setup
First of all, we would suggest you pass through our crossbow
basic tutorials for Android or/and iOS.
After you got familiar with crossbow
you can get to the following steps to run Fastlane
locally:
- Make sure you have crossbundle installed.
- Install Fastlane.
- Setup XCode or Android Studio depending on which platform you want to run your workflow.
- Create a test project (you can use our template) or add Fastlane to your project.
- Install our
fastlane
plugin with the next commandfastlane add_plugin crossbow
.
Setup for Play Market
- Open Google Play Console (you will need a developer account for this).
- Click on the button "Create app" and specify your application data in the form.
- Generate signing key through Android Studio as shown in this official tutorial.
- Generate a "Play Store Json Key" for Fastlane as shown here.
- Configure corresponding variables in
fastlane/Fastfile
file.
Run lane
To run our Fastlane pipeline just call fastlane android
or fastlane ios
at the root of the project.
Please note, Fastlane will ask you to log in on the first run to configure the setup.
See results
After the successful finish of publishing as an internal testing draft, you should see your release on the Google Play Console
. Find section "Testing" and click on the "Internal testing". You will see something like this:
Feel free to add some other lanes to fill your needs, here's the full list of them.
If you found a bug or issue - you can find or create an issue in this repository.
Using subxt with bevy engine
-
You need to install crossbundle if you haven't already. See documention to install it and configure your project.
-
Specify
subxt
crate andbevy
in your Cargo.toml. We prefer to use versions below:
[dependencies]
subxt = "0.23"
bevy = "0.8.1"
You might need additional dependencies to write your code. See examples/bevy-explorer/cargo.toml
Bevy explorer example
To learn how to use subxt with bevy engine, you can go to the examples/bevy-explorer or install bevy explorer template. Follow next steps:
- Install cargo-generate:
cargo install cargo-generate
- Install bevy-explorer template:
crossbundle new example --template=bevy-explorer
- After previous steps, now you can install the application on the device.
Installing application on the device
You can deploy the application on your device or android emulator with commands below. At first, you should go to example directory. Use it:
Bash:
If the template was installed
cd example
If bevy-explorer example will be used
cd example/bevy-explorer
By default crossbundle build android
command will generate gradle project and install apk on your device. To build native .apk
and .aab
see commands below.
To build native APK and run it on the device using the command. If you want to build an application replaces run
with build
.
crossbundle run android -s=native-apk
or
crossbundle run ios
To build native AAB and run it on the device using the command. If you want to build an application replaces run
with build
.
crossbundle run android -s=native-aab
Contributing
If you want to help us build an awesome Cross-Platform future for Rust Games, please reach out! We need all the help we can get:
- If you are a software developer and you want to help out, check out the Contributing Code section.
- If you are good at writing or teaching, consider Contributing to our Docs.
Also, read testing guide to run tests in crossbow
.
How to Contribute Code
Would you like to contribute code to Crossbow? Here's how!
- Fork the dodorare/crossbow repository on GitHub, you'll need to create a GitHub account if you don't have one already.*
- Make your changes in a local clone of your fork.
- For a higher chance of CI passing the first time, consider run these commands from the root of your local clone:
cargo fmt --all -- --check
(remove --check to let the command fix found problems)cargo clippy --all-targets --all-features -- -D warnings -A clippy::unnecessary-unwrap -A clippy::too-many-arguments
cargo test --all-targets --workspace
- Push your changes to your fork and open a Pull Request.
- Respond to any CI failures or review feedback.
The same steps apply for any other repository in the organization that you would like to contribute to.
How to Contribute Docs
Crossbow Documentation
If you want to contribute to this documentation, please see the Contributing section.
- Fork the dodorare/crossbow repository on GitHub, you'll need to create a GitHub account if you don't have one already.*
- Install mdBook.
- In the "docs/" directory, run
mdbook serve --open
and make your changes in a local clone of your fork. - Push your changes to your fork and open a Pull Request.
- Respond to any CI failures or review feedback.
That's all, big thanks for contributing!
The same steps apply for any other repository in the organization that you would like to contribute to.
Testing guide
How to run tests in crossbow
In crossbow
, we have unit tests, integration tests, and examples. To run tests, you will need to set up an Android and Apple environment (you can find more information in installation category).
If you want to run tests for our crossbundle
crate, you can make it by the following steps: download this repository, proceed to the crossbundle/tools
directory, and run cargo test
. It will run all tests for the crossbundle-tools
crate that is primarily used by crossbundle
.
In case of issues
Feel free to open Github Issues - we will be happy to fix or review them.
Contributors
Here is a list of the contributors who have helped improving Crossbow
. Big shout-out to them!
- David (enfipy) - Project Lead
- Daniil (Heezay)
- Oleksii (olvyko)
- Adil (Adoka3710)
- Rodrigo (rodrigocam)
Development Roadmap
Number | Title | Specification | Status |
---|---|---|---|
1. | Support AAB | Add support of generation AAB file. Android App Bundle is a publishing format that includes all your app’s compiled code and resources. | ✅ |
2. | Support Macroquad engine | Add support of Macroquad engine. We will change our crossbundle command-line tool to support Android and iOS building of Macroquad. | ✅ |
3. | Support Android Plugins | Add support of Android plugins to help add additional functionality provided by the Android platform and ecosystem (like Ads, Auth, In-app purchases, etc.). Something similar to Godot Android plugins. | ✅ |
4. | Support Cross-platform permissions | Provide a single cross-platform permission API that works with any iOS, Android, etc application that can be accessed from shared code no matter how the user interface is created. | ✅ |
5. | Simple installation | Simple installation with environment variables, libs, etc. Make installation of Android SDK, NDK, tools more robust. | ✅ |
6. | Support iOS Plugins | Add support of iOS plugins to help add additional functionality provided by the Apple platforms and ecosystem (like Ads, Auth, In-app purchases, etc.). Something similar to Godot iOS plugins. | 🛠 |
7. | Sign in with Google | Add support of Google Sign In inside any application. | ✅ |
8. | Sign in with Apple | Add support of Apple Sign In inside any application. | 📝 |
9. | Better support for Apple xcrun, xcode proj | Add better support and rust wrappers for Apple xcode tools, xcrun. Make cool xcode project generation library. | 📝 |
10. | Apple Game Center | Add Apple Game Center support. | 📝 |
11. | Android In-App purchases & Google Play Billing | Add support for Google Play Billing. Make it possible to buy items from your application. | ✅ |
12. | Support Apple In-App purchases | Support Apple StoreKit. Make it possible to buy items from your application. | 📝 |
13. | Support Android In-App updates | Add support for Android In-App updates. | ✅ |
✅ = Works and tested — 🆗 = Works but may contain bugs — 🛠 = Under development — 📝 = Planned
Useful links
- https://developers.google.com/games/services/common/concepts/sign-in
- https://developers.google.com/games/services/downloads/sdks
- https://developers.google.com/games/services/cpp/GettingStartedNativeClient
- https://developers.google.com/identity/sign-in/web/build-button
- https://github.com/cgisca/PGSGP
- https://docs.godotengine.org/en/stable/tutorials/platform/ios/ios_plugin.html
- https://github.com/polyhorn/simctl
- https://docs.godotengine.org/en/stable/tutorials/plugins/android/android_plugin.html
- https://github.com/godotengine/godot-google-play-billing
- https://github.com/google/play-unity-plugins
- https://android.googlesource.com/platform/frameworks/opt/gamesdk
- https://developer.android.com/games/develop/permissions
- https://docs.microsoft.com/en-gb/xamarin/essentials
- https://docs.microsoft.com/en-us/xamarin/essentials/permissions
Special Thanks
This project initially funded by Web3 Foundation Grants Program. Big shout-out to them!
If you want to support this project - contact us on our corporate email: [email protected].