Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@

## Changelog

> This section is optional. If this was a trivial fix, or has no externally-visible impact, you can delete this section.
> This section is optional. If this was a trivial fix or has no externally-visible impact, you can delete this section.

- What changed as a result of this PR?
- If applicable, organize changes under "Added", "Changed", or "Fixed" sub-headings
- Stick to one or two sentences. If more detail is needed for a particular change, consider adding it to the "Solution" section
- If you can't summarize the work, your change may be unreasonably large / unrelated. Consider splitting your PR to make it easier to review and merge!
- If applicable, organize changes under "Added", "Changed", or "Fixed" sub-headings.
- Stick to one or two sentences. If more detail is needed for a particular change, consider adding it to the "Solution" section.

## Migration Guide

> This section is optional. If there are no breaking changes, you can delete this section.

- If this PR is a breaking change (relative to the last release of Crossbow), describe how a user might need to migrate their code to support these changes
- Simply adding new functionality is not a breaking change.
- Fixing behavior that was definitely a bug, rather than a questionable design choice is not a breaking change.
- Fixing behavior that was definitely a bug rather than a questionable design choice is not a breaking change.
1 change: 1 addition & 0 deletions .github/scripts/publish_crates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Legends say that the order of the crates should be kept.
crates=(
platform/android
platform/ios
plugins/admob
crossbundle/tools
crossbundle/cli
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
build-and-publish-release:
name: Build and publish Github release
runs-on: ${{ matrix.os }}
if: false
strategy:
fail-fast: false
matrix:
Expand Down
14 changes: 10 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,31 @@ authors = ["DodoRare Team <support@dodorare.com>"]
description = "Cross-Platform Rust Toolkit for Games 🏹"
repository = "https://github.com/dodorare/crossbow"
license = "Apache-2.0"
keywords = ["build", "android", "apple", "ios", "tools"]
keywords = ["build", "android", "ios", "tools"]
readme = "README.md"
exclude = [".github/**/*"]

[dependencies]
# Platform-specific dependencies
crossbow-android = { path = "platform/android", version = "0.1.6", optional = true }
thiserror = "1.0"
displaydoc = "0.2"
anyhow = "1.0"

[target.'cfg(target_os = "android")'.dependencies]
crossbow-android = { path = "platform/android", version = "0.1.6", optional = true }
ndk-glue = "0.6.2"

[target.'cfg(target_os = "ios")'.dependencies]
crossbow-ios = { path = "platform/ios", version = "0.1.6", optional = true }

[patch.crates-io]
winit = { git = "https://github.com/rust-windowing/winit", rev = "f93f2c158bf527ed56ab2b6f5272214f0c1d9f7d" }
bevy = { git = "https://github.com/dodorare/bevy", rev = "d51104020004d34db1aa3a9a5795834d7814ae55" }
miniquad = { git = "https://github.com/not-fl3/miniquad", rev = "d67ffe6950cf73df307e2d23aaa4726f14399985" }

[features]
default = ["android"]
default = ["android", "ios"]
android = ["crossbow-android"]
ios = ["crossbow-ios"]

[workspace]
members = [
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@

## 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.
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](https://github.com/rust-windowing/android-ndk-rs/tree/master/cargo-apk), [cargo-mobile](https://github.com/BrainiumLLC/cargo-mobile), [cargo-xcode](https://gitlab.com/kornelski/cargo-xcode), etc. - why do I need another packaging tool?

Project `crossbow` is not only a packaging tool for Android and iOS - it's a toolkit. With `crossbundle-tools` you can customize and create new commands; 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 `crossbow-android` you can write your own Android plugins in *Java/Kotlin*.
Project `crossbow` is not only a packaging tool for **Android** and iOS - it's a toolkit. With `crossbundle-tools` you can customize and create new commands; 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 `crossbow-android` you can write your own Android plugins in *Java/Kotlin*.

## Design Goals

* **Customizable**: Create new commands with available tools.
* **Simple**: Easy to start but 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 - almost everything can be configured from **Cargo.toml**.
* **Rust**: Don't leave your *Rust* code - almost everything can be configured from `Cargo.toml`.

## 🛠 Installation

Expand All @@ -41,14 +41,16 @@ Crossbundle crates:

| Name | Description | Status |
| ---- | ----------- | ------ |
| [crossbundle](./crossbundle/cli) | Command-line tool for building applications. | ✅ |
| [crossbundle](./crossbundle/cli) | Command-line tool for building and running applications. | ✅ |
| [crossbundle-tools](./crossbundle/tools) | Toolkit used in `crossbundle` to build/pack/sign bundles. | ✅ |

Crossbow Plugins:

| Name | Description | Status |
| ---- | ----------- | ------ |
| [crossbow-admob](./crossbow/admob) | Google AdMob Plugin for Android. | 🆗 |
| [crossbow-android](./platform/android) | Crossbow Android Platform implementation. | 🆗 |
| [crossbow-ios](./platform/ios) | Crossbow iOS Platform implementation. | 🛠 |
| [crossbow-admob](./crossbow/admob) | Google AdMob Plugin for Android (iOS in future). | 🆗 |
| [crossbow-play-billing](./crossbow/play-billing) | Google Play Billing for Android. | 📝 |
| [crossbow-play-games-sdk](./crossbow/play-games-sdk) | Google Play Games Sdk for Android. | 📝 |

Expand Down
2 changes: 1 addition & 1 deletion crossbundle/cli/src/commands/build/apple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl AppleBuildCommand {
config.status("Copying binary to app folder")?;
std::fs::copy(&bin_path, &app_path.join(&name)).unwrap();
config.status_message("Generating", "Info.plist")?;
apple::save_apple_plist(&app_path, properties, false).unwrap();
apple::save_info_plist(&app_path, properties, false).unwrap();
if self.identity.is_some() {
config.status("Starting code signing process")?;
apple::copy_profile(
Expand Down
2 changes: 2 additions & 0 deletions crossbundle/cli/src/commands/build/build_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ impl BuildContext {
pub fn gen_info_plist(&self, package_name: &str) -> Result<InfoPlist> {
if let Some(info_plist_path) = &self.apple_config.info_plist_path {
Ok(apple::read_info_plist(info_plist_path)?)
} else if let Some(info_plist) = &self.apple_config.info_plist {
Ok(info_plist.clone())
} else {
Ok(apple::gen_minimal_info_plist(
package_name,
Expand Down
16 changes: 8 additions & 8 deletions crossbundle/cli/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,25 @@ pub enum Error {
TeamIdentifierNotProvided,
/// Invalid cargo metadata values
InvalidCargoMetadata,
/// Invalid metadata in manifest
/// Invalid metadata in manifest: {0:?}
InvalidMetadata(anyhow::Error),
/// IO error
/// IO error: {0:?}
Io(#[from] std::io::Error),
/// Clap error
/// Clap error: {0:?}
Clap(#[from] clap::Error),
/// Anyhow error
/// Anyhow error: {0:?}
AnyhowError(#[from] anyhow::Error),
/// Crossbundle Tools error
/// Crossbundle Tools error: {0:?}
CrossbundleTools(#[from] crossbundle_tools::error::Error),
/// AndroidManifest error
/// AndroidManifest error: {0:?}
AndroidManifest(#[from] android_manifest::error::Error),
/// FsExtra error
/// FsExtra error: {0:?}
FsExtra(#[from] fs_extra::error::Error),
/// Path {0:?} doesn't exist
PathNotFound(std::path::PathBuf),
/// Home dir not found
HomeDirNotFound,
/// Failed to download jar file
/// Failed to download jar file: {0:?}
DownloadFailed(ureq::Error),
/// Failed to create jar file in specified path `{path}` cause of `{cause}`
JarFileCreationFailed {
Expand Down
7 changes: 7 additions & 0 deletions crossbundle/cli/src/types/android_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ pub const MIN_SDK_VERSION: u32 = 19;

#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct AndroidConfig {
/// Application name.
pub app_name: Option<String>,
/// Application version name.
pub version_name: Option<String>,
/// Application version code.
pub version_code: Option<u32>,
/// Minimum SDK version supported.
pub min_sdk_version: Option<u32>,
/// Target SDK version.
pub target_sdk_version: Option<u32>,
/// Maximum SDK version supported.
pub max_sdk_version: Option<u32>,
/// Icon name in resources.
pub icon: Option<String>,

/// Path to AndroidManifest.xml file.
Expand Down
10 changes: 9 additions & 1 deletion crossbundle/cli/src/types/apple_config.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
use crossbundle_tools::types::*;
use crossbundle_tools::types::{apple_bundle::prelude::*, AppleTarget};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct AppleConfig {
/// Application Name.
pub app_name: Option<String>,
/// Application version name.
pub version_name: Option<String>,
/// Application version code.
pub version_code: Option<u32>,
/// Icon name in resources.
pub icon: Option<String>,

/// Path to Info.plist file.
pub info_plist_path: Option<PathBuf>,

/// Apple Info.plist configuration.
pub info_plist: Option<InfoPlist>,
/// Apple build targets.
pub build_targets: Option<Vec<AppleTarget>>,
/// Apple resources directory path relatively to project path.
Expand Down
4 changes: 2 additions & 2 deletions crossbundle/tools/src/commands/apple/save_plist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::fs::File;
use std::path::Path;

/// Saves given InfoPlist in new `Info.plist` file.
pub fn save_apple_plist(out_dir: &Path, properties: &InfoPlist, binary: bool) -> Result<()> {
pub fn save_info_plist(out_dir: &Path, properties: &InfoPlist, binary: bool) -> Result<()> {
// Create Info.plist file
let file_path = out_dir.join("Info.plist");
let file = File::create(file_path)?;
Expand Down Expand Up @@ -104,7 +104,7 @@ mod tests {
},
..Default::default()
};
save_apple_plist(dir.path(), &properties, false).unwrap();
save_info_plist(dir.path(), &properties, false).unwrap();
let file_path = dir.path().join("Info.plist");
let result = std::fs::read_to_string(&file_path).unwrap();
assert_eq!(result, PLIST_TEST_EXAMPLE.replace(" ", "\t"));
Expand Down
22 changes: 11 additions & 11 deletions crossbundle/tools/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ pub enum AndroidError {
FailedToFindAndroidManifest(String),
/// Unable to find NDK file
UnableToFindNDKFile,
/// AndroidTools error
/// AndroidTools error: {0:?}
AndroidTools(#[from] android_tools::error::Error),
/// AndroidManifest error
/// AndroidManifest error: {0:?}
AndroidManifest(#[from] android_manifest::error::Error),
}

Expand All @@ -61,7 +61,7 @@ pub enum AppleError {
ZipCommandFailed,
/// Codesign allocate not found
CodesignAllocateNotFound,
/// Simctl error
/// Simctl error: {0:?}
Simctl(simctl::Error),
/// Target dir does not exists
TargetNotFound,
Expand All @@ -71,7 +71,7 @@ pub enum AppleError {
AssetsNotFound,
/// Failed to find Info.plist in path: {0}
FailedToFindInfoPlist(String),
/// Plist data error
/// Plist data error: {0:?}
Plist(#[from] plist::Error),
}

Expand Down Expand Up @@ -115,19 +115,19 @@ pub enum Error {
/// Failed to choose shell string color.
/// Argument for --color must be auto, always, or never, but found `{}`
FailedToChooseShellStringColor(String),
/// IO error
/// IO error: {0:?}
Io(#[from] std::io::Error),
/// FS Extra error
/// FS Extra error: {0:?}
FsExtra(#[from] fs_extra::error::Error),
/// Zip error
/// Zip error: {0:?}
Zip(#[from] zip::result::ZipError),
/// Android error
/// Android error: {0:?}
Android(#[from] AndroidError),
/// Apple error
/// Apple error: {0:?}
Apple(#[from] AppleError),
/// Anyhow error
/// Anyhow error: {0:?}
AnyhowError(#[from] anyhow::Error),
/// Other error
/// Other error: {0:?}
OtherError(#[from] Box<dyn std::error::Error>),
}

Expand Down
2 changes: 1 addition & 1 deletion crossbundle/tools/tests/apple_full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ fn test_apple_full() {

// Generate Info.plist
let properties = get_minimal_info_plist(&name);
save_apple_plist(&app_dir, &properties, false).unwrap();
save_info_plist(&app_dir, &properties, false).unwrap();

// Sign bundle
codesign(&app_dir, true, None, None).unwrap();
Expand Down
18 changes: 15 additions & 3 deletions examples/macroquad-permissions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ edition = "2021"

[dependencies]
crossbow = { version = "0.1.6", path = "../../" }
crossbow-admob = { version = "0.1.6", path = "../../plugins/admob" }
log = "0.4"
anyhow = "1.0"
macroquad = "0.3.7"
async-executor = "1.4.1"
futures-lite = "1.12.0"

[target.'cfg(target_os = "android")'.dependencies]
crossbow-admob = { version = "0.1.6", path = "../../plugins/admob" }

[package.metadata.android]
app_name = "Macroquad_Permissions"
target_sdk_version = 30
Expand Down Expand Up @@ -45,10 +47,20 @@ name = "android.permission.CAMERA"

[package.metadata.apple]
app_name = "Macroquad_Permissions"
target_sdk_version = 30
version_code = 1
icon = "ic_launcher"
icon = "icon"

build_targets = ["aarch64-apple-ios", "x86_64-apple-ios"]
assets = "assets"
res = "res/apple"

[package.metadata.apple.info_plist]
CFBundleIdentifier = "dodorare.macroquad-permissions"
CFBundleVersion = "1.0"
CFBundleShortVersionString = "1.0"
CFBundleExecutable = "macroquad-permissions"
UILaunchStoryboardName = "LaunchScreen"
CFBundleName = "Macroquad_Permissions"
# Permissions
NSCameraUsageDescription = "Macroquad_Permissions requires access to your phone's camera."
NSPhotoLibraryUsageDescription = "Macroquad_Permissions requires access to your phone's photo library."
Loading