2

I'm trying to run my first C++ program on Solaris. Just a simple Hello World program. When I try to run. I get the error libstdc++.so.6:open failed:No such file or directory. Of course I did some googling and found out that I can solve this by setting the environment variable:

export LD_LIBRARY_PATH=/usr/local/lib

After relog, I found out that it was not a permanent way to solve it. I'm guessing this have something to do with linking the libstdc++.so.6 during compile. Here are the step that I did from the beginning:

bash-3.2# gcc -c test.cpp

bash-3.2# gcc -o test test.o -lstdc++

bash-3.2# ./test
   libstdc++.so.6:open failed:No such file or directory

bash-3.2# ldd test | grep not
   libstdc++.so.6 =>        (file not found)

bash-3.2# /usr/ccs/bin/elfdump test | grep RUNPA

bash-3.2# find /usr -name libstdc++.so.6
   /usr/local/lib/libstdc++.so.6

Did I miss a flag or something during compile? How do I create a softlink so that it knows where to look for when running that program?

This is the platform that I'm using:

bash-3.2# uname -a
   SunOS ms-sparc8 5.8 Generic_108528-13 sun4u sparc SUNW,Sun-Blade-100

bash-3.2# gcc -v
   Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/3.3.2/specs
   Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls --disable-libgcj --enable-languages=c,c++
   Thread model: posix
   gcc version 3.3.2
2

The easiest way to set the Solaris run-time linker search path is by using crle, but you need to be very careful when doing so as you can quite easily make your system unusable if you break it! To add /usr/local/bin to the linker path:

# crle -u -l /usr/local/lib

Once you've done that, call crle on its own to verify the new search path.

An alternative is to compile the path into the binary itself:

$ gcc -Wl,-rpath,/usr/local/lib -o test test.o -lstdc++

The above is a better option as the binary will work on other systems without having to have the linker path adjusted.

3
  • I have tested to compile using the -Wl,-rpath. Seems like its still unable to link. This is the error. ld: fatal: option -dn and -P are incompatible ld: fatal: Flags processing errors collect2: ld returned 1 exit status May 9 '14 at 10:02
  • 1
    @MohdFikrie Can you try $ gcc -Wl,-R/usr/local/lib -o test test.o -lstdc++ - this ought to pass -R/usr/local/lib to ld. May 10 '14 at 1:04
  • thx Mark Plotnick..its the capital r that I'm missing. Seems like on Solaris they use -R to link and not -r. May 26 '14 at 2:39
1

The problem is that the Solaris loader can't find the library.

The best thing to do is set the LD_RUN_PATH environment variable during compile to the directory where libstdc++.so.xxxx (your version number) lives. This tells the linker to search that directory at runtime.

Note that LD_RUN_PATH is not to be confused with LD_LIBRARY_PATH. The latter is parsed at run-time, while LD_RUN_PATH essentially compiles in a library path into the executable, so that it doesn't need a LD_LIBRARY_PATH setting to find its libraries.

If all else fails, you can always run your programs from wrapper shell scripts that set the LD_LIBRARY_PATH environment variable appropriately.

That is in a gist,

  • set the LD_LIBRARY_PATH, if it is not included in /usr/local/lib:

    LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ; export LD_LIBRARY_PATH

  • gcc files normally are installed to /usr/lib/gcc/.

Then link the libstdc++.so.6 from the installed directory to /usr/lib or /usr/local/lib using soft-linking

sudo ln -s libstdc++.so.6 /usr/lib/<filename>
3
  • by filename. Which file am I really suppose to link it to? is it just a sub directory inside include? Because there seems to be no libstdc++ or libstdc++.so.6. May 9 '14 at 10:21
  • You can find path/location using the find command, find /usr -name libstd++.so.*
    – delta24
    May 9 '14 at 10:51
  • You can probably try this too, cd ~/lib ln -s /usr/local/lib/libstdc++.so.6 libstdc++.so.3 and export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/lib
    – delta24
    May 9 '14 at 10:54
0

First, there's no need to use crle (and unless you really really understand what you're doing, stay away from it; trust me, you'll lock yourself out with crazy runtime errors when you use it wrong)

Second, there's no need to set LD_LIBRARY_PATH, ever (well mostly), also there's no need to symlink any third party libs in /usr

Just do what mjturner suggests and give gcc the right runtime path when compiling

PS: C++ code should be compiled with g++

Links:

http://notes.theorbis.net/2010/01/how-to-screw-up-solaris-with-crle.html http://prefetch.net/articles/linkers.badldlibrary.html

0

If you use the g++ front-end, it will know how to correctly link C++ code with the libstdc++ library. This is especially true for Solaris.

No matter what you do, do not, under any circumstances use LD_RUN_PATH or LD_LIBRARY_PATH because those variables are meant for shared object library developers to help with debugging and not for final linking. Using those will interpose symbols from different versions of shared object libraries and can cause insidious crashes which are extremely difficult to debug, since one won't know which symbols are being used at run time because of the said interposition.

Always link through the g++ front-end. If you need to pass additional RPATH information to the link-editor, the correct thing to do is g++ -Wl,-R/path/to/lib or g++ -m64 -Wl,-R/path/to/lib/64 (unlike "lib64" on GNU/Linux) depending on whether one is compiling 32- or 64-bit, respectively. GCC compilers on Solaris are multi-arch.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.