libstdc++ GLIBCXX version errors - c++

when I compile a c++ program in my computer using g++ and transfer the executable to run it on my university server, I get
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./main)
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./main)
The program runs well on my computer, and I don't have privileges to install any new software on my university servers.
any help ?
Thanks

It seems you are using the standard library as a shared library (default behaviour) when linking your program at home.
So rather than really "linking" the library, your linker just resolves some symbols and does another operation, while delaying the actual loading of the library to run-time.
When you execute your program at your university computer, the loader (the program which actually loads your program in memory and throws the main thread) looks for the libraries your program needs and tries to load them (look for LD_LIBRARY_PATH in linux if you feel curious).
The problem here is that you are linking your program at home with a version of the stdlib that is not the same version as what you have at the university. So when the loader tries to find the library, it fails, and so your program cannot be run.
Solutions:
a) To avoid all these problems use static linking instead of dynamic linking. I am not sure if this is possible with stdlib, but I think it is worth to test it (see: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html and look for "-static" flag)
b) You can try to compile your program at your university computer so it will use the version there.
c) Try to know which stdlib version is installed there and install the same version in your compiler machine.
d) You can try to copy your home version of stdlib to the same folder your application is. This usually works because the loader tends to search for shared libraries in the current application folder before looking in the path set in the environment variable LD_LIBRARY_PATH (linux)
Hope that helps.
P.S.:
Here you have a nice introduction to static vs shared/dynamic libraries http://www.network-theory.co.uk/docs/gccintro/gccintro_25.html
And here (http://en.wikipedia.org/wiki/Library_%28computing%29) a not so nice but more complete library description.

The version of libstdc++.so.6 is too old on the university computer. You have two options:
Statically link with -static. The C++ library will then be merged into the final binary.
Copy the correct version to somewhere in your home directory, then reference it either by passing -rpath /path/to/library/directory at build time, or setting the LD_LIBRARY_PATH environment variable to point to the directory containing the newer libstdc++.so.6.

You can copy your version of the /usr/lib/libstdc++.so.6 to a subdirectory of your home directory of the server, say ~/lib and then run:
$ LD_LIBRARY_PATH=$HOME/lib ./main
Or if you prefer
$ export LD_LIBRARY_PATH=$HOME/lib
$ ./main
And the program should load your private library instead of the system one.

What platforms are you trying to compile for? i.e. 'Your computer' and your 'University servers' ?
You could try compiling your program with the static linking option. This will generate a statically linked executable with all lib dependencies loaded already.
Cheers,

Related

How to build c++ with all dependencies to run on another machine

I wrote c++ code that in including some libraries that I included using -l option. The code is right on my machine but I want finally run this code on another machine named B. I built it on my machine using c++11 and GNU GCC Compiler and attempt to run it on machine B but it errors :
error while loading shared libraries: libcppkafka.so.0.1: cannot open shared object file: No such file or directory
How can I build c++ code with all dependencies to disappear this error?
note: libcppkafka.so.0.1 is in my machine in path /usr/local/lib
note: I use codeblock IDE, so I appreciate that if solution will be codeblock compatible
note: Both machines are ubuntu 16.04
In order to achieve your goal you have 2 options.
You can copy your shared libraries(libcppkafka.so) with your executable and configure its location correctly.
Or you can avoid shared libraries by statically linking them to your program. For this you'll need to have static version of those libraries (libcppkafka in your case)
Since both machines are running the same distribution and version (Ubuntu 16.04), you could find out on the first machine the installed and useful packages, and install these on the second machine.
You'll need to copy the non-packaged things, e.g. in (some part of) /usr/local/lib
You could consider making a real .deb package for your thing (but that is more work).
Notice that an IDE is just an IDE and don't compile anything (an IDE is running external compiler commands; your compiler is GCC invoked as g++). You should perhaps compile on the command line (and you could even make that some shell script, to run on the other machine).

Glibc version mismatch

I have created .so library in my Ubuntu and run it on another machine. Got error:
/lib/tls/i686/cmov/libc.so.6: version `GLIBC_2.15' not found
I suppose this is general C++ library. But how to solve such problem? I can't change client configuration and that means I must to do something with my configuration. But what exactly I must do?
UPD
ldd -version returns
my machine:
ldd (Ubuntu EGLIBC 2.19-0ubuntu6.6) 2.19
host machine:
ldd (Ubuntu EGLIBC 2.11.1-0ubuntu7.8) 2.11.1
On the target machine, run ldd --version and check the output which will tell you what version of GLIBC_ they have.
You can then roll yours back to match their version.
Statically link your executable so it doesn't need their Clib.
You can also alter your program to use the older version, once you know what it is, that is.
See this SO solution for how to do that. How can I link to a specific glibc version?
You have to make sure that you are linking to corresponding or older versions of GLIBC. GCC has flag --sysroot which allows you to define which libs are used.
This may help with details: https://sourceware.org/glibc/wiki/Testing/Builds
The point is that creating a shared library necessarily means that you need to link it to the C library (glibc, in your case). That means that calls to C library functions (which the stdc++ library does) get replaced with actual correct symbol locations in the C library.
Now, if the C library on the compiling/linking machine is not the same as on the target machine, this must fail, and hence, libc version gets checked.
Solutions is to either statically link your .so (which honestly doesn't make much sense, usually), or just correctly compile and link it for your target machine.
Beside compiling everything static, which is usually a bad
idea or does not work at all, the only way to solve the isssue
is to recompile your binary for the target platform.
Install a virtual machine or chroot with the same Ubuntu version
as on the target platform and compile there. There are also solutions
like sbuild or pbuilder/cowbuilder which automates this for Debian/Ubuntu packages.

How can I link to an older version of a shared library

I'm building my program on my computer, on which libtiff.so -> libtiff.so.5.
And then pushing the builds on another machine on which libtiff.so -> libtiff.so.4.
At runtime, my program exists : « error while loading shared libraries: libtiff.so.5: cannot open shared object file: No such file or directory ».
I cannot upgrade the other machine, and I would like to avoid compiling on a virtual machine (with the same linux version than the executing machine). Therefore, I would like to force the compiler to use the libtiff.so.4 instead of libtiff.so.5.
I have libtiff.so.4 installed on my computer (as well as libtiff.so.5). How can I force the linkage with this version instead of the newer version. I thought about moving the libtiff.so -> libtiff.so.4, but I'm afraid of breaking my system if it needs the latest version (apt-get purge libtiff5 gives an error because some other package needs it).
Is it possible to link with an older (installed) version of a library? If yes, how?
And is it harmfull to change the symbolic link of libtiff.so to the older version? If not, will it solve my issue?
You can use this syntax to link to a specific version of a library:
gcc [other options] -l:libtiff.so.4
You do not need to specify a path; the usual directories are searched in order to find the library.
Note: as Michael Wild mentioned, you should have the header files for that version installed instead of the newest ones.
As others have mentioned, you can force the linker by specifying the full versioned name, or even the absolute path.
However, I would strongly advice against doing so. The problem is, that the installed headers correspond to the newer version of the library. If there have been API/ABI-breaking changes between these library versions, the program might work, crash intermittently, or if you're lucky, not work at all.
Instead you should temporarily install the development package that corresponds to the libtiff.so.4 library. If on Debian/Ubuntu or similar, this would be the libtiff4-dev package.
Specify the full path to the .so: instead of -ltiff pass /lib64/libtiff.so.4 to the linker.
You see that error when application is running. So you can either stop your application and then exrract your library tar file. Or, force to link the lib file to the newer version after you extract. In second case, you will use something like:
ln -fs libversionname libfile
Example:
ln -fs libomyapp.1.1.3 libomyapp.lib
This links your libomyapp.lib to the version specified. This can be your older vsersion or your newer version.
But as said, best way to work is to bring down your application to properly match to the expected lib functionality to work without errors or issues.

How to statically link libstdc++

I am trying to get my program working in another machine where libstdc++ versions is different. I am developing and compiling it on netbeans. I have specified the option -static-libstdc++ but the program continues trying to load libstdc++.so.6 in the local machine.
How can I get a fully static libstdc++ link?
Thanks.
Not sure of the exact circumstances here, but I ran into a similar problem just now with different versions of Mac OS X and gcc. I worked around it by copying the actual dylib I wanted into the same directory as the executable and changing DYLD_LIBRARY_PATH to have it search there first before /usr/lib.

How to install the program depending on libstdc++ library

My program is written in C++, using GCC on Ubuntu 9.10 64 bit. If depends on /usr/lib64/libstdc++.so.6 which actually points to /usr/lib64/libstdc++.so.6.0.13. Now I copy this program to virgin Ubuntu 7.04 system and try to run it. It doesn't run, as expected. Then I add to the program directory the following files:
libstdc++.so.6.0.13
libstdc++.so.6 (links to libstdc++.so.6.0.13)
Execute command:
LD_LIBRARY_PATH=. ./myprogram
Now everything is OK. The question: how can I write installation script for such program? myprogram file itself should be placed to /usr/local/bin. What can I do with dependencies? For example, on destination computer, /usr/lib64/libstdc++.so.6 link points to /usr/lib64/libstdc++.so.6.0.8. What can I do with this?
Note: the program is closed-source, I cannot provide source code and makefile.
If you're working on Ubuntu, making a .deb (Debian Package) seems to way to go. Here is a link to get you started.
Your package will state it depends on some other packages (typically the packages that includes libstdc++.so.6.0.13 - i guess the package name is something like libstdc++) and dependencies will be installed when you install your own package using dpkg -i <yourpackage>.deb.
Afterwards, you'll be able to uninstall it using dpkg -r <yourpackage>.
Anyway, never ship such standards files with your own archive. Dependencies exists for this exact purpose.
Hope it helps.
The real problem is that you try to install a binary that use newer versions os common libraries that the ones available on Ubuntu 9.10. The best option should be to make a specific target for the old Ubuntu 7.10 an compile it with the old libraries (that's a backport).
Then you should make two (or more) .deb packages, one for Ubuntu 9.10 and one for Ubuntu 7.10.
Another possibility is to continue doing what you are doing now : set LD_LIBRARY_PATH to point to the desired version of libstdc++ and other necessary libraries. You just set this environment variable in a launcher shell script. In you script you check if the new libraries are available or not and you set your LB_LIBRARY_PATH (say to /usr/local/lib/myprogram/) only if needed. But as others poster pointed out : that's a very bad practice. Anyway, never try to put these provided libraries at their standard place in Ubuntu 9.10, you would risk broking the target system and causing update problems for users or your program if these libraries are officially backported someday.
But if you choose to include your own set of system libraries there is still another way to go than the above one: just link these libraries statically. If a program is the only user of a library as it will probably be in the above scenario you'll lose all advantages of using a shared dynamic library, then why bother with using it at all ? And with stacically linked libraries you won't have to install them.