dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

For bundling, desktop apps should canonicalize assets automatically.

Open jkelleyrtp opened this issue 3 years ago • 10 comments

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.

  • [x] macOS

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

  • [ ] windows
  • [ ] linux (rpm)
  • [ ] linux (deb)

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.

jkelleyrtp avatar Feb 11 '22 20:02 jkelleyrtp

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.

autarch avatar Feb 11 '22 22:02 autarch

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.

jkelleyrtp avatar Feb 12 '22 14:02 jkelleyrtp

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.

autarch avatar Feb 12 '22 16:02 autarch

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

jkelleyrtp avatar Feb 12 '22 17:02 jkelleyrtp

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

jkelleyrtp avatar Feb 23 '22 20:02 jkelleyrtp

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

cxgreat2014 avatar Mar 25 '22 04:03 cxgreat2014

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

ealmloff avatar Mar 13 '23 20:03 ealmloff

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 avatar Sep 13 '23 23:09 jrouaix

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

jrouaix avatar Sep 14 '23 07:09 jrouaix

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

ealmloff avatar Sep 14 '23 13:09 ealmloff