cargo-mobile2 does not support cargo workspaces
neupsh opened this issue · 2 comments
Describe the bug
Cargo mobile does not support cargo workspaces. If I create a mobile project under a workspace, it fails to build as it cannot find built shared libraries under <android project>/target/
. When you use workspace, those files are all under the <workspace-dir>/target
instead of under each member project inside the workspace.
Steps To Reproduce
- Create a workspace directory (
mkdir parent
) and add aCargo.toml
with the following contents:
[workspace]
members = ["dioxus-mobile-test"]
- create member project for android:
mkdir -p dioxus-mobile-test
and cd into it:cd dioxus-mobile-test
- Run
cargo mobile init
in there and use default values, selectwry
template and let it complete successfully. - Update the Cargo.toml for this project with the following. (Note I ran into linker issue when I tried to just run the default wry template. The following instructions are from dioxus mobile setup)
[dependencies]
anyhow = "1.0.56"
log = "0.4.11"
dioxus = { version = "0.5", features = ["mobile"] }
wry = "0.35.0"
tao = "0.25.0"
- Update the
src/lib.rs
with the following:
src/lib.rs
use anyhow::Result;
use dioxus::prelude::*;
#[cfg(target_os = "android")]
fn init_logging() {
android_logger::init_once(
android_logger::Config::default()
.with_max_level(log::LevelFilter::Trace)
);
}
#[cfg(not(target_os = "android"))]
fn init_logging() {
env_logger::init();
}
#[cfg(any(target_os = "android", target_os = "ios"))]
fn stop_unwind<F: FnOnce() -> T, T>(f: F) -> T {
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
Ok(t) => t,
Err(err) => {
eprintln!("attempt to unwind out of `rust` with err: {:?}", err);
std::process::abort()
}
}
}
#[no_mangle]
#[inline(never)]
#[cfg(any(target_os = "android", target_os = "ios"))]
pub extern "C" fn start_app() {
fn _start_app() {
stop_unwind(|| main().unwrap());
}
#[cfg(target_os = "android")]
{
tao::android_binding!(
com_example,
dioxus_mobile_test,
WryActivity,
wry::android_setup, // pass the wry::android_setup function to tao which will invoke when the event loop is created
_start_app
);
wry::android_binding!(com_example, dioxus_mobile_test);
}
#[cfg(target_os = "ios")]
_start_app()
}
pub fn main() -> Result<()> {
init_logging();
launch(app);
Ok(())
}
fn app() -> Element {
let mut items = use_signal(|| vec![1, 2, 3]);
log::debug!("Hello from the app");
rsx! {
div {
h1 { "Hello, Mobile"}
div { margin_left: "auto", margin_right: "auto", width: "200px", padding: "10px", border: "1px solid black",
button {
onclick: move|_| {
println!("Clicked!");
let mut items_mut = items.write();
let new_item = items_mut.len() + 1;
items_mut.push(new_item);
println!("Requested update");
},
"Add item"
}
for item in items.read().iter() {
div { "- {item}" }
}
}
}
}
}
- Run
cargo android build
- It fails as it expects to link artifacts fromparent/dioxus-mobile-test/target/
instead of theparent/target/
directory which is where they are present when using cargo workspace feature.
Finished dev [unoptimized + debuginfo] target(s) in 1m 09s
error: Failed to symlink lib
Library artifact not found at /tmp/parent/dioxus-mobile-test/target/aarch64-linux-android/debug/libdioxus_mobile_test.so. Make sure your Cargo.toml file has a [lib] block with `crate-type = ["staticlib", "cdylib",
"rlib"]`
Expected behavior
Android build is successful.
Platform and Versions (please complete the following information):
Host OS: archlinux
Target OS: android (aarch64-linux-android)
Rustc: rustc 1.77.2 (25ef9e3d8 2024-04-09)
Ouput of cargo mobile doctor
:
[!] cargo-mobile v0.11.1
• Contains commits up to "chore(deps): update to windows-rs 0.56 and other deps (#305)\n"
• Installed at "~/.cargo/.cargo-mobile2"
✗ Failed to get OS info: Failed to find `VERSION` in "/etc/os-release": "NAME=\"Arch Linux\"\nPRETTY_NAME=\"Arch Linux\"\nID=arch\nBUILD_ID=rolling\nANSI_COLOR=\"38;2;23;147;209\"\nHOME_URL=\"https://archlinux.org/
\"\nDOCUMENTATION_URL=\"https://wiki.archlinux.org/\"\nSUPPORT_URL=\"https://bbs.archlinux.org/\"\nBUG_REPORT_URL=\"https://gitlab.archlinux.org/groups/archlinux/-/issues\"\nPRIVACY_POLICY_URL=\"https://
terms.archlinux.org/docs/privacy-policy/\"\nLOGO=archlinux-logo\n"
• rustc v1.77.2 (25ef9e3d8 2024-4-9)
[✔] Android developer tools
• SDK v26.1.1 installed at "~/Android/Sdk"
• NDK v27.0.11718014-beta1 installed at "~/Android/Sdk/ndk/latest"
[✔] Connected devices
• No connected devices were found
Other notes
If you rename the parent Cargo.toml
to Cargo.toml.backup
and try to build the dioxus-mobile-test
project again, it works without error, as it builds the artifacts inside the dioxus-mobile-test/target
directory and expects them there.
Would be interested to know if there are any workarounds until this is resolved as well. Thank you.
Got one workaround: you can pass the target directory of workspace and it builds successfully:
CARGO_TARGET_DIR="../target" cargo android build
Perhaps there is a way to add one more else condition here to check for workspace and add workspace target directory if the CARGO_TARGET_DIR is not set. I wonder if there is a way to get the target directory from cargo itself.
Either use CARGO_TARGET_DIR
or set target-dir
in .cargo/config.toml
of your crate.