Avoiding the LD_LIBRARY_PATH for Shared Libs in Go (cgo) Applications (2015-12-21)

That Go (#golang) works very well accessing C libraries is widely known. The DRMAA and DRMAA2 Go wrappers for example accessing the native C shared libraries provided by the Grid Engine installation. Those libraries are not installed in the standard libraries paths by default so the Go application using the Go wrapper can only find the shared lib when the LD_LIBRARY_PATH is set to the lib/lx-am64 path of the Grid Engine installation.

But what when you want to ship an application written in Go which uses a shared library and you want to ship the shared library along with your application? Or when you want to force the application to use a shared library which is not in a default library path?

If you not place the shared lib in a system library path and you don't want to use mechanisms like LD_LIBRARY_PATH then you can think about setting the rpath for your application. This is also possible for Go applications. The rpath just adds an library search path in your binary which can be different to standard search paths. When you don't know the absolute path of the application in advance, this is most likely the common case, then you can set the rpath relatively to where your application is stored. This can be done by using the ORIGIN keyword.

Following example demonstrates how this can be done when you compile your Go application.

Let's assume you ship your Go application in a directory structure like this:

myapp/
myapp/bin/myapplication
myapp/lib/mysharedlib.so

The Go myapplication needs the C mysharedlib.so which is in the lib directory ../lib. Then you can build it telling the linker you want to set the rpath to ../lib:

export CGO_LDFLAGS="-L/path/to/the/lib -Wl,-rpath -Wl,\$ORIGIN/../lib"
export CGO_CFLAGS="-I/path/to/include/file/of/the/lib/include"
go build

Inspecting the rpath of the executable can be done in that way:

objdump -p yourapplication | grep RPATH
  RPATH                $ORIGIN/../lib