feat: allow android apps with any name, fix android + windows for aarch64 target (#3213)

* use llvm objcopy to rename syms
* use handlebars
* it works!
* remove linker code
* better docs internally about dev.dioxus.main
* use bundle identifier
* double check bundle identifier is proper
This commit is contained in:
Jonathan Kelley authored and GitHub committed 2024-11-13 18:48:21 -05:00
1 parent 1370bce182
commit 8a2922c663
13 files changed
+173 -79

No files matched your search

+15 -9
View File
@@ -347,9 +347,8 @@ impl AppBundle {
//
// todo(jon): maybe just symlink this rather than copy it?
Platform::Android => {
// https://github.com/rust-mobile/xbuild/blob/master/xbuild/template/lib.rs
// https://github.com/rust-mobile/xbuild/blob/master/apk/src/lib.rs#L19
std::fs::copy(&self.app.exe, self.main_exe())?;
self.copy_android_exe(&self.app.exe, &self.main_exe())
.await?;
}
// These are all super simple, just copy the exe into the folder
@@ -703,10 +702,6 @@ impl AppBundle {
Ok(())
}
pub(crate) fn bundle_identifier(&self) -> String {
format!("com.dioxuslabs.{}", self.build.krate.executable_name())
}
fn macos_plist_contents(&self) -> Result<String> {
handlebars::Handlebars::new()
.render_template(
@@ -715,7 +710,7 @@ impl AppBundle {
display_name: self.build.platform_exe_name(),
bundle_name: self.build.platform_exe_name(),
executable_name: self.build.platform_exe_name(),
bundle_identifier: format!("com.dioxuslabs.{}", self.build.platform_exe_name()),
bundle_identifier: self.build.krate.bundle_identifier(),
},
)
.map_err(|e| e.into())
@@ -729,7 +724,7 @@ impl AppBundle {
display_name: self.build.platform_exe_name(),
bundle_name: self.build.platform_exe_name(),
executable_name: self.build.platform_exe_name(),
bundle_identifier: format!("com.dioxuslabs.{}", self.build.platform_exe_name()),
bundle_identifier: self.build.krate.bundle_identifier(),
},
)
.map_err(|e| e.into())
@@ -774,4 +769,15 @@ impl AppBundle {
.join("debug")
.join("app-debug.apk")
}
/// Copy the Android executable to the target directory, and rename the hardcoded com_hardcoded_dioxuslabs entries
/// to the user's app name.
async fn copy_android_exe(&self, source: &Path, destination: &Path) -> Result<()> {
// we might want to eventually use the objcopy logic to handle this
//
// https://github.com/rust-mobile/xbuild/blob/master/xbuild/template/lib.rs
// https://github.com/rust-mobile/xbuild/blob/master/apk/src/lib.rs#L19
std::fs::copy(source, destination)?;
Ok(())
}
}
+57 -23
View File
@@ -307,6 +307,7 @@ impl BuildRequest {
pub(crate) fn android_rust_flags(&self) -> String {
let mut rust_flags = std::env::var("RUSTFLAGS").unwrap_or_default();
// todo(jon): maybe we can make the symbol aliasing logic here instead of using llvm-objcopy
if self.build.platform() == Platform::Android {
let cur_exe = std::env::current_exe().unwrap();
rust_flags.push_str(format!(" -Clinker={}", cur_exe.display()).as_str());
@@ -456,19 +457,13 @@ impl BuildRequest {
let mut env_vars = vec![];
if self.build.platform() == Platform::Android {
let app = self.root_dir().join("app");
let app_main = app.join("src").join("main");
let app_kotlin = app_main.join("kotlin");
let app_kotlin_out = app_kotlin.join("com").join("example").join("androidfinal");
env_vars.push((
"WRY_ANDROID_PACKAGE",
"com.example.androidfinal".to_string(),
));
env_vars.push(("WRY_ANDROID_LIBRARY", "androidfinal".to_string()));
env_vars.push(("WRY_ANDROID_PACKAGE", "dev.dioxus.main".to_string()));
env_vars.push(("WRY_ANDROID_LIBRARY", "dioxusmain".to_string()));
env_vars.push((
"WRY_ANDROID_KOTLIN_FILES_OUT_DIR",
app_kotlin_out.display().to_string(),
self.wry_android_kotlin_files_out_dir()
.display()
.to_string(),
));
env_vars.push(("RUSTFLAGS", self.android_rust_flags()))
@@ -619,8 +614,10 @@ impl BuildRequest {
Platform::Liveview => self.krate.executable_name().to_string(),
Platform::Windows => format!("{}.exe", self.krate.executable_name()),
// from the apk spec, the root exe will actually be a shared library
Platform::Android => format!("lib{}.so", self.krate.executable_name()),
// from the apk spec, the root exe is a shared library
// we include the user's rust code as a shared library with a fixed namespacea
Platform::Android => "libdioxusmain.so".to_string(),
Platform::Web => unimplemented!("there's no main exe on web"), // this will be wrong, I think, but not important?
// todo: maybe this should be called AppRun?
@@ -643,7 +640,7 @@ impl BuildRequest {
let app_kotlin = app_main.join("kotlin");
let app_jnilibs = app_main.join("jniLibs");
let app_assets = app_main.join("assets");
let app_kotlin_out = app_kotlin.join("com").join("example").join("androidfinal");
let app_kotlin_out = self.wry_android_kotlin_files_out_dir();
create_dir_all(&app)?;
create_dir_all(&app_main)?;
create_dir_all(&app_kotlin)?;
@@ -657,6 +654,18 @@ impl BuildRequest {
tracing::debug!("Initialized app/src/assets: {:?}", app_assets);
tracing::debug!("Initialized app/src/kotlin/main: {:?}", app_kotlin_out);
// handlerbars
let hbs = handlebars::Handlebars::new();
#[derive(serde::Serialize)]
struct HbsTypes {
application_id: String,
app_name: String,
}
let hbs_data = HbsTypes {
application_id: self.krate.full_mobile_app_name(),
app_name: self.krate.mobile_app_name(),
};
// Top-level gradle config
write(
root.join("build.gradle.kts"),
@@ -692,7 +701,10 @@ impl BuildRequest {
// Now the app directory
write(
app.join("build.gradle.kts"),
include_bytes!("../../assets/android/gen/app/build.gradle.kts"),
hbs.render_template(
include_str!("../../assets/android/gen/app/build.gradle.kts.hbs"),
&hbs_data,
)?,
)?;
write(
app.join("proguard-rules.pro"),
@@ -700,18 +712,20 @@ impl BuildRequest {
)?;
write(
app.join("src").join("main").join("AndroidManifest.xml"),
include_bytes!("../../assets/android/gen/app/src/main/AndroidManifest.xml"),
hbs.render_template(
include_str!("../../assets/android/gen/app/src/main/AndroidManifest.xml.hbs"),
&hbs_data,
)?,
)?;
// Write the main activity manually since tao dropped support for it
write(
app_main
.join("kotlin")
.join("com")
.join("example")
.join("androidfinal")
self.wry_android_kotlin_files_out_dir()
.join("MainActivity.kt"),
include_bytes!("../../assets/android/MainActivity.kt"),
hbs.render_template(
include_str!("../../assets/android/MainActivity.kt.hbs"),
&hbs_data,
)?,
)?;
// Write the res folder
@@ -720,7 +734,10 @@ impl BuildRequest {
create_dir_all(res.join("values"))?;
write(
res.join("values").join("strings.xml"),
include_bytes!("../../assets/android/gen/app/src/main/res/values/strings.xml"),
hbs.render_template(
include_str!("../../assets/android/gen/app/src/main/res/values/strings.xml.hbs"),
&hbs_data,
)?,
)?;
write(
res.join("values").join("colors.xml"),
@@ -790,4 +807,21 @@ impl BuildRequest {
Ok(())
}
pub(crate) fn wry_android_kotlin_files_out_dir(&self) -> PathBuf {
let mut kotlin_dir = self
.root_dir()
.join("app")
.join("src")
.join("main")
.join("kotlin");
for segment in "dev.dioxus.main".split('.') {
kotlin_dir = kotlin_dir.join(segment);
}
tracing::debug!("app_kotlin_out: {:?}", kotlin_dir);
kotlin_dir
}
}