DioxusLabs / dioxus

Fullstack app framework for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
20.15k stars 772 forks source link

For bundling, desktop apps should canonicalize assets automatically. #232

Open jkelleyrtp opened 2 years ago

jkelleyrtp commented 2 years ago

Specific Demand

When resolving assets, we should determine of the current program is contained within a bundle. If it is, then we should cananocalize the asset differently to be relative to the .app/.deb/.rpm/.exe for a smoother distribution experience.

These targets do not provide a straightforward way of bundling assets. I've opted to make it the asset dir configurable instead.

Implement Suggestion

https://github.com/burtonageo/cargo-bundle/pull/93/files

For macos:


        // TODO: support for other platforms
         #[cfg(target_os = "macos")]
         {
             let bundle = core_foundation::bundle::CFBundle::main_bundle();
             let bundle_path = bundle.path()?;
             let resources_path = bundle.resources_path()?;
             let absolute_resources_root = bundle_path.join(resources_path);
             let canonical_resources_root = dunce::canonicalize(absolute_resources_root).ok()?;
             Some(canonical_resources_root)
         }

I have yet to figure out linux or windows ways of doing this.

autarch commented 2 years ago

At least on Linux, we shouldn't expect assets like images to share a root with the executable. That may be the case in some packaging scenarios, but a typical apt package will have images somewhere like /usr/share/myapp and the application itself at /usr/bin/myapp.

If the goal is to support single-file distributions, then there are probably ways to compile the assets into the executable itself. Maybe Dioxus could offer support for accessing those assets for desktop apps.

jkelleyrtp commented 2 years ago

Is there a way to get the directory for Linux assets? So installed packages know where they're being launched from? Im sure a crate like bevy has figured this out.

autarch commented 2 years ago

For regular packages, there are things like the Debian Filesystem Hierarchy Standard. There's one for Fedora, too.

I looked for crates that might help with this but I only found crates that abstract per-user directories across operating systems. I didn't find any that do the same for system directories.

I dug into Bevy a bit to see how it handles it, but I think it does some sort of bundling for distribution, so that you don't have to deal with the FHS at all. Nothing in the docs talks about handling things like the FHS.

jkelleyrtp commented 2 years ago

We should optimize for the case of cargo-bundle - and I'm not entirely sure how their resources system works.

jkelleyrtp commented 2 years ago

Okay so cargo bundle is broken on windows.... Sounds like we have to fix cargo bundle first. Seems like people use cargo-wix for windows. Still not sure what it is for linux.

278

If we ever get some money to put towards hiring people, then maybe we should focus on resolving assets. Or somehow merge our desktop efforts into Tauri.

https://tauri.studio/docs/distribution/publishing

cxgreat2014 commented 2 years ago

Maybe here can help this issue: https://github.com/tauri-apps/tauri/tree/4c84559e1f3019e7aa2666b10a1a0bd97bb09d24/tooling/bundler/src/bundle

ealmloff commented 1 year ago

https://github.com/DioxusLabs/cli/pull/118 should fix this issue on windows. It uses Tauri's bundler. We need to test this on MacOS, and Linux

jrouaix commented 12 months ago

Well, it does not seems to work for linux right now, for example :

fn main() -> anyhow::Result<()> {
  // Dioxus setup
  let config = dioxus_desktop::Config::new()
    .with_custom_head(r#"<link rel="stylesheet" href="public/main.css">"#.to_string());

  dioxus_desktop::launch_cfg(app::App, config);

  Ok(())
}

when I launch the app with dx serve --hot-reload --platform desktop the style is applied, no problem.

Then I bundle the app with dx bundle --release the css file will be install in some /usr/lib/... fodler.

Then the css is not found anymore (same for .dev and .AppImage)

jrouaix commented 12 months ago

So, it's magically working when I change the resource file path at runtime, depending on the environment using tauri-utils, something like this :

  let env = Env::default();
  let package_infos = PackageInfo {
    name: env!("CARGO_PKG_NAME").into(),
    version: env!("CARGO_PKG_VERSION").parse()?,
    authors: env!("CARGO_PKG_AUTHORS"),
    description: env!("CARGO_PKG_DESCRIPTION"),
  };
fn get_resource_path(bundle_path: &str, infos: &PackageInfo, env: &Env) -> Result<String, tauri_utils::Error> {
  #[cfg(debug_assertions)]
  {
    let (_ignored1, _ignored2) = (infos, env);
    Ok(bundle_path.to_string())
  }
  #[cfg(not(debug_assertions))]
  {
    let resource_dir = dbg!(tauri_utils::platform::resource_dir(infos, env)?);
    let resource_path = dbg!(resource_dir.join(bundle_path));
    return dbg!(Ok(resource_path.to_string_lossy().to_string()));
  }
}

Ubviously, the debug/not(debug) is a little crappy but for now, it'll do the trick

ealmloff commented 12 months ago

You can check the CARGO environment variable to see if the program is currently being run by cargo. We should integrate that into this code: https://github.com/DioxusLabs/dioxus/blob/master/packages/desktop/src/protocol.rs#L122 to get the asset root