Help with packaging a binary and patchelf

Hi all. I’m trying to pull a derivation together for a non-NixOS binary program (VESTA, a virtual molecule visualizer), mostly by following the guide here, using patchelf to resolve library paths, which is failing to locate a library that seems to be available. This is my first attempt at packaging, so I’m probably doing something stupid. Here’s my default.nix:

{ stdenv, fontconfig, lib, gdk-pixbuf, openjdk, gtk2, gtk3, iconv,    
  libGLU, libGL, libglvnd, pango, xorg, glib, glibc, gcc-unwrapped,
  cairo, makeWrapper, fetchurl, autoPatchelfHook }:
stdenv.mkDerivation rec {
  name = "VESTA-gtk3";
  version = "3.5.8";

  src = fetchurl {
    url = "https://jp-minerals.org/vesta/archives/${version}/VESTA-gtk3.tar.bz2";
    sha256 = "sha256-eL7wJcKzHx1kycfgatKxOdJSs6aGiT7nmsdLMCGGjfg=";
  };

  nativeBuildInputs = [
    autoPatchelfHook
    fontconfig.lib
    gcc-unwrapped.lib
    gcc-unwrapped.libgcc 
    gdk-pixbuf 
    glib
    gtk2 
    gtk3 
    iconv 
    libGLU 
    libglvnd 
    pango 
    xorg.libX11 
    xorg.libXxf86vm
    xorg.libXtst
    openjdk
  ];

  dontConfigure = true;
  dontBuild = true;

  installPhase = ''
    mkdir $out
    cp -ar * $out
  '';

  preFixup = let
    libPath = lib.makeLibraryPath [ cairo
      fontconfig.lib 
      gcc-unwrapped.lib 
      gcc-unwrapped.libgcc 
      gdk-pixbuf     
      glib
      gtk2           
      gtk3           
      iconv          
      libGLU         
      libglvnd       
      pango          
      xorg.libX11    
      xorg.libXxf86vm
      xorg.libXtst
      openjdk
    ];
  in ''
    patchelf \
      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
      --set-rpath "${libPath}" \
      $out/VESTA
    patchelf \
      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
      --set-rpath "${libPath}" \
      $out/VESTA-core
    patchelf \
      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
      --set-rpath "${libPath}" \
      $out/VESTA-gui
  '';

  meta = with lib; {
    homepage = "https://jp-minerals.org/vesta/en/";
    description = "Visualization for Electronic and STructural Analysis";
    license = licenses.free;
    platforms = platforms.linux;
    architectures = [ "amd64" ];
  };
}

I first load utilities in nix-shell

$ nix-shell -p binutils stdenv nix-index stdenv.cc

and then run

$ nix-build -E '((import <nixpkgs> {}).callPackage (import ./default.nix) { })' --keep-failed --no-out-link

The output indicates all libs are resolved except for one java library: libjawt.so, which nevertheless does exist, supplied by the jdk package (and nix-locate confirms this). Here is the tail of the build log:

searching for dependencies of /nix/store/pvlf028qs680ac96l6rq5cn9czapcgbx-VESTA-gtk3/PowderPlot/libswt-awt-gtk-3346.so
    libjawt.so -> not found!
setting interpreter of /nix/store/pvlf028qs680ac96l6rq5cn9czapcgbx-VESTA-gtk3/STRUCTURE_TIDY/structure_tidy
searching for dependencies of /nix/store/pvlf028qs680ac96l6rq5cn9czapcgbx-VESTA-gtk3/STRUCTURE_TIDY/structure_tidy
    libgcc_s.so.1 -> found: /nix/store/5gk8zqasr9hdhm9nhl0y7g0g7bf5lvbc-gcc-12.2.0-libgcc/lib
