Linking libraries compiled with different version of gcc - c++

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.)

Related

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)

Using a C++11 shared library in a C++03 application that was compiled with gcc 4.1 in Linux?

Having gone through a number of similar questions (see below), I don't think any of them cover this case.
Problem
Is it possible to dlopen and use a C++11 shared library compiled using gcc 4.9 from a C++03 application compiled with gcc 4.1? Both the library and application use libstdc++, including on the API (but not std::list, which is apparently a problem). I can't change the way the application is compiled (sadly), and must be certain that existing code doesn't break (e.g. if it ends up dynamically linking to a new version of libstdc++.so).
As far as I understand it (which is not very), on Linux the dynamic linker uses a flat namespace, meaning that is not possible to have the same symbol defined in two libraries. Does statically linking the library against the newer libstdc++ help at all here, or is there perhaps some other way?
Some similar questions that don't seem to answer this
C++11 backwards compatibility
C++03 library with C++11 source code
C++11 compatibility with existing libraries/frameworks
Can a compiled C++11 library (lib,dll,etc.) be linked in older C++ compilers? [softwareengineering.stackexchange.com]
If you do that, you definitely need to use the newer libstdc++.so.6, which should be compatible with the system libstdc++.so.6 based on GCC 4.1 (in the sense that GCC upstream intends to preserve ABI compatibility for the library). It would be a very good idea to use the libstdc++.so.6 library that came with the GCC 4.9 compiler.
Once you do that, it is supposed to work, unless you hit the few of the compatibility gotchas you already listed, and as long as the C++ part of the library interface actually sticks to the C++98 subset and does not use any constructs which are not expressible in the language subset.
All this assumes that the library was actually compiled on the the system which uses GCC 4.1, which probably has something like glibc 2.5. If the library was compiled on a completely different, newer system, then you will likely run into library compatibility issues beyond libstdc++.so.6, and these libraries tend to be even harder to upgrade.
(There is also the possibility that the library was explicitly compiled for use with the 4.1-based system libstdc++.so.6 and everything just works, just as if by magic, but then you wouldn't be asking here, I suppose.)
If you still have problems there is the option to use a statically linked C-API library as border between the two, application and your library, see this post.
Also you may be able to explicitely demand an old version of a symbol, see this post

Benefits to recompiling source using newer IDE

I have a shared DLL that was last compiled in 1997 using Visual Studio 6. We're now using this application and shared DLL on MS Server 2008 and it seems less stable.
I'm assuming if I recompiled using VS 2005 or newer, it would also include improvements in the included Microsoft libraries, right? Is this common to have to recompile for MS bug fixes?
Is there a general practice when it comes to using old compiled code in newer environments?
edit:
I can't really speak from a MS/VS-specific vantage point, but my experiences with other compilers have been the following:
The ABI (i.e. calling conventions or layout of class information) may change between compilers or even compiler versions. So you may get weird crashes if you compile the app and the library with different compiler versions. (That's why there are things like COM or NSObject -- they define a stable way for different modules to talk to each other)
Some OSes change their behaviour depending on the compiler version that generated a binary, or the system libraries it was linked against. That way they can fix bugs without breaking workarounds. If you use a newer compiler or build again with the newer libraries, it is assumed that you test again, so they expect you to notice your workaround is no longer needed and remove it. (This usually applies to the entire application, though, so an older library in a newer app generally gets the new behavior, and its workarounds have already broken.
The new compiler may be better. It may have a better optimizer and generate faster code, it may have bugs fixed, it may support new CPUs.
A new compiler/new libraries may have newer versions of templates and other stub, glue and library code that gets compiled into your application (e.g. C++ template classes). This may be a variant of #3, or of #1 above. E.g. if you have an older implementation of a std::vector that you pass to the newer app, it might crash trying to use parts of it that have changed. Or it might just be less efficient or have less features.
So in general it's a good idea to use a new compiler, but it also means you should be careful and test it thoroughly to make sure you don't miss any changes.
You tagged this with "C++" and "MFC". If you actually have a C++ interface, you really should compile the DLL with the same compiler that you build the clients with. MS doesn't keep the C++ ABI completely stable across compiler versions (especially the standard library), so incompatibilities could lead to subtle errors.
In addition, newer compilers are generally better at optimizing.
If the old dll seems more stable, in my experience, it's only because bugs are obscured better with VC6. (Use of extensive runtime checks with the new version?!)
The main benefit is, that you can debug the dll seamlessly while interacting with the main application. There are other improvements you won't want to miss, e.g. CTime being able to hold dates past year 2037.

Boost compilation with different compiler than used for other sources

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.

Linking code compiled with VC++10 to code compiled with VC++9

Our project uses VC++9 with VS2008, and we want to make the switch to VC++10 with VS2010 to use the new features. Unfortunately, some of our dependencies were built with VC++9, and recompiling them with VC++10 is not possible at the moment for various reasons. Since we really want to make the switch, is there was a way to simply link with those libraries, or is there no compatibility between VC++10 and VC++9 binaries?
EDIT: The actual dependencies are BWAPI and BWTA. In the case of BWAPI, it's not a problem, but BWTA depends in CGAL, and that's what's giving us trouble. Trying to link with it yields a bunch of linking errors.
In general you are out of luck unless the dependencies are COM modules or dlls that export only "pure" C functions.
Visual Studio releases are allowed to break ABI compatibility. This means the exported and internal signature of C++ classes is different, and passing for example a std::string from a binary compiled with one version to a binary compiled with a different version might not have the expected result. In short: do not rely on this working. If it does, you're lucky, but in "undefined behavior" territory at the runtime level. Just fix your code to build with VS2010. It's probably broken to start with.
well in the case of a 3rd party lib that you cannot change, the typical answer is to wrap them with a simple dll that is built with VC2008 and calls the 3rd party for you. You then have control over what is exposed, so you can fall back to a 'standardised' mechanism that works with both linkers. This is almost always C function calls as C is very standardised.
The problem is MS changing the ABI of compiled C++, and I guess with the standards committee not providing a standard way of calling C++ binaries.
Looking at GCAL this doesn't seem to be a good answer for you, the best you can do in such cases is to contact GCAL and wait for a rebuilt binary.
But I just checked - its open source, rebuild it yourself. Not only that, it already supports VS2010 so rebuild should be easy.