diff --git a/crossbundle/cli/Cargo.toml b/crossbundle/cli/Cargo.toml index 633db22a..d8ea6082 100644 --- a/crossbundle/cli/Cargo.toml +++ b/crossbundle/cli/Cargo.toml @@ -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 = [] diff --git a/crossbundle/cli/src/commands/build/android.rs b/crossbundle/cli/src/commands/build/android.rs index f9504f4b..5e5424d0 100644 --- a/crossbundle/cli/src/commands/build/android.rs +++ b/crossbundle/cli/src/commands/build/android.rs @@ -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, @@ -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( @@ -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, )?; @@ -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), @@ -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")?; @@ -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; diff --git a/crossbundle/cli/src/lib.rs b/crossbundle/cli/src/lib.rs index 8b666652..ed7e445c 100644 --- a/crossbundle/cli/src/lib.rs +++ b/crossbundle/cli/src/lib.rs @@ -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; diff --git a/crossbundle/cli/tests/build_gradle.rs b/crossbundle/cli/tests/build_gradle.rs new file mode 100644 index 00000000..0a387c25 --- /dev/null +++ b/crossbundle/cli/tests/build_gradle.rs @@ -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(); +} diff --git a/crossbundle/cli/tests/execute_aab.rs b/crossbundle/cli/tests/execute_aab.rs new file mode 100644 index 00000000..1c73b56d --- /dev/null +++ b/crossbundle/cli/tests/execute_aab.rs @@ -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); +} diff --git a/crossbundle/cli/tests/execute_apk.rs b/crossbundle/cli/tests/execute_apk.rs new file mode 100644 index 00000000..ed3c8920 --- /dev/null +++ b/crossbundle/cli/tests/execute_apk.rs @@ -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); +} diff --git a/crossbundle/tools/src/commands/android/add_libs_into_apk.rs b/crossbundle/tools/src/commands/android/add_libs_into_apk.rs index e0579dee..6857d38a 100644 --- a/crossbundle/tools/src/commands/android/add_libs_into_apk.rs +++ b/crossbundle/tools/src/commands/android/add_libs_into_apk.rs @@ -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(()) } diff --git a/crossbundle/tools/src/commands/android/gradle_command.rs b/crossbundle/tools/src/commands/android/gradle_command.rs index f01cd6e2..7554fa6b 100644 --- a/crossbundle/tools/src/commands/android/gradle_command.rs +++ b/crossbundle/tools/src/commands/android/gradle_command.rs @@ -7,7 +7,7 @@ pub fn gradle_init() -> Result { 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)) } diff --git a/crossbundle/tools/src/commands/common/gen_minimal_project/consts.rs b/crossbundle/tools/src/commands/common/gen_minimal_project/consts.rs index 999cb3be..81edb379 100644 --- a/crossbundle/tools/src/commands/common/gen_minimal_project/consts.rs +++ b/crossbundle/tools/src/commands/common/gen_minimal_project/consts.rs @@ -1,12 +1,17 @@ pub const BEVY_CARGO_TOML_VALUE: &str = r#" [package] name = "example" +version = "0.1.0" authors = ["DodoRare Team "] 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");}"#; @@ -14,14 +19,19 @@ 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 "] version = "0.1.0" +authors = ["DodoRare Team "] 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#" diff --git a/crossbundle/tools/tests/aab_full.rs b/crossbundle/tools/tests/aab_full.rs deleted file mode 100644 index 55a1742f..00000000 --- a/crossbundle/tools/tests/aab_full.rs +++ /dev/null @@ -1,174 +0,0 @@ -use android_tools::java_tools::{android_dir, AabKey, JarSigner, KeyAlgorithm, Keytool}; -use crossbundle_tools::{ - commands::{ - android::{self, remove, rust_compile, GenAndroidManifest}, - gen_minimal_project, - }, - tools::*, - types::*, -}; - -#[test] -/// Tests all tools for creating aab -fn test_aab_full() { - // Creates temporary directory - let tempdir = tempfile::tempdir().unwrap(); - let project_path = tempdir.path(); - - // Assigns configuration for project - let macroquad_project = false; - let package_name = gen_minimal_project(project_path, macroquad_project).unwrap(); - let sdk = AndroidSdk::from_env().unwrap(); - let ndk = AndroidNdk::from_env(Some(sdk.sdk_path())).unwrap(); - let target_sdk_version = 30; - let version_code = 1_u32; - let profile = Profile::Debug; - let build_target = AndroidTarget::Aarch64LinuxAndroid; - let bevy_lib_name = format!("lib{}.so", package_name.replace("-", "_")); - let target_dir = project_path.join("target"); - let android_build_dir = target_dir.join("android").join(profile.to_string()); - let app_wrapper_for_bevy = ApplicationWrapper::NdkGlue; - - // Compile rust code for android with bevy engine - rust_compile( - &ndk, - build_target, - project_path, - profile, - vec![], - false, - false, - target_sdk_version, - &bevy_lib_name, - app_wrapper_for_bevy, - ) - .unwrap(); - println!("rust was compiled for bevy example"); - - // Generates manifest - let manifest = GenAndroidManifest { - package_name: package_name.clone(), - version_code, - ..Default::default() - }; - let android_manifest = manifest.gen_min_android_manifest(); - let manifest_path = - android::save_android_manifest(&android_build_dir, &android_manifest).unwrap(); - assert!(manifest_path.exists()); - - // Compiles resources - let compiled_res_path = android_build_dir.join("compiled_res"); - if !compiled_res_path.exists() { - std::fs::create_dir_all(&compiled_res_path).unwrap(); - } - let res_path = project_path.join("res"); - let aapt2_compile = sdk - .aapt2() - .unwrap() - .compile_incremental(&res_path, &compiled_res_path); - let compiled_res = aapt2_compile.run().unwrap(); - - // Links all resources and creates .apk file - let apk_path = android_build_dir.join(format!("{}_module.apk", package_name)); - let mut aapt2_link = - sdk.aapt2() - .unwrap() - .link_compiled_res(Some(compiled_res), &apk_path, &manifest_path); - aapt2_link - .android_jar(sdk.android_jar(target_sdk_version).unwrap()) - .version_code(1) - .proto_format(true) - .auto_add_overlay(true); - aapt2_link.run().unwrap(); - - // Extracts files from .apk into /extracted_apk_files folder - let output_dir = android_build_dir.join("extracted_apk_files"); - let extracted_apk_path = android::extract_archive(&apk_path, &output_dir).unwrap(); - assert!(extracted_apk_path.exists()); - - // Specifies needed directories to manage library location - let mut libs = Vec::new(); - let out_dir = target_dir - .join(build_target.rust_triple()) - .join(profile.as_ref()); - let compiled_lib = out_dir.join(&bevy_lib_name); - // Check the size of the library to ensure it is not corrupted - if compiled_lib.exists() { - let size = std::fs::metadata(&compiled_lib).unwrap().len(); - println!("library size is {:?}", size); - } - assert!(compiled_lib.exists()); - libs.push((compiled_lib, build_target)); - - // Adds libs into specified directory - for (compiled_lib, build_target) in libs { - let lib = android::add_libs_into_aapt2( - &ndk, - &compiled_lib, - build_target, - profile, - target_sdk_version, - &extracted_apk_path, - &target_dir, - &package_name, - ) - .unwrap(); - assert!(lib.exists()); - } - - // Generates zip archive - let gen_zip_modules = - android::gen_zip_modules(&android_build_dir, &package_name, &extracted_apk_path).unwrap(); - - // Genenerates aab from given list of modules (zip, zip, zip) - let aab_path = android::gen_aab_from_modules( - &package_name, - &[gen_zip_modules.clone()], - &android_build_dir, - ) - .unwrap(); - - // Removes unnecessary files - remove(vec![extracted_apk_path, gen_zip_modules]).unwrap(); - - // Removes old keystore if it exists - let android_dir = android_dir().unwrap(); - let target = vec![android_dir.join("aab.keystore")]; - remove(target).unwrap(); - - // Create keystore with deafault configuration - let key = AabKey::new_default().unwrap(); - Keytool::new() - .genkeypair(true) - .v(true) - .keystore(&key.key_path) - .alias(&key.key_alias) - .keypass(&key.key_pass) - .storepass(&key.key_pass) - .dname(&["CN=Android Debug,O=Android,C=US".to_owned()]) - .keyalg(KeyAlgorithm::RSA) - .keysize(2048) - .validity(10000) - .run() - .unwrap(); - - // Sign AAB with created keystore - JarSigner::new(&aab_path, &key.key_alias) - .keystore(&key.key_path) - .storepass(key.key_pass.to_string()) - .verbose(true) - .sigalg("SHA256withRSA".to_string()) - .digestalg("SHA-256".to_string()) - .run() - .unwrap(); - - // Creates apks from generated aab - let apks = android_build_dir.join(format!("{}.apks", package_name)); - let _build_apks = BuildApks::new(&aab_path, &apks) - .overwrite(true) - .ks(&key.key_path) - .ks_pass_pass(key.key_pass) - .ks_key_alias(key.key_alias) - .run() - .unwrap(); -} diff --git a/crossbundle/tools/tests/android_full.rs b/crossbundle/tools/tests/android_full.rs deleted file mode 100644 index e62f3f59..00000000 --- a/crossbundle/tools/tests/android_full.rs +++ /dev/null @@ -1,134 +0,0 @@ -use android_tools::java_tools::{android_dir, AabKey, KeyAlgorithm, Keytool}; -use crossbundle_tools::{ - commands::{ - android::{self, remove, rust_compile, GenAndroidManifest}, - gen_minimal_project, - }, - tools::{AndroidNdk, AndroidSdk}, - types::*, -}; - -#[test] -/// Tests all tools for creating apk -fn test_android_full() { - // Creates temporary directory - let tempdir = tempfile::tempdir().unwrap(); - let project_path = tempdir.path(); - let macroquad_project = true; - let quad_package_name = gen_minimal_project(&project_path, macroquad_project).unwrap(); - - // Create dependencies - let sdk = AndroidSdk::from_env().unwrap(); - let ndk = AndroidNdk::from_env(Some(sdk.sdk_path())).unwrap(); - let target_sdk_version = 30; - let version_code = 1_u32; - let profile = Profile::Release; - let build_target = AndroidTarget::Aarch64LinuxAndroid; - let quad_lib_name = format!("lib{}.so", quad_package_name.replace("-", "_")); - let app_wrapper_for_quad = ApplicationWrapper::Sokol; - - // Compile rust code for android with quad engine - rust_compile( - &ndk, - build_target, - &project_path, - profile, - vec![], - false, - false, - target_sdk_version, - &quad_lib_name, - app_wrapper_for_quad, - ) - .unwrap(); - println!("rust was compiled for quad example"); - - // Create needed directories - let out_dir = project_path - .join("target") - .join(build_target.rust_triple()) - .join(profile.as_ref()); - let compiled_lib = out_dir.join(format!("lib{}.so", quad_package_name)); - if !out_dir.exists() { - std::fs::create_dir_all(&out_dir).unwrap(); - } - let android_build_dir = project_path - .join("target") - .join("android") - .join(&quad_package_name); - let native_build_dir = android_build_dir.join("native"); - - // Gen android manifest - let target_dir = project_path.join("target"); - let manifest = GenAndroidManifest { - package_name: quad_package_name.clone(), - version_code, - ..Default::default() - }; - let android_manifest = manifest.gen_min_android_manifest(); - let apk_build_dir = target_dir.join(&profile).join("apk"); - let manifest_path = android::save_android_manifest(&apk_build_dir, &android_manifest).unwrap(); - assert!(manifest_path.exists()); - - // Gen unaligned apk - let unaligned_apk_path = android::gen_unaligned_apk( - &sdk, - &project_path, - &native_build_dir, - &manifest_path, - None, - None, - &quad_package_name, - target_sdk_version, - ) - .unwrap(); - assert!(unaligned_apk_path.exists()); - - // Add all needed libs into apk - android::add_libs_into_apk( - &sdk, - &ndk, - &unaligned_apk_path, - &compiled_lib, - build_target, - profile, - 29, - &android_build_dir, - &target_dir, - ) - .unwrap(); - - // Align apk - let aligned_apk_path = android::align_apk( - &sdk, - &unaligned_apk_path, - &manifest.package_name, - &apk_build_dir, - ) - .unwrap(); - assert!(aligned_apk_path.exists()); - - // Removes old keystore if it exists - let android_dir = android_dir().unwrap(); - let target = vec![android_dir.join("aab.keystore")]; - remove(target).unwrap(); - - // Gen debug key for signing apk - let key = AabKey::new_default().unwrap(); - Keytool::new() - .genkeypair(true) - .v(true) - .keystore(&key.key_path) - .alias(&key.key_alias) - .keypass(&key.key_pass) - .storepass(&key.key_pass) - .dname(&["CN=Android Debug,O=Android,C=US".to_owned()]) - .keyalg(KeyAlgorithm::RSA) - .keysize(2048) - .validity(10000) - .run() - .unwrap(); - - // Sign apk - android::sign_apk(&sdk, &aligned_apk_path, key).unwrap(); -} diff --git a/crossbundle/tools/tests/gen_gradle_project.rs b/crossbundle/tools/tests/gen_gradle_project.rs deleted file mode 100644 index 429fa654..00000000 --- a/crossbundle/tools/tests/gen_gradle_project.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crossbundle_tools::{ - commands::{ - android::{self, rust_compile, GenAndroidManifest}, - gen_minimal_project, - }, - tools::{AndroidNdk, AndroidSdk}, - types::{AndroidTarget, ApplicationWrapper, IntoRustTriple, Profile}, -}; - -#[test] -pub fn test_gen_gradle_project() { - // Creates temporary directory - let tempdir = tempfile::tempdir().unwrap(); - let project_path = tempdir.path(); - - // Assigns configuration for project - let package_name = gen_minimal_project(&project_path, true).unwrap(); - - // Assign needed configuration to compile rust for android with bevy - let sdk = AndroidSdk::from_env().unwrap(); - let ndk = AndroidNdk::from_env(Some(sdk.sdk_path())).unwrap(); - let build_target = AndroidTarget::Aarch64LinuxAndroid; - let profile = Profile::Release; - let target_sdk_version = 30; - let version_code = 1_u32; - let lib_name = format!("lib{}.so", package_name.replace("-", "_")); - let app_wrapper = ApplicationWrapper::Sokol; - - let android_build_dir = project_path - .join("target") - .join("android") - .join(&package_name); - std::fs::create_dir_all(&android_build_dir).unwrap(); - - // Generate gradle project - let gradle_project_path = android::gen_gradle_project(&android_build_dir, None, None).unwrap(); - - // Generate manifest - let manifest = GenAndroidManifest { - package_name: package_name.to_string(), - version_code, - ..Default::default() - }; - let android_manifest = manifest.gen_min_android_manifest(); - let manifest_path = - android::save_android_manifest(&gradle_project_path, &android_manifest).unwrap(); - assert!(manifest_path.exists()); - - // Compile rust code for android with bevy engine - rust_compile( - &ndk, - build_target, - project_path, - profile, - vec![], - false, - false, - target_sdk_version, - &lib_name, - app_wrapper, - ) - .unwrap(); - println!("rust was compiled for example"); - - // Specifies needed directories to manage library location - let mut libs = Vec::new(); - let out_dir = project_path - .join("target") - .join(build_target.rust_triple()) - .join(profile.as_ref()); - let compiled_lib = out_dir.join(lib_name); - assert!(compiled_lib.exists()); - libs.push((compiled_lib, build_target)); - - // Adds libs into ./target/aarch64-linux-android/debug/ - for (compiled_lib, build_target) in libs { - let lib = android::add_libs_into_aapt2( - &ndk, - &compiled_lib, - build_target, - profile, - target_sdk_version, - &out_dir, - &project_path.join("target"), - &package_name, - ) - .unwrap(); - assert!(lib.exists()); - println!("library saved in {:?}", lib); - - // Check the size of the library to ensure it is not corrupted - for entry in std::fs::read_dir(&lib).unwrap() { - let library = entry.unwrap().path(); - let size = std::fs::metadata(&library).unwrap().len(); - println!("library size is {:?}", size); - } - } -} diff --git a/docs/crossbow-plugins.md b/docs/crossbow-plugins.md index 34d43069..e9bb0452 100644 --- a/docs/crossbow-plugins.md +++ b/docs/crossbow-plugins.md @@ -25,4 +25,23 @@ adb shell pm revoke adb shell pm reset-permissions adb shell pm list permission-groups adb shell pm list permissions -``` \ No newline at end of file +``` + +## Crossbow gradle + +Crossbow gradle project requires installed Gradle on your PC. Check or download it [here](https://gradle.org/). Don't forget to install `GRADLE_HOME` environment variable. + +To create a project go to the example you want to build and use the command below. The command belongs to macroquad engine examples: + +```rust +crossbundle build android --quad --gradle +``` + +By default build directory is `target/android//gradle`. You can assign your own build directory via `--export_path` flag. Go to the directory where Gradle project was built and use command below to manually install APK on the device. + +```sh +gradle installDebug +``` + +Also you can replace `build` with `run` subcommand to build and run APK on your device. To see how to set android emulator check install recommendations for [linux-android](./install-linux-android.md), +[macos-android](./install-macos-android.md), [windows-android](./install-windows-android.md).