Boost compilation with different compiler than used for other sources - c++

Should there be a problem to compile static boost libraries (thread, filesystem, etc.) with one gcc version (4.6) and the rest of the code (uses boost headers) with another (4.7)?
I had a compilation error which was solved once everything was compiled with gcc4.7.

Theoretically, it shouldn't be a problem, because the GCC maintains a stable C++ ABI across compiler versions.
In practice, sometimes there are ABI compliance bugs, which may get fixed (or introduced), but my experience is that this issue is a very low risk.

Related

Use Multiple Versions of GCC During Compilation & Dependency on GCC in Object File Execution

This may be a dumb question, but I am a novice in the compilation of a C or C++ project through the command line. I am currently trying to cross-compile some frameworks to run in an aarch64 device, which has a built-in gcc5.4.0. However, some of the libraries require at least gcc7.5.0. So my first question is:
Can a framework that is compiled with gcc7.5.0 version can be used in an environment where gcc5.4.0 is present?
Moreover, some processes the I try to run on the device also requires gcc7.5.0. Therefore, my second question is that:
Can an object file (.o, e.g. the output of the compiled .c / .cpp file) that is compiled with gcc7.5.0 run on a system with gcc5.4.0?
Lastly, some processes require the libraries compiled in gcc5.4.0 and gcc7.5.0 to be used together. Therefore, I have to link the .so files that are generated by both gcc5.4.0 and gcc7.5.0. Hence, my last question is:
Can one create an executable by using libraries together that are compiled with different gcc versions?
Thanks.
For your first two questions: the presence or absence of a compiler in the system does not matter. I've run software on machines where no compiler was installed (it was compiled elsewhere). I've run software on machines where a bunch of compilers are installed, included multiple version of g++.
For your last question: the thing which matter when linking (either statically, at link time, or dynamically at execution time) libraries is called ABI. There are two aspects of the ABI: for the language itself, and for the standard libraries. For both, GCC maintains forward compatibility: using the latest compiler and standard library, you can link with object files compiled with older compiler (and for older standard library) since something like 3.4. In some more restricted cases (less well documented), you can even use the older compiler and standard library.
If you want to execute a program dynamically linked (which is usually the default with GCC) with a newer version of the standard library than the one on your system, you need to ensure it is found. That's a whole other subject, but here are two key words to help you find information for Unix (I know nothing about how Windows handle this, I presume but could be wrong that MacOS is a unix for this purpose): LD_LIBRARY_PATH and rpath.
Obviously meeting bugs is always a possibility and some care is needed in some cases. So here are some relevant links with the details.
GCC Compiler option related to ABI.
Standard library documentation related to ABI.
On the use on the C++11 library ABI. C++11 put additional requirements on some types (notably std::string) which prevented GCC to keep its old ABI for those types. Thus a new ABI was introduced in GCC 5 or so and if you want to be compatible with the previous one you have to pay attention. (Note that distributers sometimes forced the old ABI even with GCC version 5 and later)
Older related SO question

If you use a newer gcc than the one that comes with your distro, are system libraries a concern?

