Puchatek
Puchatek

Reputation: 1537

How to make Scons look for libstdc++ in nonstandard directory

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++

Upvotes: 0

Views: 946

Answers (2)

Jonathan Wakely
Jonathan Wakely

Reputation: 171443

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"

Upvotes: 2

Avatar33
Avatar33

Reputation: 826

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']

Upvotes: 1

Related Questions