Trouble packaging Everspace (proprietary game)

I’m trying to package Everspace. Partly so I can play it myself, but also to learn more about nix.

This is what I have so far:

{
  # Packaging Dependencies
  lib, stdenv, requireFile, autoPatchelfHook, unzip, makeWrapper,
    
  # Everspace Dependencies
  libGL, openal, samba
}:
 
stdenv.mkDerivation {
  pname = "everspace";
  version = "1.3.5.3655";

  src = requireFile {
    name = "everspace_1_3_5_3655_32896.sh";
    url = "https://www.gog.com/";
    sha256 = "0jlvxq14k1pxmbr08y8kar0ijlqxcnkfqlvw883j96v9zr34ynj3";
  };

  nativeBuildInputs = [
    autoPatchelfHook
    makeWrapper
    unzip
  ];

  buildInputs = [
    openal
    samba
    stdenv.cc.cc.lib
  ];
    
  runtimeDependencies = [
    libGL
  ];

  # TODO: Do we even need this if we have specified these as runtime dependencies?
  autoPatchelfIgnoreMissingDeps = [
    "libGL.so.1"
    "libEGL.so.1"
  ];

  unpackPhase = ''
    runHook preUnpack

    # The shell script contains a zip file. Unzipping it works but will result
    # in some error output and an error exit code.
    unzip "$src" || true

    runHook postUnpack
  '';
  
  dontPatch = true;
  dontConfigure = true;
  dontBuild = true;

  installPhase = ''
    runHook preInstall

    mkdir -p "$out/opt"
    cp -r "./data/noarch" "$out/opt/everspace"

    mkdir -p "$out/bin"

    # TODO: Figure out whether we even need to wrap this.
    makeWrapper "$out/opt/everspace/start.sh" "$out/bin/everspace" --chdir "$out/opt/everspace"

    runHook postInstall
  '';

  # TODO: Add meta.
}

This fails at because “auto-patchelf failed to find all the required dependencies.” The dependencies in question appear to be the following:

  • libauthkrb5.so.0
  • libCHARSET3.so.0
  • libcliauth.so.0
  • libcli-ldap-common.so.0
  • libcli-smb-common.so.0
  • libdbwrap.so.0
  • libdcerpc-samba.so.0
  • libgenrand.so.0
  • libgse.so.0
  • libinterfaces.so.0
  • libiov-buf.so.0
  • libkrb5samba.so.0
  • libldbsamba.so.0
  • liblibcli-lsa3.so.0
  • liblibsmb.so.0
  • libmessages-dgm.so.0
  • libmessages-util.so.0
  • libmsrpc3.so.0
  • libsamba3-util.so.0
  • libsamba-debug.so.0
  • libsamba-security.so.0
  • libsamba-sockets.so.0
  • libsamdb-common.so.0
  • libsecrets3.so.0
  • libserver-id-db.so.0
  • libserver-role.so.0
  • libsmbd-shim.so.0
  • libsmbregistry.so.0
  • libsmb-transport.so.0
  • libsocket-blocking.so.0
  • libsys-rw.so.0
  • libtalloc-report.so.0
  • libtdb-wrap.so.0
  • libtime-basic.so.0
  • libutil-cmdline.so.0
  • libutil-reg.so.0
  • libutil-setid.so.0
  • libutil-tdb.so.0
  • libwinbind-client.so.0

Using nix-locate didn’t get me anywhere but most of these appear to be some kind of samba libs. For example, libsecrets3.so.0 is nowhere to be found but the samba package provides libsecrets3-samba4.so.

What exactly does this mean and where should I go from here? Am I even on the right track or should I go about this in an entirely different way?

Would appreciate feedback and/or pointers. Thanks!

have you tired this?

sometimes it works!

sometimes it doesn’t!

wrapping it with steam-run should fix your issue, but it’s not very clean…

Thanks for the idea! I gave it a go and it did sorta launch but immediately crashed, like this:

4.17.2-0+++UE4+Release-4.17 513 0
Disabling core dumps.
LowLevelFatalError [File:/mnt/SSD/Jenkins/workspace/RSG_Linux_GOG/Engine/Engine/Source/Runtime/Core/Private/Linux/LinuxPlatformMisc.cpp] [Line: 642] 
Error Presenting MessageBox: No message system available

Signal 11 caught.
Malloc Size=131076 LargeMemoryPoolOffset=131092 
CommonLinuxCrashHandler: Signal=11
Malloc Size=65535 LargeMemoryPoolOffset=196655 
Engine crash handling finished; re-raising signal 11 for the default handler. Good bye.
[1]    93550 segmentation fault (core dumped)   RSG-Linux-Shipping

