ralismark / nix-appimage

Convert a nixos derivation into a self-contained binary
MIT License
148 stars 17 forks source link

Does this solve the issues with OpenGL? #5

Closed arximboldi closed 2 weeks ago

arximboldi commented 1 year ago

This looks very promising. Have been looking for ages for a solution to generate working for generating appimage applications for OpenGL applications. nix-bundle has issues with it all attempts to find a workaround (documented in that thread and related PRs) have failed for me.

This project, due to it's ability to not bring glibc, looks promising. However since it doesn't include a desktop file, maybe it is not intended to fix the OpenGL issue? Is this supported or part of the road-map?

arximboldi commented 1 year ago

I gave this a try today. When I try to run the generated image on NixOS I get an error:

$ appimage-run myapp-x86_64.AppImage 
Unsupported AppImage Type: 32
ralismark commented 1 year ago

Hi, the Unsupported AppImage Type is an error with this project that I've fixed with https://github.com/ralismark/nix-appimage/commit/9f2cace67953e650914157108420c58eece060c8 -- thanks for letting me know!

Regarding OpenGL, this doesn't do anything special to make those apps work on non-NixOS. So you'll still need to use e.g. nixGL. I don't currently have plans to address the issue with this project, since I feel it's a bit out of scope.

arximboldi commented 1 year ago

Hi @ralismark: sorry for the late reply but I think it is sadly it should be within the scope of the project, as it is not possible to use nixGL on the foreign system where the appimage is run (onless of course they have Nix, but that defeats the purpose of distributing an appimage).

athre0z commented 9 months ago

If your application links against libgl.so dynamically with dlopen, I seem to have found a reasonable workaround. The approach can probably also be adapted for regular (non-dlopen) dynamic linking if you strip Nix's libGL from your application's RPATH, or not include it during build in the first place.

Some context first: Nix's glibc is patched in a way that it will not load its config from /etc/ld.so.conf. That is where traditional distros configure their library load paths. Nix does this to ensure that it doesn't accidentally end up loading distro libraries in non-NixOS environments. However, in the case of a portable AppImage where we want to load the distro's OpenGL library, this works against us.

Fortunately, there's a simple workaround: a wrapper script that sets LD_LIBRARY_PATH in a way that still prefers libraries from Nix' system search path, but allows fallback to distros paths. I determined the Nix system paths by running ld.so --help on a NixOS box and looking at the section where it lists load paths.

An example for such a wrapper could look like this:

appImageLibDirs = [
  # Nix system paths
  "${pkgs.glibc}/lib"
  "${pkgs.stdenv.cc.libc.libgcc.libgcc}/lib"

  # Distro library paths
  "/usr/lib/${system}-gnu"  # Debian, Ubuntu
  "/usr/lib"                # Arch, Alpine
  "/usr/lib64"              # Fedora
];
appImageWrapper = pkgs.writeShellScriptBin "myapp-appimage" ''
  export LD_LIBRARY_PATH=${lib.concatStringsSep ":" appImageLibDirs}
  ${lib.getExe myapp} "$@"
'';

As you can see, this currently simply hard-codes the library paths for some common distros. Optimally we'd either:

Maybe there is a way to tell ld.so to load a second config from a path without patching, but I'm not aware of it.

ralismark commented 8 months ago

for the record, the main issue discussing this problem is

alas it seems kinda stalled, and i don't really have the time to contribute to working on that