Glenn Jones

Hello 👋 Welcome to my corner of the internet. I write here about the different challenges I encounter, and the projects I work on. Find out more about me.

Fixing gdal-bin error libblas.so.3 cannot open shared object file No such file or directory

I was getting an error after installing the latest version of gdal-bin:

error while loading shared libraries: libblas.so.3: cannot open shared object file: No such file or directory

For context, this is a server on ubuntu 18.04, deploying applications using dokku and buildpacks. I install ogr2ogr by install the gdal-bin package using Apt (using the apt buildpack).

Debugging

I did the following to debug the issue:

dokku —rm run <app_name> bash
/app/.apt/usr/bin/ogr2ogr # should cause the error
ldd /app/.apt/usr/bin/ogr2ogr

This showed that two libraries could not be found:

Googling uncovered the following GitHub issue with a similar problem: heroku-buildpack-apt/issues/64. There it was suggested that adding to the LDLIBRARYPATH would fix it.

I could validate this fix in the running application by doing:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/.apt/usr/lib/x86_64-linux-gnu/lapack:/app/.apt/usr/lib/x86_64-linux-gnu/blas

Now when I called /app/.apt/usr/bin/ogr2ogr, the executable ran successfully.

Attempt 1 at fixing

Then, to fix it structurally within dokku: I could not find a way to add a dynamic environment variable (to add to the existing LD_LIBRARY_PATH). So, I went into the running container and did:

echo $LD_LIBRARY_PATH:/app/.apt/usr/lib/x86_64-linux-gnu/lapack:/app/.apt/usr/lib/x86_64-linux-gnu/blas

The resulting value I then set as an environment variable (LD_LIBRARY_PATH) for the dokku application. However, upon redeployment, this caused other executables to fail.

The fix

Rather simple: prefix the specific executable I was calling through Open3 with a hash of environment variables, with the updated LD_LIBRARY_PATH

cmd = "ogrinfo" # for debugging now
env = {
  'LD_LIBRARY_PATH' => "#{ENV['LD_LIBRARY_PATH']}:/app/.apt/usr/lib/x86_64-linux-gnu/lapack:/app/.apt/usr/lib/x86_64-linux-gnu/blas"
}
_o, e, _s = Open3.capture3(env, cmd)

Links

Previous: Silly-id ruby gem for generating locale-aware random names
Next: Refer to a local gem within a ruby project