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
3 changes: 3 additions & 0 deletions crossbundle/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ ureq = "2.4.0"
cargo = "0.63.1"
cargo-util = "0.2.0"

[dev-dependencies]
tempfile = "3.2"

[features]
default = ["android", "ios"]
android = []
Expand Down
38 changes: 20 additions & 18 deletions crossbundle/cli/src/commands/build/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl AndroidBuildCommand {
Ok(())
}

/// Compile rust code as a dynamic library, generate Gradle project and build generate apk/aab
/// Compile rust code as a dynamic library, generate Gradle project
pub fn build_gradle(
&self,
config: &Config,
Expand Down Expand Up @@ -224,6 +224,13 @@ impl AndroidBuildCommand {
target_sdk_version,
)?;

let min_sdk_version = android_manifest
.uses_sdk
.as_ref()
.unwrap()
.min_sdk_version
.unwrap_or(MIN_SDK_VERSION);

config.status("Adding libs into APK file")?;
for (compiled_lib, build_target) in compiled_libs {
android::add_libs_into_apk(
Expand All @@ -233,12 +240,7 @@ impl AndroidBuildCommand {
&compiled_lib,
build_target,
profile,
android_manifest
.uses_sdk
.as_ref()
.unwrap()
.min_sdk_version
.unwrap_or(MIN_SDK_VERSION),
min_sdk_version,
&android_build_dir,
&target_dir,
)?;
Expand Down Expand Up @@ -309,12 +311,12 @@ impl AndroidBuildCommand {
)?;

config.status_message("Generating", "proto format APK file")?;
let compiled_res_path = native_build_dir.join("compiled_res");
if !compiled_res_path.exists() {
std::fs::create_dir_all(&compiled_res_path)?;
}

let compiled_res = if let Some(res) = context.android_res() {
let compiled_res_path = native_build_dir.join("compiled_res");
if !compiled_res_path.exists() {
std::fs::create_dir_all(&compiled_res_path)?;
}
let aapt2_compile = sdk.aapt2()?.compile_incremental(
dunce::simplified(&res),
dunce::simplified(&compiled_res_path),
Expand All @@ -329,11 +331,13 @@ impl AndroidBuildCommand {
let mut aapt2_link =
sdk.aapt2()?
.link_compiled_res(compiled_res, &apk_path, &manifest_path);
aapt2_link
.android_jar(sdk.android_jar(target_sdk_version)?)
.assets(context.android_assets().unwrap())
.proto_format(true)
.auto_add_overlay(true);
aapt2_link.android_jar(sdk.android_jar(target_sdk_version)?);
if let Some(assets) = context.android_assets() {
aapt2_link.assets(assets)
} else {
&mut aapt2_link
};
aapt2_link.proto_format(true).auto_add_overlay(true);
aapt2_link.run()?;

config.status("Extracting apk files")?;
Expand Down Expand Up @@ -395,8 +399,6 @@ impl AndroidBuildCommand {
let signed_aab = android_build_dir.join(format!("{}_signed.aab", package_name));
std::fs::rename(&aab_path, &signed_aab)?;
let output_aab = signed_aab.file_name().unwrap().to_str().unwrap();
println!("output_aab {:?}", output_aab);
println!("outputs_build_dir {:?}", outputs_build_dir);
let aab_output_path = outputs_build_dir.join(output_aab);
let mut options = fs_extra::file::CopyOptions::new();
options.overwrite = true;
Expand Down
2 changes: 1 addition & 1 deletion crossbundle/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub mod error;

use clap::Parser;
use colored::Colorize;
use commands::*;
pub use commands::*;
use crossbundle_tools::utils::{Config, Shell, Verbosity};
use std::path::PathBuf;

Expand Down
56 changes: 56 additions & 0 deletions crossbundle/cli/tests/build_gradle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use cli::build::{android::AndroidBuildCommand, BuildContext, SharedBuildCommand};
// use cli::{android::AndroidBuildCommand, BuildContext, SharedBuildCommand};
use crossbundle_tools::{
commands::gen_minimal_project,
types::AndroidTarget,
utils::{Config, Shell},
};

#[test]
/// Use macroquad minimal project in a temporary directory to test gradle project generation.
/// It is working likewise the command below.
/// ```sh
/// crossbundle build android --quad --gradle
/// ```
fn test_build_gradle() {
let tempdir = tempfile::tempdir().unwrap();
let project_path = tempdir.path();
let macroquad_project = true;
gen_minimal_project(&project_path, macroquad_project).unwrap();

let target_dir = std::path::PathBuf::from(project_path).join("target");
std::fs::create_dir_all(&target_dir).unwrap();

let shell = Shell::new();
let config = Config::new(shell, target_dir.clone());
let context = BuildContext::new(&config, Some(target_dir.clone())).unwrap();

let shared_build_command = SharedBuildCommand {
example: None,
features: vec![],
all_features: false,
no_default_features: false,
release: false,
target_dir: None,
quad: false,
};

let android_build_command = AndroidBuildCommand {
shared: shared_build_command,
target: vec![AndroidTarget::Aarch64LinuxAndroid],
aab: false,
lib: None,
gradle: None,
sign_key_path: None,
sign_key_pass: None,
sign_key_alias: None,
};

AndroidBuildCommand::build_gradle(
&android_build_command,
&config,
&context,
project_path.to_str().unwrap(),
)
.unwrap();
}
56 changes: 56 additions & 0 deletions crossbundle/cli/tests/execute_aab.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use cli::build::{android::AndroidBuildCommand, BuildContext, SharedBuildCommand};
use crossbundle_tools::{
commands::gen_minimal_project,
types::AndroidTarget,
utils::{Config, Shell},
};

#[test]
/// Use bevy minimal project in a temporary directory to test AAB generation.
/// It is working likewise the command below.
/// ```sh
/// crossbundle build android --quad --aab
/// ```
fn test_execute_aab() {
let tempdir = tempfile::tempdir().unwrap();
let project_path = tempdir.path();
let macroquad_project = false;
gen_minimal_project(&project_path, macroquad_project).unwrap();

let target_dir = std::path::PathBuf::from(project_path).join("target");
std::fs::create_dir_all(&target_dir).unwrap();

let shell = Shell::new();
let config = Config::new(shell, target_dir.clone());
let context = BuildContext::new(&config, Some(target_dir.clone())).unwrap();

let shared_build_command = SharedBuildCommand {
example: None,
features: vec![],
all_features: false,
no_default_features: false,
release: false,
target_dir: None,
quad: false,
};

let android_build_command = AndroidBuildCommand {
shared: shared_build_command,
target: vec![AndroidTarget::Aarch64LinuxAndroid],
aab: false,
lib: None,
gradle: None,
sign_key_path: None,
sign_key_pass: None,
sign_key_alias: None,
};

let (_, _, generated_aab_path, _, _) =
AndroidBuildCommand::execute_aab(&android_build_command, &config, &context).unwrap();
let expected_path = target_dir
.join("android")
.join("example")
.join("outputs")
.join("example_signed.aab");
assert_eq!(generated_aab_path, expected_path);
}
56 changes: 56 additions & 0 deletions crossbundle/cli/tests/execute_apk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use cli::build::{android::AndroidBuildCommand, BuildContext, SharedBuildCommand};
use crossbundle_tools::{
commands::gen_minimal_project,
types::AndroidTarget,
utils::{Config, Shell},
};

#[test]
/// Use macroquad minimal project in a temporary directory to test APK generation.
/// It is working likewise the command below.
/// ```sh
/// crossbundle build android --quad
/// ```
fn test_execute_apk() {
let tempdir = tempfile::tempdir().unwrap();
let project_path = tempdir.path();
let macroquad_project = true;
gen_minimal_project(&project_path, macroquad_project).unwrap();

let target_dir = std::path::PathBuf::from(project_path).join("target");
std::fs::create_dir_all(&target_dir).unwrap();

let shell = Shell::new();
let config = Config::new(shell, target_dir.clone());
let context = BuildContext::new(&config, Some(target_dir.clone())).unwrap();

let shared_build_command = SharedBuildCommand {
example: None,
features: vec![],
all_features: false,
no_default_features: false,
release: false,
target_dir: None,
quad: false,
};

let android_build_command = AndroidBuildCommand {
shared: shared_build_command,
target: vec![AndroidTarget::Aarch64LinuxAndroid],
aab: false,
lib: None,
gradle: None,
sign_key_path: None,
sign_key_pass: None,
sign_key_alias: None,
};

let (_, _, generated_apk_path) =
AndroidBuildCommand::execute_apk(&android_build_command, &config, &context).unwrap();
let expected_path = target_dir
.join("android")
.join("example")
.join("outputs")
.join("Example.apk");
assert_eq!(generated_apk_path, expected_path);
}
10 changes: 3 additions & 7 deletions crossbundle/tools/src/commands/android/add_libs_into_apk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,9 @@ fn aapt_add_lib(
.join("libs")
.join(abi)
.join(file_name.to_str().unwrap());
// FIXME: Is this should just let it do nothing if apk file is not found?
// Perhaps throw an error if apk file is not found.
if apk_path.exists() {
let mut aapt = sdk.build_tool(bin!("aapt"), Some(apk_dir))?;
aapt.arg("add").arg(apk_path).arg(add_lib);
aapt.output_err(true)?;
}
let mut aapt = sdk.build_tool(bin!("aapt"), Some(apk_dir))?;
aapt.arg("add").arg(apk_path).arg(add_lib);
aapt.output_err(true)?;
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion crossbundle/tools/src/commands/android/gradle_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub fn gradle_init() -> Result<Command> {
return Ok(Command::new(gradle));
}
let gradle = std::env::var("GRADLE_HOME").ok();
let gradle_path = std::path::PathBuf::from(gradle.ok_or(AndroidError::AndroidSdkNotFound)?);
let gradle_path = std::path::PathBuf::from(gradle.ok_or(AndroidError::GradleNotFound)?);
let gradle_executable = gradle_path.join("bin").join(bat!("gradle"));
Ok(Command::new(gradle_executable))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
pub const BEVY_CARGO_TOML_VALUE: &str = r#"
[package]
name = "example"
version = "0.1.0"
authors = ["DodoRare Team <support@dodorare.com>"]
edition = "2021"
version = "0.1.0"

[dependencies]
crossbow = { git = "https://github.com/dodorare/crossbow" }

[package.metadata]
app_name = "Example"
version_code = 1
target_sdk_version = 30
"#;

pub const BEVY_MAIN_RS_VALUE: &str = r#"fn main(){println!("hello");}"#;

pub const MQ_CARGO_TOML_VALUE: &str = r#"
[package]
name = "example"
authors = ["DodoRare Team <support@dodorare.com>"]
version = "0.1.0"
authors = ["DodoRare Team <support@dodorare.com>"]
edition = "2021"

[dependencies]
crossbow = { git = "https://github.com/dodorare/crossbow" }
anyhow = "1.0"
macroquad = "0.3.7"

[package.metadata]
app_name = "Example"
target_sdk_version = 30
version_code = 1
"#;

pub const MQ_MAIN_RS_VALUE: &str = r#"
Expand Down
Loading