Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 9 commits into from
Nov 13, 2024

Conversation

jkelleyrtp
Copy link
Member

@jkelleyrtp jkelleyrtp commented Nov 13, 2024

Enables android apps with any name, not just apps with a fixed name.
Does this by hardcoding the dioxus library itself and then importing ourselves into the main app.
Also now uses the bundle_identifier from the dioxus.toml instead of hardcoding things to com.dioxuslabs


For posterity, here's some code to use llvm-objcopy to rename the symbols we care about

    #[allow(dead_code)]
    async fn android_objcopy_rename(&self, source: &Path, destination: &Path) -> Result<()> {
        // gathered by `nm -g target/debug/android-final | grep dev_dioxus_main`
        let known_symbols = vec![
            "Java_dev_dioxus_main_Ipc_ipc",
            "Java_dev_dioxus_main_RustWebChromeClient_handleReceivedTitle",
            "Java_dev_dioxus_main_RustWebViewClient_assetLoaderDomain",
            "Java_dev_dioxus_main_RustWebViewClient_handleRequest",
            "Java_dev_dioxus_main_RustWebViewClient_onPageLoaded",
            "Java_dev_dioxus_main_RustWebViewClient_onPageLoading",
            "Java_dev_dioxus_main_RustWebViewClient_shouldOverride",
            "Java_dev_dioxus_main_RustWebViewClient_withAssetLoader",
            "Java_dev_dioxus_main_RustWebView_onEval",
            "Java_dev_dioxus_main_RustWebView_shouldOverride",
            "Java_dev_dioxus_main_WryActivity_create",
            "Java_dev_dioxus_main_WryActivity_destroy",
            "Java_dev_dioxus_main_WryActivity_focus",
            "Java_dev_dioxus_main_WryActivity_memory",
            "Java_dev_dioxus_main_WryActivity_pause",
            "Java_dev_dioxus_main_WryActivity_resume",
            "Java_dev_dioxus_main_WryActivity_save",
            "Java_dev_dioxus_main_WryActivity_start",
            "Java_dev_dioxus_main_WryActivity_stop",
        ];

        tracing::debug!(
            "Redefining symbols for Android linker. Source: {source:#?}, target: {destination:#?}"
        );

        // --redefine-sym=Java_dev_dioxuslabs_hardcoded_WryActivity_create=Java_com_example_DIOXUSLABS_WryActivity_create
        let redefined_org = self.build.krate.mobile_org().replace('.', '_');
        let app_name = self.build.krate.mobile_app_name();

        let res = Command::new(self.build.krate.android_llvm_objcopy().unwrap())
            .args(known_symbols.iter().map(|incoming| {
                let replaced =
                    incoming.replace("dev_dioxus_main", &format!("{redefined_org}_{app_name}"));
                let redefined = format!("--redefine-sym={incoming}={replaced}",);
                tracing::trace!("redefining symbol {incoming} to {redefined}");
                redefined
            }))
            .arg(source)
            .arg(destination)
            .stdout(std::process::Stdio::piped())
            .stderr(std::process::Stdio::piped())
            .output()
            .await?;

        if !res.stderr.is_empty() {
            tracing::error!(
                "error running llvm-objcopy {:#?}",
                str::from_utf8(&res.stderr)
            );
        }

        Ok(())
    }

    pub(crate) fn android_llvm_objcopy(&self) -> Option<PathBuf> {
        self.android_ndk().map(|ndk| {
            let toolchain_dir = ndk.join("toolchains").join("llvm").join("prebuilt");

            if cfg!(target_os = "macos") {
                // for whatever reason, even on aarch64 macos, the linker is under darwin-x86_64
                return toolchain_dir
                    .join("darwin-x86_64")
                    .join("bin")
                    .join("llvm-objcopy");
            }

            if cfg!(target_os = "windows") {
                return toolchain_dir
                    .join("windows-x86_64")
                    .join("bin")
                    .join("llvm-objcopy.cmd");
            }

            if cfg!(target_os = "linux") {
                return toolchain_dir
                    .join("linux-x86_64")
                    .join("bin")
                    .join("llvm-objcopy");
            }

            panic!("unsupported target os");
        })
    }