setting RPATH to: /nix/store/5gk8zqasr9hdhm9nhl0y7g0g7bf5lvbc-gcc-12.2.0-libgcc/lib
auto-patchelf: 1 dependencies could not be satisfied
error: auto-patchelf could not satisfy dependency libjawt.so wanted by /nix/store/pvlf028qs680ac96l6rq5cn9czapcgbx-VESTA-gtk3/PowderPlot/libswt-awt-gtk-3346.so
auto-patchelf failed to find all the required dependencies.
Add the missing dependencies to --libs or use `--ignore-missing="foo.so.1 bar.so etc.so"`.
/nix/store/37p8gq9zijbw6pj3lpi1ckqiv18j2g62-stdenv-linux/setup: line 79: pop_var_context: head of shell_variables not a function context
/nix/store/37p8gq9zijbw6pj3lpi1ckqiv18j2g62-stdenv-linux/setup: line 1457: pop_var_context: head of shell_variables not a function context
/nix/store/37p8gq9zijbw6pj3lpi1ckqiv18j2g62-stdenv-linux/setup: line 1594: pop_var_context: head of shell_variables not a function context
note: keeping build directory '/tmp/nix-build-VESTA-gtk3.drv-58'
error: builder for '/nix/store/qvrryfms3ym39fzzqxii28gldfbldjgh-VESTA-gtk3.drv' failed with exit code 1;
       last 10 log lines:
       > searching for dependencies of /nix/store/pvlf028qs680ac96l6rq5cn9czapcgbx-VESTA-gtk3/STRUCTURE_TIDY/structure_tidy
       >     libgcc_s.so.1 -> found: /nix/store/5gk8zqasr9hdhm9nhl0y7g0g7bf5lvbc-gcc-12.2.0-libgcc/lib
       > setting RPATH to: /nix/store/5gk8zqasr9hdhm9nhl0y7g0g7bf5lvbc-gcc-12.2.0-libgcc/lib
       > auto-patchelf: 1 dependencies could not be satisfied
       > error: auto-patchelf could not satisfy dependency libjawt.so wanted by /nix/store/pvlf028qs680ac96l6rq5cn9czapcgbx-VESTA-gtk3/PowderPlot/libswt-awt-gtk-3346.so
       > auto-patchelf failed to find all the required dependencies.
       > Add the missing dependencies to --libs or use `--ignore-missing="foo.so.1 bar.so etc.so"`.
       > /nix/store/37p8gq9zijbw6pj3lpi1ckqiv18j2g62-stdenv-linux/setup: line 79: pop_var_context: head of shell_variables not a function context
       > /nix/store/37p8gq9zijbw6pj3lpi1ckqiv18j2g62-stdenv-linux/setup: line 1457: pop_var_context: head of shell_variables not a function context
       > /nix/store/37p8gq9zijbw6pj3lpi1ckqiv18j2g62-stdenv-linux/setup: line 1594: pop_var_context: head of shell_variables not a function context
       For full logs, run 'nix log /nix/store/qvrryfms3ym39fzzqxii28gldfbldjgh-VESTA-gtk3.drv'.

Confirming the error,

$ ldd /nix/store/pvlf028qs680ac96l6rq5cn9czapcgbx-VESTA-gtk3/PowderPlot/libswt-awt-gtk-3346.so
ldd: warning: you do not have execution permission for `/nix/store/pvlf028qs680ac96l6rq5cn9czapcgbx-VESTA-gtk3/PowderPlot/libswt-awt-gtk-3346.so'
        linux-vdso.so.1 (0x00007f608bf5f000)
        libjawt.so => not found
        libc.so.6 => /nix/store/yaz7pyf0ah88g2v505l38n0f3wg2vzdj-glibc-2.37-8/lib/libc.so.6 (0x00007f608bc1a000)
        /nix/store/yaz7pyf0ah88g2v505l38n0f3wg2vzdj-glibc-2.37-8/lib64/ld-linux-x86-64.so.2 (0x00007f608bf61000)

Does anyone know why patchelf can’t seem to find this particular library (everything else it found successfully), despite the fact that libjawt.so is clearly available?

Did you ever figure this out?

@xav-ie Sorry for very late reply. In answer to your question, no, and I finally concluded that VESTA’s programmer is using a now fairly ancient JDK, such that pointing the linker to more recent libjawt.so versions fails (the not found error may be somewhat misleading, although here I’m just guessing). As a workaround, I ended up just excluding the compilation steps that included this dependency. Not really a fix, but given that this exclusion was a minor, ancillary part of VESTA, this workaround at least allowed the core program to build successfully. Hope this clarifies.

1 Like