I think this is because certain dependencies are dynamically loaded at run time. nix-alien probably cannot detect these.

I’ll remember this program for the future though.

By the way: Do you know why it’s not in nixpkgs?

Thanks! I tried that but it failed:

$ steam-run RSG-Linux-Shipping 
/nix/store/sn1746dc6yrdfn6hsn23ridknvk62bcz-steam-run: line 16: exec: RSG-Linux-Shipping: not found

Seems the environment does not provide everything that is required.

you certainly want to run unzip on the installer sh file, and use steam-run on the start.sh found in the extracted directory

I was able to get something up and running with this:

{
  # Packaging Dependencies
  lib, stdenv, requireFile, autoPatchelfHook, unzip,
    
  # Everspace Dependencies
  cairo, gdk-pixbuf, gnome2, gtk2-x11, libGL, openal,

  # Unreal Engine 4 Dependencies
  xorg
}:

# Known issues:
# - Video playback (upon starting a new game) does not work (screen is black)
stdenv.mkDerivation {
  pname = "everspace";
  version = "1.3.5.3655";

  src = requireFile {
    name = "everspace_1_3_5_3655_32896.sh";
    url = "https://www.gog.com/";
    sha256 = "0jlvxq14k1pxmbr08y8kar0ijlqxcnkfqlvw883j96v9zr34ynj3";
  };

  nativeBuildInputs = [
    autoPatchelfHook
    unzip
  ];

  buildInputs = [
    cairo
    gdk-pixbuf
    gnome2.pango
    gtk2-x11
    openal
    stdenv.cc.cc.lib
  ];
    
  runtimeDependencies = [
    libGL

    # ue4
    xorg.libX11
    xorg.libXScrnSaver
    xorg.libXau
    xorg.libXcursor
    xorg.libXext
    xorg.libXfixes
    xorg.libXi
    xorg.libXrandr
    xorg.libXrender
    xorg.libXxf86vm
    xorg.libxcb
  ];

  unpackPhase = ''
    runHook preUnpack

    # The shell script contains a zip file. Unzipping it works but will result
    # in some error output and an error exit code.
    unzip "$src" || true

    runHook postUnpack
  '';
  
  patchPhase = ''
    runHook prePatch
    
    ## Remove Bundled Libs ##
    
    # vlc libs
    #
    # TODO: This is probably what breaks video playback. It would be cleaner
    #   to remove the bundled libs and replace them with system libs but there
    #   are so many. Copy-pasting the list from the vlc package is a good start
    #   but still leaves us with many unresolved dependencies.
    rm -rf ./data/noarch/game/RSG/Plugins/VlcMedia

    # openal
    rm -rf ./data/noarch/game/Engine/Binaries/ThirdParty/OpenAL
    
    runHook postPatch
  '';

  dontConfigure = true;
  dontBuild = true;

  installPhase = ''
    runHook preInstall

    mkdir -p "$out/opt"
    cp -r "./data/noarch" "$out/opt/everspace"

    mkdir -p "$out/bin"
    ln -s "$out/opt/everspace/game/RSG/Binaries/Linux/RSG-Linux-Shipping" "$out/bin/everspace"

    runHook postInstall
  '';

  # TODO: Add meta.
}

Turns out the missing files used to be part of samba but were renamed at some point (thanks to @Sandro for pointing that out).

Anyway, the samba libs are actually a VLC dependency. The game uses some kind of VLC plugin (presumably for video playback). I was able to just delete the entire plugin without breaking the game. There is a kind of intro that now just shows a black screen with some subtitles but it doesn’t appear to be anything game breaking.

To get things working I also needed additional libs that are loaded at runtime. I copy-pasted them from the ue4 package, since Everspace is an Unreal Engine 4 game.

Figuring all this out took a really long time but I learned a lot in the process and hope to be able to package more games like this in the future.

Oh yeah. That attempt was with the binary that ends up getting run after a few levels of indirection.

You’re right that I should include all the wrapper scripts when using steam-run. Here’s what that looks like:

$ steam-run ./start.sh
Running EVERSPACE™
Inconsistency detected by ld.so: dl-call-libc-early-init.c: 37: _dl_call_libc_early_init: Assertion `sym != NULL' failed!

You don’t want to overwrite patchPhase because it breaks patches. Always use postPatch

Ah ok. I’ll change that.