and the shell script that inspired it

# /Users/jonkelley/Development/Tinkering/mobile-testing/androidfinal/target/aarch64-linux-android/dioxus-android/androidfinal
    # --redefine-sym=old=new

/Users/jonkelley/Library/Android/sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objcopy \
    --redefine-sym=Java_com_example_androidfinal_WryActivity_create=Java_com_example_DIOXUSLABS_WryActivity_create \
    /Users/jonkelley/Development/Tinkering/mobile-testing/androidfinal/target/aarch64-linux-android/dioxus-android/androidfinal \
    /Users/jonkelley/Development/Tinkering/mobile-testing/androidfinal/target/aarch64-linux-android/dioxus-android/androidfinal2

nm /Users/jonkelley/Development/Tinkering/mobile-testing/androidfinal/target/aarch64-linux-android/dioxus-android/androidfinal2 | grep com_

# 00000000006ff16c T Java_com_example_androidfinal_WryActivity_create
# 00000000006ff128 T Java_com_example_androidfinal_Ipc_ipc
# 00000000006ff124 T Java_com_example_androidfinal_RustWebChromeClient_handleReceivedTitle
# 00000000006ff140 T Java_com_example_androidfinal_RustWebViewClient_assetLoaderDomain
# 00000000006ff148 T Java_com_example_androidfinal_RustWebViewClient_handleRequest
# 00000000006ff12c T Java_com_example_androidfinal_RustWebViewClient_onPageLoaded
# 00000000006ff130 T Java_com_example_androidfinal_RustWebViewClient_onPageLoading
# 00000000006ff13c T Java_com_example_androidfinal_RustWebViewClient_shouldOverride
# 00000000006ff144 T Java_com_example_androidfinal_RustWebViewClient_withAssetLoader
# 00000000006ff134 T Java_com_example_androidfinal_RustWebView_onEval
# 00000000006ff138 T Java_com_example_androidfinal_RustWebView_shouldOverride
# 00000000006ff154 T Java_com_example_androidfinal_WryActivity_destroy
# 00000000006ff14c T Java_com_example_androidfinal_WryActivity_focus
# 00000000006ff150 T Java_com_example_androidfinal_WryActivity_memory
# 00000000006ff15c T Java_com_example_androidfinal_WryActivity_pause
# 00000000006ff160 T Java_com_example_androidfinal_WryActivity_resume
# 00000000006ff158 T Java_com_example_androidfinal_WryActivity_save
# 00000000006ff168 T Java_com_example_androidfinal_WryActivity_start
# 00000000006ff164 T Java_com_example_androidfinal_WryActivity_stop

#   --redefine-sym=old=new  Change the name of a symbol old to new
#   --redefine-syms=filename
#                           Reads a list of symbol pairs from <filename> and runs as if --redefine-sym=<old>=<new> is set for each one. <filename> contains two symbols per line separated with whitespace and may contain comments beginning with '#'. Leading and trailing whitespace is stripped from each line. May be repeated to read symbols from many files.

@jkelleyrtp jkelleyrtp marked this pull request as ready for review November 13, 2024 23:28
@jkelleyrtp jkelleyrtp changed the title feat: allow android apps with any name feat: allow android apps with any name, fix android + windows for aarch64 Nov 13, 2024
@jkelleyrtp jkelleyrtp changed the title feat: allow android apps with any name, fix android + windows for aarch64 feat: allow android apps with any name, fix android + windows for aarch64 target Nov 13, 2024
@jkelleyrtp jkelleyrtp merged commit 8a2922c into main Nov 13, 2024
17 checks passed
@jkelleyrtp jkelleyrtp deleted the jk/android-any-name branch November 13, 2024 23:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant