1

When I compile a c++ program using g++ from the command line and then do ldd a.out ldd is able to find libstdc++.a(libstdc++.so.6)

When I build a c++ ruby extension ldd myext.so cannot find libstdc++.a(libstdc++.so.6), and require 'myext' fails to load, with a complaint about not being able to find libstdc++.

If I run g++ -v I see the following output:

COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/big_long_path....
Target: powerpc-ibm-aix7.1.0.0
Configured with: ../gcc-4.8.2/configure .....
Thread model: aix
gcc version 4.8.2 (GCC) 

Now if I set my LIBPATH to include that big_long_path

export LIBPATH=/big_long_path....:$LIBPATH

ldd myext.so

is able to find libstdc++ and my require 'myext' works (returns true)

This might be OK, but I would rather not have to have users muck with their LIBPATH. Is there something I can add to my Makefile that allow the generated myext.so to find libstdc++ (and libgcc) in the location pointed to by that big_long_path I see in the COLLECT_LTO_WRAPPER line that I see when I run g++ -v ?

Update

The first link in the accepted answer below really helped me understand what was going on, and I was able to get ldd to not complain about libstdc++ by adding -blibpath:big_long_path:/usr:/usr/lib to the LDFLAGS in the Makefile.

But for some reason when ruby tried to load the ext it still failed. This made me think that ruby was somehow adjusting the LIBPATH. In the end my solution was to put a symbolic link to the libstdc++ and libgcc_s in the lib directory of the ruby install. The thought was ruby must need to search for extension shared objects, so I figured I would take advantage of this and place these two libs in the path that ruby must search. The only thing I am wondering is if I should just copy the libstdc++ and libgcc_s rather than symbolically link them?

nPn
  • 16,254
  • 9
  • 35
  • 58

2 Answers2

1

It looks like you build your own gcc.

This is a known issue that gcc does not pass -rpath to the linker to specify the locations of libstdc++ and libgcc_s.

You either need to pass that path manually to the linker, or configure your own gcc to do that for you via specs file.

Community
  • 1
  • 1
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0

Don't let the loader searching for the libraries, use option -Wl,-bipath; check the result with dump -X32_64 -H; you should see something like this:

INDEX  PATH                          BASE                MEMBER              
0      /usr/local/lib:/usr/lib:/lib                                          
1      /usr/local/lib                libapr-1.so.0                           
2      /usr/local/lib                libaprutil-1.so.0                       
3      /usr/local/lib                libcrypto.so.1.0.1f                     
4      /usr/local/lib                libexpat.so.1                           
5      /usr/local/lib                libgcc_s.a          shr.o               
6      /usr/local/lib                libiconv.so.2                           
7      /usr/local/lib                libssl.so.1.0.1f                        
8      /usr/local/lib                libcpotlas.so.1                         
9      /usr/lib                      librtl.a            shr.o               
10     /usr/lib                      libc.a              shr.o               
11                                   .   

Also I have to say using C++ for plugin is a really bad idea, especially in exotic systems like AIX

Lorinczy Zsigmond
  • 1,749
  • 1
  • 14
  • 21
  • it's a swig generated wrapper around a c++ class library, ie the library knows nothing about ruby, I just want to write clients in ruby rather than c++ – nPn Jan 15 '16 at 18:01