0

I'm trying to use Scons to build a simple project on a server on which I have rights to install stuff only in specific locations (and not in /usr/ ). Since I'm not happy with default compiler the server is offering me, I installed g++4.8 and verified it works just fine. But when I try to use Scons to build a simple project, while it picks up correct g++ (I can get that by checking the version), it's looking for libstdc++ in /usr/ directories instead of the directory where g++4.8 installation resides. E.g. code compiles, but upon execution fails with:

./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)

Again - this doesn't happen when I call the compiler myself from the terminal. Even when I add the lib path containing libraries for g++4.8 with LIBPATH option, I get the same error. Here's my SConscript file:

            Import('env')

    COMPILER_FLAGS = '-Wall -fopenmp -O3 -std=c++11'
    LINK_FLAGS = '-Wall -fopenmp -O3 -std=c++11'
    LIB_PATH = 'myfolder/gcc-4.8.2/lib64'

    PROGRAM = 'main'
    SRC = ['main.cpp', 'Foo.cpp']
    env.Append(CPPFLAGS = COMPILER_FLAGS)
                                                                                                                                                             env.Append(LINKFLAGS = LINK_FLAGS)
    env.Program(target = PROGRAM, source = SRC, LIBPATH = LIB_PATH)

and SConstruct is just

import os
env = Environment(ENV = os.environ)
SConscript('./SConscript', exports=['env'], duplicate=0)

Edit:

I made sure location of my compiler comes in the path before default compiler. But even if I set it explicitly with Environment(CXX=...) it's the same story. Here's the build output:

/mypath/gcc-4.8.2/bin/g++ -o Foo.o -c -Wall -fopenmp -O3 -std=c++11 Foo.cpp
/mypath/gcc-4.8.2/bin/g++ -o main.o -c -Wall -fopenmp -O3 -std=c++11 main.cpp
/mypath/gcc-4.8.2/bin/g++ -o main -Wall -fopenmp -O3 -std=c++11 main.o Foo.o -L/mypath/gcc-4.8.2/lib64
scons: done building targets.
-bash-3.2$ 
-bash-3.2$ 
-bash-3.2$ ./main 
./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)
./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./main)
-bash-3.2$ 

Yet another edit:

ldd on both manual and scons compile reveal:

linux-vdso.so.1 =>  (0x00007fff513fd000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6(0x0000003e7f600000)
libm.so.6 => /lib64/libm.so.6 (0x0000003e79600000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003e7de00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003e79200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003e78e00000)

So indeed even manual compile doesn't look for the libs in the right directory (or where I installed the compiler) and the problem isn't with the scons itself, but likely that I didn't configure something right, but then I'm really puzzled as to why the executable runs fine, while it doesn't for scons.


Ok, so my problem wasn't with scons, but with me not giving explicit paths to nonstandard locations of libstdc++ and friends. SO answer over here explains this in more detail: Linking g++ 4.8 to libstdc++

Community
  • 1
  • 1
Puchatek
  • 1,477
  • 3
  • 15
  • 33

2 Answers2

2

You're misinterpreting the error. GCC always knows how to find its own libraries, including libstdc++. The problem is that after you've compiled the program the runtime linker (which is not part of GCC, it's part of your OS and comes from glibc) doesn't know how to find the newer libstdc++, so it finds the default system one, which is too old.

The problem and solution are described at in the Libstdc++ FAQ, "How do I insure that the dynamically linked library will be found?", and manual, "Finding Dynamic or Shared Libraries"

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
1

This doesn't sound right. Can you show us what you do to override the compiler? If you are only doing the above, I don't think your compiler will be overridden with the new version.

You need to do something like env = Environment(CC='/path/to/gcc') Or Environment(CXX='/path/to/g++') if you want to override the c++ compiler

Or is your path on your environment setup to have the directory of the custom compiler before the standard compilers directory?

It might help to clean and then run with scons with --debug=presub which will show you the command line used to build each target. Also your environment is a dictionary, so try printing out different keys to make sure they match what you expect:

print env['CC']
print env['CXX']
Avatar33
  • 787
  • 5
  • 14
  • It seems like main.o was compiled "by hand" explicitly using the newer compiler, and scons is trying to link with that version of main.o. Although, I would imagine SCons would detect this situation, either way, all objects should definitely be cleaned. – Brady Mar 09 '14 at 09:09
  • Please have a look at my edit, the answer was too long to put it in the comments. – Puchatek Mar 09 '14 at 12:28
  • What is surprising to me is that you say that this doesn't happen when you call the compiler manually from the terminal. – Avatar33 Mar 09 '14 at 14:52
  • 1
    Premature enter there. ... I can't imagine what scons could possibly do to influence the situation. I would do the following test. Compile your binary manually from the command line, then run ldd /path/to/your/binary and save the result. Now compile the binary with scons and again run ldd /path/to/your/binary Now examine and compare the results. If the results are the same then it seems highly unlikely that the problem is scons related. If on the other hand the results are different then careful examination may reveal the problem. – Avatar33 Mar 09 '14 at 15:01
  • Avatar33 - a good call there, please have a look at my edit. I guess the problem is with how I configured compiler installation then :/ – Puchatek Mar 10 '14 at 01:29
  • I'm glad you were able to understand the situation better. I think you have 3 options: 1) Use rpath as suggested, scons does support rpath. Just do env.['RPATH'] = '/path/to/gcc/lib'. Google or manual for more info 2) Use static linking. This will embed the library into your executable. This is has it's advantages and disadvantages but means you don't have to ship your library along with your application. 3) Use the LD_LIBRARY_PATH environment variable to point to your libraries. You'll find that each of these options has their own advantages and disadvantages. HTH – Avatar33 Mar 10 '14 at 07:23