Problem linking shared library at runtime (libzmq)

3,445 views
Skip to first unread message

Kiki Sugiaman

unread,
Jun 30, 2013, 12:05:59 AM6/30/13
to golan...@googlegroups.com
Hi all,

I am playing around with the example code for Go binding for Zeromq
(using this binding: https://github.com/pebbe/zmq3).

The examples: https://github.com/pebbe/zmq3/tree/master/examples

The examples build successfully, but at runtime I get this error:
"error while loading shared libraries: libzmq.so.3: cannot open shared
object file: No such file or directory"

I then searched around and found this thread:
https://groups.google.com/forum/#!topic/golang-nuts/fFIyDVilcrU
<https://groups.google.com/forum/#%21topic/golang-nuts/fFIyDVilcrU>

Using the workaround mentioned in the thread (setting LD_LIBRARY_PATH or
using -ldflags="-r /usr/local/lib" on "go build"), I could get the
examples to work.

My question is, is there a way to solve this from my Go application?
That is, how can I program my Go app so that it knows where the needed
shared library is located at runtime?

Thanks.

Carlos Castillo

unread,
Jun 30, 2013, 10:15:00 AM6/30/13
to golan...@googlegroups.com
The # cgo LDFLAGS directive in the comment to an import "C" can be used to pass such flags (see: http://golang.org/cmd/cgo/).

So in your own apps you can make one of your own packages have a file that looks like the following: http://play.golang.org/p/jB_gi9MTm1 . Your program will then be built with the -r flags passed to the linker.

Also shown in the cgo documentation, is that the CGO_LDFLAGS environment variable can be set to have a set of arguments passed to every cgo link (ie: w/o typing it as part of the go command).

That all being said, your problem is that the locations where the dynamic linker looks for so files doesn't include the location where you have libzmq.so.3 installed on your system. There are several ways to fix this:
  • Update your system so the dynamic linker does what you want:
    1. Use the LD_LIBRARY_PATH to add directories of your choice to the runtime library path.
    2. Update your /etc/ld.so.conf file (or more likely create a /etc/ld.so.conf.d/*.conf file), so that /usr/local/lib is included in the search path. The run ldconfig. This is like a more widespread (and permanent) version of #1.
  • Change how programs are linked against libzmq to put /usr/local/lib into the binary's rpath:
    1. Add a -ldflags="-r /usr/local/lib" option to all go build / install / run commands that need the zmq3 package
    2. Set CGO_LDFLAGS="-r /usr/local/lib" in the environment so that all go build/install/run/etc... add the -r flag to the build
    3. Use a cgo directive in your own programs to artificially add the -r option to the linker command line
    4. Change /usr/local/lib/pkgconfig/libzmq.pc so that anything (including the zmq3 package) that uses pkg-config to find and link against the library adds the -r /usr/local/lib option
  • Move, or symlink the libzmq.so.3 file to a location already in the runtime search path.

Kiki Sugiaman

unread,
Jun 30, 2013, 3:37:16 PM6/30/13
to golan...@googlegroups.com
Thanks Carlos.

I added the #cgo LDFLAGS directive like the following:
http://play.golang.org/p/qXixMR5ZJP

and now I get this at compile time:
# command-line-arguments
/usr/bin/ld: cannot find /usr/local/lib: File format not recognized
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s
collect2: ld returned 1 exit status

Anything missing here?
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Carlos Castillo

unread,
Jul 1, 2013, 7:47:43 AM7/1/13
to golan...@googlegroups.com
After a little research, I found that -r is a 6l (go ld) option: http://golang.org/cmd/ld/, whereas the gnu ld option is "-rpath", and to pass it to ld from gcc you need a -Wl option.  I believe that this will do it: http://play.golang.org/p/0I562kLGII

Kiki Sugiaman

unread,
Jul 1, 2013, 1:13:43 PM7/1/13
to golan...@googlegroups.com
Thanks! This works.

Carlos Castillo

unread,
Jul 1, 2013, 4:13:23 PM7/1/13
to Kiki Sugiaman, golang-nuts
Just remember, for this case, ie: your own app on your own machine, this is fine. But in the more general case, you will not want to hard code this into the source code for a program or library, since it may need to be changed for every system.

In the more general case you should be either:
  • Installing dynamic libraries to places in the runtime search path
  • Updating the runtime search path to include the custom locations where you install the libraries (eg: using LD_LIBRARY_PATH or updating /etc/ld.so.conf)
  • Building your apps or packages with flags or env values specific to the machine they're on (eg: 'go build -ldflags "-r /usr/local/lib"' OR 'export CGO_LDFLAGS=-Wl,-rpath,/usr/local/lib')


--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/Rpq7wBntSjM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Carlos Castillo

Ondřej Kupka

unread,
Nov 19, 2013, 2:07:06 AM11/19/13
to golan...@googlegroups.com
Hi,

I had the same problem, then I ran ldconfig and it started working.

Regards,
Ondrej Kupka
Reply all
Reply to author
Forward
0 new messages