Skip to content

Commit

Permalink
Add wry build support for android target.
Browse files Browse the repository at this point in the history
  • Loading branch information
dvc94ch committed Oct 27, 2022
1 parent 27e9490 commit b93835b
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 13 deletions.
1 change: 1 addition & 0 deletions xbuild/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ log-panics = "2.1.0"
msix = { version = "0.3.0", path = "../msix" }
mvn = { version = "0.1.0", path = "../mvn" }
path-slash = "0.2.1"
quick-xml = { version = "0.26.0", features = ["serialize"] }
reqwest = { version = "0.11.12", features = ["blocking"] }
serde = { version = "1.0.145", features = ["derive"] }
serde_json = "1.0.86"
Expand Down
9 changes: 6 additions & 3 deletions xbuild/src/command/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::download::DownloadManager;
use crate::task::TaskRunner;
use crate::{BuildEnv, Format, Opt, Platform};
use anyhow::Result;
use apk::Apk;
use appbundle::AppBundle;
use appimage::AppImage;
use msix::Msix;
Expand All @@ -27,6 +26,9 @@ pub fn build(env: &BuildEnv) -> Result<()> {
let bin_target = env.target().platform() != Platform::Android;
let has_lib = env.root_dir().join("src").join("lib.rs").exists();
if bin_target || has_lib {
if env.target().platform() == Platform::Android {
crate::wry::setup_env(&env)?;
}
for target in env.target().compile_targets() {
let arch_dir = platform_dir.join(target.arch().to_string());
let mut cargo = env.cargo_build(target, &arch_dir.join("cargo"))?;
Expand Down Expand Up @@ -66,8 +68,9 @@ pub fn build(env: &BuildEnv) -> Result<()> {
}
Platform::Android => {
let out = platform_dir.join(format!("{}.{}", env.name(), env.target().format()));
crate::wry::build_apk(env, &out)?;

let mut apk = Apk::new(
/*let mut apk = Apk::new(
out,
env.manifest().android().clone(),
env.target().opt() != Opt::Debug,
Expand All @@ -83,7 +86,7 @@ pub fn build(env: &BuildEnv) -> Result<()> {
}
}
apk.finish(env.target().signer().cloned())?;
apk.finish(env.target().signer().cloned())?;*/
}
Platform::Macos => {
let target = env.target().compile_targets().next().unwrap();
Expand Down
2 changes: 2 additions & 0 deletions xbuild/src/command/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ impl Default for Doctor {
Check::new("adb", Some(VersionCheck::new("--version", 0, 4))),
Check::new("javac", Some(VersionCheck::new("--version", 0, 1))),
Check::new("java", Some(VersionCheck::new("--version", 0, 1))),
Check::new("kotlin", Some(VersionCheck::new("-version", 0, 2))),
Check::new("gradle", Some(VersionCheck::new("--version", 2, 1))),
],
},
Group {
Expand Down
15 changes: 6 additions & 9 deletions xbuild/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{Opt, Platform};
use anyhow::Result;
use apk::manifest::{Activity, AndroidManifest, IntentFilter, MetaData};
use apk::manifest::{Activity, AndroidManifest, IntentFilter};
use apk::VersionCode;
use appbundle::InfoPlist;
use msix::AppxManifest;
Expand Down Expand Up @@ -96,8 +96,8 @@ impl Manifest {
if let Ok(code) = VersionCode::from_semver(&config.version) {
manifest.version_code.get_or_insert_with(|| code.to_code(1));
}
let target_sdk_version = 31;
let target_sdk_codename = 11;
let target_sdk_version = 33;
let target_sdk_codename = 13;
let min_sdk_version = 21;
manifest
.compile_sdk_version
Expand All @@ -122,7 +122,7 @@ impl Manifest {
application
.debuggable
.get_or_insert_with(|| opt == Opt::Debug);
application.has_code.get_or_insert(false);
application.has_code.get_or_insert(true);
if application.activities.is_empty() {
let activity = Activity {
config_changes: Some(
Expand All @@ -143,15 +143,12 @@ impl Manifest {
),
label: None,
launch_mode: Some("singleTop".into()),
name: Some("android.app.NativeActivity".into()),
name: Some(".MainActivity".into()),
orientation: None,
window_soft_input_mode: Some("adjustResize".into()),
hardware_accelerated: Some(true),
exported: Some(true),
meta_data: vec![MetaData {
name: "android.app.lib_name".into(),
value: config.name.replace('-', "_"),
}],
meta_data: vec![],
intent_filters: vec![IntentFilter {
actions: vec!["android.intent.action.MAIN".into()],
categories: vec!["android.intent.category.LAUNCHER".into()],
Expand Down
2 changes: 1 addition & 1 deletion xbuild/src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ impl<'a> DownloadManager<'a> {
pub fn android_ndk(&self) -> Result<()> {
let output = self.env.android_ndk();
let item =
WorkItem::github_release(output, "cloudpeers", "x", "v0.1.0+2", "Android.ndk.tar.zst");
WorkItem::github_release(output, "cloudpeers", "x", "v0.1.0+3", "Android.ndk.tar.zst");
self.fetch(item)
}

Expand Down
1 change: 1 addition & 0 deletions xbuild/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod config;
pub mod devices;
pub mod download;
pub mod task;
pub mod wry;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Opt {
Expand Down
10 changes: 10 additions & 0 deletions xbuild/src/wry/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.3.0' apply false
id 'com.android.library' version '7.3.0' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
}

task clean(type: Delete) {
delete rootProject.buildDir
}
21 changes: 21 additions & 0 deletions xbuild/src/wry/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
108 changes: 108 additions & 0 deletions xbuild/src/wry/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use crate::cargo::CrateType;
use crate::{task, BuildEnv};
use anyhow::Result;
use std::path::Path;
use std::process::Command;

static BUILD_GRADLE: &[u8] = include_bytes!("./build.gradle");
static GRADLE_PROPERTIES: &[u8] = include_bytes!("./gradle.properties");
static SETTINGS_GRADLE: &[u8] = include_bytes!("./settings.gradle");

pub fn setup_env(env: &BuildEnv) -> Result<()> {
let gradle = env.platform_dir().join("gradle");
let app = gradle.join("app");
let kotlin = app.join("src").join("main").join("kotlin");

let package = env.manifest().android().package.clone().unwrap_or_default();
let (package, name) = package.rsplit_once('.').unwrap();

if !kotlin.exists() {
std::fs::create_dir_all(&kotlin)?;
std::fs::write(gradle.join("build.gradle"), BUILD_GRADLE)?;
std::fs::write(gradle.join("gradle.properties"), GRADLE_PROPERTIES)?;
std::fs::write(gradle.join("settings.gradle"), SETTINGS_GRADLE)?;

let manifest = env.manifest().android();
let target_sdk = manifest.sdk.target_sdk_version.unwrap();
let min_sdk = manifest.sdk.target_sdk_version.unwrap();
let version_code = manifest.version_code.unwrap();
let version_name = manifest.version_name.as_ref().unwrap();

let app_build_gradle = format!(
r#"
plugins {{
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}}
android {{
namespace '{package}'
compileSdk {target_sdk}
defaultConfig {{
minSdk {min_sdk}
targetSdk {target_sdk}
versionCode {version_code}
versionName '{version_name}'
}}
}}
dependencies {{
implementation 'androidx.appcompat:appcompat:1.4.1'
}}
"#,
package=package,
target_sdk=target_sdk,
min_sdk=min_sdk,
version_code=version_code,
version_name=version_name,
);
std::fs::write(app.join("build.gradle"), app_build_gradle)?;

let main_activity = format!(
r#"
package {}.{}
class MainActivity : TauriActivity()
"#,
package, name
);
std::fs::write(kotlin.join("MainActivity.kt"), main_activity)?;
}

std::env::set_var("WRY_ANDROID_REVERSED_DOMAIN", package);
std::env::set_var("WRY_ANDROID_APP_NAME_SNAKE_CASE", name);
std::env::set_var("WRY_ANDROID_KOTLIN_FILES_OUT_DIR", kotlin);
Ok(())
}

pub fn build_apk(env: &BuildEnv, apk: &Path) -> Result<()> {
let platform_dir = env.platform_dir();
let gradle = platform_dir.join("gradle");
let main = gradle.join("app").join("src").join("main");
let jnilibs = main.join("jniLibs");

let manifest = env.manifest().android();
std::fs::write(
main.join("AndroidManifest.xml"),
quick_xml::se::to_string(manifest)?,
)?;

for target in env.target().compile_targets() {
let arch_dir = platform_dir.join(target.arch().to_string());
let lib = env.cargo_artefact(&arch_dir.join("cargo"), target, CrateType::Cdylib)?;
let lib_name = lib.file_name().unwrap();
let lib_dir = jnilibs.join(target.android_abi().android_abi());
std::fs::create_dir_all(&lib_dir)?;
std::fs::copy(&lib, lib_dir.join(lib_name))?;
}

let mut cmd = Command::new("gradle");
cmd.current_dir(&gradle).arg("build");
task::run(cmd, env.verbose())?;
let out = gradle
.join("app")
.join("build")
.join("outputs")
.join("apk")
.join("debug")
.join("app-debug.apk");
std::fs::copy(out, apk)?;
Ok(())
}
16 changes: 16 additions & 0 deletions xbuild/src/wry/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}

include ':app'

0 comments on commit b93835b

Please sign in to comment.