My question specifies the version numbers of my scenario, but I'm interested in a general to the question.
I'd like to use gcc 11 on Alma Linux/Red Hat 8 (identical ABI), which come with gcc 8, in order to use C++20/23 features in my own programs. The programs I compile with it (all userspace applications) would run on the same system.
I'm thinking of compiling gcc11 from source, installing it in /usr/local/gcc11/, and calling it when I need it. I don't want to replace/remove the system gcc, since various tools that support a given distro will be expecting that compiler. I would just call a wrapper script to use gcc11 when I need it.
I expect gcc11 will compile just fine, and so will programs I compile with it. But any non-trivial program tends to link against libc, libm, libdl, libpthread, libgcc_s, libstdc++, and so on. I would be using gcc11 with relatively old versions of these system libraries. These are all system libraries which I've never had to deal with directly.
The situation that worries me is if some new dependency I use was written around libpthread version Z but my system has version X, and despite the ABI being unchanged (which allows my program to link successfully against the system libpthread), the behavior is different due to bugfixes, and I end up with subtle runtime bugs.
Is this a valid worry? Or am I golden as soon as my application compiles/launches successfully?
The only existing discussion on this that I could find ( Is there any issue in upgrading GCC version to other than the ones come with distro? ) is light on info, and the warnings given don't apply to me since I don't intend to touch the system gcc/libs.
It depends which features you're compiling against. This article from cppreference.com has more details on which c++ features for each language version are supported by which c++ runtime. https://en.cppreference.com/w/cpp/compiler_support
Since you're talking about compiling with gcc, you're going to want to look at the libstdc++ runtime library. It looks like not even every feature of c++20 is even supported by version 8 of the runtime library. But it is most things.
To work around this you could
install the runtime version of libstdc++ you want
package and distribute the libstdc++ runtime library along with your code
statically link against libstdc++, which I don't recommend
Keep in mind that there is theoretically an option to compile against libstdc++ statically, but you're not guaranteed to get those symbols at runtime depending on your situation. It also makes a difference if you're compiling an application vs a library. Loading a library my cause your libraries symbols to conflict with what's already been loaded (probably by libstdc++). This post does a good job explaining some things to look out for https://stackoverflow.com/a/14082540/1196033.
(Also, Android is weird https://developer.android.com/ndk/guides/cpp-support)

C++ build application with newer compiler without rebuilding the libraries

I have a C++ program that uses several libraries.
I build my application and the libraries with gcc version 4.
The libraries are built as static libraries and the header and libX.a files are added to the project.
Can I build my application with a newer gcc (for example gcc 7) without needing to rebuild also the libraries?
If I try building with the newer gcc and succeed, does it means I won't get any unexpected problems related to this later?
As mentioned in the comments you should recompile everything when doing such a major compiler upgrade.
Successful linking does not guarantee you will not get problems at runtime. This is due to ABI incompatibility between GCC versions. You might get lucky but it's something you can't depend on in the long run.
You might try to use GCC's code generation switches to make your compiled file compatible with your old libraries by looking up what has changed since those libraries were compiled in GCC's ABI policy but I think it's just not worth the effort.

If clang++ and g++ are ABI incompatible, what is used for shared libraries in binary?

clang++ and g++ are ABI incompatible, even for things as core as standard containers, according to, e.g., the clang++ website.
Debian ships with C++ shared libraries, i.e. libboost, etc... that are compiled with ~something and user programs using both compiler generally work, and the library names aren't mangled with the compiler that was used for them. When you install clang, debian doesn't go and pull in duplicate versions of every C++ library installed on your system.
What's the deal? Is the ability of clang to link against distro-provided C++ libraries just way stronger than the (thankfully cautious) compiler devs describe it to be?
even for things as core as standard containers
Standard containers are not all that "core". (For typical implementations) they are implemented entirely in valid C++ in headers, and if you compile the same headers with G++ and Clang++ you'll get ABI compatible output. You should only get incompatibilities "even for things as core as standard containers" if you use different versions of the container headers, not just by using Clang instead of GCC.
Both GCC and Clang conform to a cross-vendor, cross-platform C++ ABI (originally developed for the Itanium architecture, but also used for x86, x86_64, SPARC etc.) The really core things such as class layout, name mangling, exception handling, vtables etc. are specified by that ABI and Clang and GCC both follow it.
So in other words, if you compile the same source with GCC and Clang you'll get ABI-compatible binaries.
If you want to understand this stuff better see my What's an ABI and why is it so complicated? slides.
G++ and Clang are for the vast majority completely ABI compatible. Furthermore, ABI incompatibilities for Standard containers are properties of the standard library implementation (libstdc++ or libc++), not the compiler. Therefore, there is no need for any re-compilation.
Clang could never have gotten off the ground if it was not ABI compatible with g++, as it would be basically unusable without a pre-existing large following. In fact, Clang is so compatible with GCC, they ape virtually all of g++'s command-line interface, compiler intrinsics, bugs, etc, so that you can literally just drop in Clang instead of G++ and the vast majority of the time, everything will just work.
This probably will not answer the exact question correctly:
Some time ago I tried to compile some object files wih gcc, another object files with clang. Finally I linked everything together and it worked correctly.
I believe Linux distributions uses gcc, because I examined some Makefile's of Ubuntu and CentOS and they used gcc.

Linking libraries compiled with different version of gcc

I have a C++ software (Borealis stream engine) which is compiled and works with GCC 3.3.6 (I haven't been able to make it work with newer version of GCC, and there is no longer support for the software).
I like to extends this to call some complex cryptographic libraries (Pairing Based library) which is definitely compiled with the latest version of GCC.
My question is whether it is possible to do that, i.e. to call a library compiled with a new version of GCC from the code compiled with much older version of GCC? Is it technically possible? What are the potential problems?
I hope someone can help shedding some lights on these questions, so that I can avoid spending days (or even weeks) compiling and learning how to use these software just to find out at the end that they cannot work together.
It is. If it wasn't, we would have serious problems. The version of the compiler is unrelated to the ABI of the platform.
(One thing that may actually break in the case of C++ compilers is a change in the name mangling convention, but, for example, with C, even this risk is nonexistent.)