I’m looking into packaging Daggerfall Unity. Despite technically being an open-source project, it does run on the proprietary Unity engine, so building the project from source is not a real possibility here.
The Unity player doesn’t seem to rely on anything strange in terms of shared libraries, I only noticed one of the native Mono libraries relying on zlib
:
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libMonoPosixHelper.so]
Other than that, nothing out of the ordinary, so I tried going through the usual motions one would go through when trying to package a binary, aka, just use autoPatchelfHook
, which results in
{ stdenv
, lib
, fetchzip
, autoPatchelfHook
, zlib
}:
stdenv.mkDerivation rec {
pname = "daggerfall-unity";
version = "0.14.5";
src = fetchzip {
url = "https://github.com/Interkarma/daggerfall-unity/releases/download/v0.14.5-beta/dfu_linux_64bit-v${version}-beta.zip";
sha256 = "8OXIzkyVZgSbDtcB+BreFSHNJqTKP2kNRWgibWwwZtc=";
stripRoot = false;
};
nativeBuildInputs = [
autoPatchelfHook
];
buildInputs = [
zlib
];
sourceRoot = ".";
installPhase = ''
mkdir -p "$out/bin"
cp -R source/* "$out/bin"
'';
}
This of course builds just fine, and patches the zlib path. Trying to run the built package, however, does nothing.
With a quick strace, we can see that, at runtime, the process is trying to open several Xorg libraries:
Openat(AT_FDCWD, "/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libX11.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libXext.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libXcursor.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libXinerama.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libXi.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libXrandr.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libXss.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libXxf86vm.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
What I don’t understand is why it ends up looking for those libraries in the glibc
store path? Is that the result of patchelf doing something strange?
Using LD_DEBUG=libs ./result/bin/DaggerfallUnity.x86_64
shows that indeed the libraries are searched but never initialized:
37375: find library=libX11.so.6 [0]; searching
37375: search cache=/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/etc/ld.so.cache
37375: search path=/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib (system search path)
37375: trying file=/nix/store/hsk71z8admvgykn7vzjy11dfnar9f4r1-glibc-2.35-163/lib/libX11.so.6
Etc. etc.
I’m also curious as to why the glibc
store path is listed as the “system search path”?
Is there a way to work around this issue? I know using something like steam-run
would probably take care of this issue, but I’m curious as to how to solve this issue, and having steam-run
as a dependency when trying to package something doesn’t quite seem like the right approach.