I want to use Red Hat Enterprise Linux 5.8 to compile folly, and gcc is 4.1.2. But folly needs gcc >=4.6. So I need to upgrade gcc to 4.6, maybe binutils etc. If new toolchain generates binary files such as *.a *.so, would running them on old Red Hat Enterprise Linux 5.8 bring any problem or unstabitily?
Probably no big trouble (because GCC 4.1 & soon released GCC 4.8 produces compatible code), at least for C code.
For C++ code I believe there is a incompatibility. Certainly the libstdc++ is tied to the compiler version. Sometimes it may be compatible in practice, sometimes not (but the C++ ABI slightly changed too). And this incompatibility may spread to every C++ library.
I believe you should try. If you recompile -with the same newest GCC- all the C++ dependencies, you'll probably be quite safe. So you could compile the newest GCC, then compile folly and all its dependencies with it.
BTW, I would suggest going to the latest GCC (today 4.7, in a few weeks 4.8).
Related
I'm cross-compiling an application for aarch64 on my x86 Ubuntu Bionic system, and I have problems with glibc version mismatch. My cross-compile toolchain was using v2.27, while the system that is to run the application has v2.24. I thought that it might be due to my toolchain having a too high version, so I decided to downgrade.
After removing all previous cross-compilation installs, I installed gcc-4.8-aarch64-linux-gnu (as I had successfully cross-compiled the application with this version on a different host system), thinking that it would install an older aarch64 version of glibc to /usr/aarch64-linux-gnu/lib/. However, again, v2.27 was installed (I verified that this directory didn't exist before installing the new cross-compilation toolchain).
So my question is twofold:
What determines which aarch64 version of glibc is installed on my system when installing gcc-4.8-aarch64-linux-gnu? Is it directly tied to my own system's x86 version of glibc?
Is there a correct way to install the aarch64 version of glibc v2.24 (or lower) on my system?
I concur with your hypothesis. After battling similar symptoms for 40 hours straight, I've discovered this confirmation:
https://packages.ubuntu.com/impish/gcc-10-aarch64-linux-gnu
https://packages.debian.org/bullseye/gcc-aarch64-linux-gnu
Note that Ubuntu 21.10 (Impish) and Debian 11 (Bullseye) have packages for a gcc 10 cross compiler. Be wary of the very confusing fact the Ubuntu's default package is actually gcc 11, but Debian 11's default is gcc 10. The similar version numbers of Debian and gcc are a coincidence. Also ignore for now the fact that Ubuntu's package is gcc 10.3.0 and Debian's is gcc 10.2.1.
Focus instead on the recommendations and dependencies of each package. Ultimately the Ubuntu package calls up libc >= 2.34, while the Debian package calls up libc >= 2.28.
Sure enough, when I cross-compile from Impish on x86 for Bullseye on aarch64 (despite having a complete SYSROOT for the target), I get this at runtime:
/lib/aarch64-linux-gnu/libc.so.6: version 'GLIBC_2.34' not found
But your question remains, is there any tie between the host libc and that used by the cross-compiler? The answer is a definite maybe.
See this excellent answer and links for an overview of a cross-compiler. The take-away:
You don't just cross-compile glibc, you need to cross-compile an entire toolchain. Toolchain components are ALWAYS: ld + gcc + libc + gdb.
So the C library is an integral part of the cross-compiler.
What shenanigans then, are going on when you install gcc-aarch64-linux-gnu? It's just a compiler - only one of the four parts of a toolchain.
Well apparently there's some flexibility. Technically, a cross-compiler can be naked. That's typically only useful when you're compiling an operating system, rather than an executable that runs on an operating system. So you can construct special toolchains for special purposes.
But for the standard purpose (cross compiling for Linux on another architecture) you want a typical toolchain. Which is where the package's dependencies and recommendations come in. A gcc is always in want of an ld which is always in want of a libc, and the ménage à trois is intimate. In fact, gcc is built with libc using ld in a complex do-si-do. See this example from a great guide by Preshing on Programming:
It's possible to force separation and link to other libraries, but it's not easy.
For example, the linker you use has a set of default search directories that are baked in. From the fine manual:
The default set of paths searched (without being specified with -L) depends on which emulation mode ld is using, and in some cases also on how it was configured.
And it gets more intwined. By default, gcc will call on a dynamic linker whose location is hard-coded. For a cross-compiler, it might be something like /lib/ld-linux-aarch64.so.1. Not only that, the executable may also end up with the hardcoded path, as its program interpreter.
Again, if you're careful you can tear apart the toolchain and override things. But not only is it tricky to enforce, particularly if you have a complex build, the multitude of combinations of options and paths means there are also often bugs. So your host environment can easily leak into your cross-compiling toolchain.
So in summary, cross-compiling requires a toolchain. While pulling a cross-compiler from a package manager seems like an easy and legitimate thing to do, it comes with a lot of implicit baggage. You can either carefully follow the package dependencies to check what version you're getting, or use one of the many dedicated toolchain environments, such as crosstool-NG.
I know Linux Matlab only has official support for gcc 4.9 for mex.
Does anyone know how to get either the Linux Intel compilers (icc) working with mex on Linux or more recent versions of the gcc?
This is for recent versions of Matlab (2015-2017).
I assume you talk about C++ projects. Yes, its possible with newer versions of gcc.
Check supported compilers to find out which Matlab uses which gcc version.
Tell your newer version of gcc to use the ABI version of the gcc version that your Matlab was made in for the compilation of your project and all dependencies.
Tell Matlab to use the standard c++ library in /usr/lib and not the one it contains itself. It is backwards compatible.
Example with gcc > 4.9.x for Matlab 2017b:
Matlab 2017b was built with gcc 4.9.x
gcc 4.9.x is compatible with CXX ABI version 8
use your gcc with compile flag -fabi-version=8 for your mex file and all dependencies
in a shell export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6 before a call to matlab
I have problem using gcc/g++ after I changed the machine I use,
I installed gcc-4.9.2 in my previous machine, when I moved to the new machine, I copied gcc folder to the new machine.
When I try to use I get this error :
/data/obenchek/gcc-4.9.2/bin/g++: /lib64/libc.so.6: version `GLIBC_2.11' not found (required by /data/obenchek/gcc-4.9.2/bin/g++)
I have already checked this question :
`GLIBC_2.11' not found
If it says right, the version of libc and g++ are not compatible , libc version :
/lib/libc.so.6
GNU C Library stable release version 2.4 (20090904), by Roland McGrath et al.
...
So I should reinstall gcc completely or there is a easier way to resolve this ??
I copied gcc folder to the new machine.
That's your problem: don't copy, install appropriate GCC package instead.
Most UNIX systems, including Linux, guarantee backward compatibility: a binary compiled on an older system continues to run on a newer one.
The reverse is not true: a binary compiled on a newer system often will not run on an older one. This is working "as designed".
In this particular instance, you copied GCC compiled with GLIBC-2.11 or newer to a machine that has GLIBC-2.10 or older. And that doesn't work.
I have a c++11 library ( https://github.com/matiu2/cdnalizer ). I want to distribute it on centos6 and ubuntu12.04 LTS.
It compiles happily on Ubuntu 13.10 and Gentoo.
I tried compiling with as much staticness as I could, but it still depends on a glibc that centos doesn't have:
matiu#matiu-laptop:~/projects/cdnalizer/build/src/apache$ readelf -d mod_cdnalizer.so | grep NEED
0x0000000000000001 (NEEDED) Shared library: [libapr-1.so.0]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000006ffffffe (VERNEED) 0xd520
0x000000006fffffff (VERNEEDNUM) 3
build line:
/usr/bin/g++ -fPIC -I/usr/local/include -I/usr/include -I/usr/include/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu/c++/4.8 -Wall -Wextra -g -shared -Wl,-soname,mod_cdnalizer.so -o mod_cdnalizer.so CMakeFiles/mod_cdnalizer.dir/mod_cdnalizer.cpp.o CMakeFiles/mod_cdnalizer.dir/config.cpp.o CMakeFiles/mod_cdnalizer.dir/filter.cpp.o ../libbase.a -lapr-1
I have tried compiling gcc-4.8.2 on centos, but the binaries it produces have similar glibc dependencies:
[root#matt src]# ./test_config
./test_config: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./test_config)
./test_config: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./test_config)
I heard that you can't escape glibc dependencies for shared libraries because c++ throws excoptions and so needs the shared libstdc++ (but my lib doesn't throw exceptions across the library boundary).
I also heard that you can't link in glibc statically because the static lib was not compiled with -fPIC.
My main question is:
How can I distribute my c++11 shared library on centos6 ?
My sub questions are:
Can I compile a c++11 shared library on ubuntu 13.10, and have it load on centos6 (and older ubuntus) ? how ?
Can I compile a c++11 shared library on centos6 and have it work on standard centos installs ?
(Don't worry about Apache2.2 vs 2.4 dependency .. that's the easy bit)
Can I compile a c++11 shared library on centos6 and have it work on standard centos installs ?
If you can't build your code with the standard CentOS 6 g++/glibc/libstdc++, then no, it's not going to run on standard CentOS 6 installs.
The CentOS distro is for long term support (LTS). Critical bugs get fixed with updates, but software otherwise doesn't change, usually. This is a feature. Even with 3rd party repositories (e.g. EPEL), the available software for CentOS isn't really recent.
Can I compile a c++11 shared library on ubuntu 13.10, and have it load on centos6 (and older ubuntus) ? how ?
If you can compile it using the g++ 4.4 toolchain, sure. In this case, you cannot use a more advanced compiler. A quick search on Ubuntu's 12.04 LTS package list shows libstdc++6-4.5-dbg using a version of libstdc++.so.6 which would be backward incompatible, based on error messages above.
How can I distribute my c++11 shared library on centos6 ?
As you've shown above, you'll have at least one updated dependency (libstdc++.so.6) that you'll need to ship with your library, and install in some odd location, with it's attendant headaches (LD_LIBRARY_PATH, what happens to any other C++ plugins, etc.). And update at some point.
Some enterprise users would object to something like this, mainly because it doesn't mesh well with the existing OS.
Statically linking in dependencies (like in Ali's answer with the Developer Toolset below) could work also. It's also not without problems (updates to dependencies again), but might be the best chance for your code to work on CentOS 6.
I see from comments to Ali's answer, that devtools 1 (gcc 4.7.0) didn't work, making it unlikely that devtools 1.1 would work. So it seems you do need C++11 support up to the level of gcc 4.8 in this case.
Your problem has nothing to do with GLIBC.
Your problem is that libstdc++.so.6 on the CentOS6 is too old.
According to distrowatch, CentOS 6.5 shipped with GCC 4.4.7. C++11 support was mostly complete in GCC 4.8, and in 4.4 had only incomplete support.
If you can build your library with GCC 4.4.7, then it should work (provided you build it on an old enough system). If you can't, then you'll have to update GCC on your target CentOS system.
Alternatively, you can distribute a newer version of libstdc++.so.6 (one from GCC 4.8), install it in non-default location, and ask your customers to link against that newer version (either via LD_LIBRARY_PATH, or better by supplying appropriate -Wl,-rpath=... option at link time).
In short:
Things are only backward compatible. You need to pick the oldest
release of the distro you want to support and build on
that. The later releases of that distro will most likely be backward
compatible so your shared library will do just fine on later releases.
You either need to build the compiler with C++11 support from source or install it from some repo of the distro. Prefer the latter if possible due to compatibility issues.
Any non-system library should be statically linked into your shared
library: -Wl,--static -lmylib1 -lmylib2 -Wl,--dynamic. The important here is that -Wl,--dynamic is at the end, after all statically linked stuff.
I haven't tried it myself but my colleague who does this routinely says:
Use CentOS 6.5 (the latest of the 6.x versions as of writing).
Install devtools / Developer Toolset. The compatibility issues are supposed to be resolved by special, patched version of the developer tools. Developer Toolset 2.1 Beta comes with gcc 4.8.
Link statically all third party libraries and libstdc++. However, do not
link glibc and other system libraries statically that are supposed to be on the target machine
anyway.
The programs that my colleague compiles this way work on my Ubuntu machine just fine. (He uses CentOS 5.10, which seems to be the oldest, still supported distro that has glibc 2.5.)
Hope this helps.
I just installed gcc 4.9 (with C11 support), and want to add it to Xcode 4.6.3's build options as a compiler option. I ran make and make install, and the packages are all there (under /usr/bin/gcc. Running gcc --version confirms that gcc 4.9 is installed rather than an older version.
When I go into an existing Xcode project's build settings, the only compiler options available are
Apple LLVM compiler 4.2
LLVM GCC 4.2
Other...
Clearly, GCC 4.9 would have to be added using the "Other..." option, although I'm not sure how. I've tried inputting the path to gcc (/usr/bin/gcc), although the default value for other isn't a path at all: com.apple.compilers.llvmgcc42.
I've also tried following the instructions from the answer to this question as well, but the machine I'm on doesn't have the /Developer directory at all, since I believe Apple integrated the developer tools that required (and created) this directory into Xcode.
How do I add gcc 4.9 as a compiler option in Xcode?