Binary still not working even when properly patchelfed

I have this binary and I have the needed libraries symlinked in a folder that is in the binary’s rpath:

However, I still get


This is the Linux version of

When running file on the executable:

Mobility: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/, for GNU/Linux 2.6.24, BuildID[sha1]=31f3777c46fd8bc6240555e8268f7f43767b9132, stripped

However, you’re patchelfing it with 64bit shared libraries here.

Here is a small example on how a Nix expression for this might look like (using autoPatchelfHook):

with import <nixpkgs> { system = "i686-linux"; };

stdenv.mkDerivation {
  name = "mobility";

  src = /path/to/Mobility-linux-tar.tar.gz;
  sourceRoot = "opt";

  nativeBuildInputs = [ autoPatchelfHook ];
  buildInputs = [
    libGL libGLU openssl openal zlib xlibs.libXrandr xlibs.libXxf86vm

  installPhase = "cp -r . \"$out\"";

I haven’t tested actually running the game, but this should hopefully help you to get you started without the need to patchelf (or update your symlinks) again after the next Nix store garbage collection.

Note that without overriding system as in the example,autoPatchelfHook will set the interpreter to whatever is in $NIX_CC/nix-support/dynamic-linker, which will be the 64-bit regardless of multilib support. So even using stdenv_32bit or multiStdenv to build the package will result in this issue.

I’m working on a patch for autoPatchelfHook to use the correct linker (${}/nix-support/dynamic-linker-m32) when patching an ELF32 executable on a 64-bit system. I wish this was baked in a little cleaner in the underlying layers; you can use binutils.dynamicLinker anywhere, but there is no equivalent for the multilib linker.