Binary compatibility (using C++11) on older distro versions - c++

I am using GCC to compile a C++ application on Ubuntu 13. I want to be able to use C++11 features in my code, but at the same time still be able to produce a binary that my users can run on older versions of Ubuntu.
If I compile on Ubuntu 13 with the latest version of GCC my binary will not run on Ubuntu 12 since glibc is not forward compatible:
(How compatible are different versions of glibc?)
What are my options?
Is this even possible without requiring my users to jump through massive hoops?
If not, what do my users have to do to be able to run the binary (i.e. can they install the newer glibc on the older version of Ubuntu)?
Note: I don't not want to consider statically linking glibc since:
I've read that this is a very bad idea
Licensing issues
Cross-distribution compatibility issues
Currently my application does not use any C++11 features and I compile on an older version of Ubuntu with an older version of GCC to avoid this problem. But it makes me sad not being able to use the latest and greatest language features :(

You can try to use Boost Libraries which have quite the same features as C++11 and is "more retro-compatible" than C++11 : it will easily compile on older version of Ubuntu.
Otherwise the best option might be to ask to the users of Ubuntu 12.04 to upgrade there GCC from 4.6 to 4.7 or more recent :
http://www.swiftsoftwaregroup.com/upgrade-gcc-4-7-ubuntu-12-04/

You are asking "how do I use code that isn't on older systems".
The answer is of course, "Include the code with your project".
If you think through what you're asking, you'll realize that in any case, you'll need the code for the c++11 functions in libstdc++. So if they aren't on ubuntu 12, YOU have to add them. Therefore, you'd have to have it statically linked. it's the only way to ensure it will run on an arbitrary ubuntu12 system.
Well you could make a fancy installation, but in the end, it'd just be your apps "dynamically linking" to the libstdc++, so it may as well be statically linked, since no other program is going to be looking for it on ubuntu12

In general, a c++ library is compatible only if the same compiler is used and (!) the versions of the compilers are matching (you might be lucky, though). There is no way to be portable in this sense, besides writing C-code.

Related

Using GCC with new glibc and binutils to build software for system with older sysroot

I have a question since some months and I can't come to an answer with Google for a long time.
Background:
I am cross compiling software for arm based controllers which are running the linux distribution ptxdist. The complete linux image is built with a cross gcc (4.5.2) that was built against glibc-2.13 and binutils-2.21.
The c++ standard is quite old so I built a new toolchain which supports c++11 (gcc 4.8.5). It now is built against glibc-2.20 and binutils-2.24. I want to use that new compiler for my application software on the controller (not the complete image, just this one "main" binary) which is updated through a package management system.
The software seems to run. I just need to set LD_LIBRARY_PATH pointing to libstdc++.so.0.19 instead of libstdc++.so.14 for the binary. It does not accept the new libc, which is libc-2.20 instead of libc-2.13, though.
So binary uses libstdc++.so.0.19 and the rest of the system is unchanged.
Question:
Why is this working?
What risks could I expect running this software and should I anyway?
For example will the binary miss some functions of glibc-2.20 in future because it just gets glibc-2.13 on the target machine? Building gcc-4.8.5 against glibc-2.13 is not possible.
I have read so far that it depends on changes inside the ABI:
Impact on upgrade gcc or binutils
Here it is said that C Code is compatible if build by GCC4.1 to GCC 4.8.
Thank you!
glibc 2.14 introduced the memcpy#GLIBC_2.14 symbol, so pretty much all software compiled against glibc 2.20 will not work on glibc 2.13 because that symbol is missing there. Ideally, you would build your new GCC against glibc 2.13, not glibc 2.20. You claim that building GCC 4.8.5 against glibc 2.13 is not possible, but this is clearly not true in general.
Some newer C++ features will work with the old system libstdc++ because they depend exclusively on templates (from header files) and none of the new code in libstdc++.
You could also investigate how the hybrid linkage model works in Red Hat Developer Toolset. It links the newer parts of libstdc++ statically, while relying on the system libstdc++ for the common, older parts. This way, you get proper interoperability for things like exceptions and you do not have to install a newer libstdc++ on the target.
Good material for this could be here:
Multiple glibc libraries on a single host
Glibc vs GCC vs binutils compatibility
My final solution is this:
I built the GCC 4.8.5 as a cross compiler. I could not manage to build it with the older glibc2.13, only with version 2.20. It may be possible but in my case it did not work. Anyway, that is not a problem because I also built it with the sysroot-flag. Compiling new software depends completely on my old system, including C Runtime. I don't get a new C++ standard with this, but if you switch on compiler optimizations, I experienced better binary compression and performance.
Regarding a new C++ standard, I could link a newer libstdc++ which came with my cross compiler using -l:libstdc++.so.6.0.19 as LDDFLAG. Therefore I only need to copy an additional libstdc++ on my target beside the old libstdc++.
After having a look into the symbols used by the new lib using
strings libstdc++.so.6.0.19 | grep GLIBC_
you can observe that it doesn't depend on any newer symbols than GLIBC_2.4. It looks like I could never run into the problem of missing symbols.
So in my case I have luck using a new C++11 standard without having any changes in the rest of the system. If there are introduced new symbols you need to follow the above links in my post which are pretty informative. But I would never try that for myself. In my case, with the GCC 4.9.4, libstdc++.so.6.0.20 got symbols pointing to GLIBC_2.17. That could give me trouble as I am cross compiling with GLIBC_2.13.

Compiling and running c++ apps in different Ubuntu version

I've been trying to find a way to make my applications compatible between different Ubuntu LTS versions.
However, most of the time it ends up with the "symbol lookup error:" or "cannot find libxxxx.so.xx".
The requirement is very clear, developer should be able to compile the code on one of last 3 Ubuntu LTS (currently 12,14,16-04) versions and the output should be able to run on all 3 last versions. But the problem is getting complex.
Is there any way to do this?
Thanks in advance.
Linux binaries compiled on older distributions are generally compatible with newer ones. The kernel invests a lot of effort in being backwards compatible - as does glibc. This may not be true for all libraries, but in my experience; most try.
So, what you probably want to do is, compile your app on the oldest supported distro and it will most likely work on the newer one(s).
A really simple trick is to ... compile from source on the appropriate distro.
You can even almost automate this as Ubuntu / Canonical give you free accounts on Launchpad. For example, I use my PPA for either backports or unpackaged sources I want at either work, or home, or on Travis CI, ... in a particular release flavour.
Otherwise, the very obvious alternative is of course to create a static build which is independent of the runtimes of the particular release. That will work 'forever' or until the kernel changes. In the 20+ years I have used Linux, such a change occurred once (with the introduction of the Elf format).

C++11 features compatibility with different versions of GCC

Following, my previous question about How to safely deploy an application built with an upgraded compiler, there is still a doubt for me about the C++11 features compatibility. Using devtoolset-2, the application that will be built with gcc 4.8.2 but linked with libstdc++.so.6.0.13 will have full C++11 features supported or only the common set with libstdc++6.0.19 ?
I am not really sure to understand this point actually.
You shouldn't be mixing libstdc++ like that, so it's a moot point. You should redistribute the libstdc++ that comes with devtoolset-2 and link against that specifically. Otherwise the compiler and standard library will be at odds with each other, and even they won't know the answer to your question!
Then, simply look up a list of what C++11 features are supported in GCC 4.8.2.

Is there a GSL implementation I can use with GCC 4.9.x?

Microsoft's (Core) Guidelines Support Library implementation is said to support GCC 5.1 - but does not specify support for other versions. Higher versions seem to be ok (anyway, 5.3.1 on my Debian Stretch) - but building the tests with GCC 4.9.3 fails.
Has anybody else implemented the GSL?
Can I use MS GSL anyway, somehow?
If not, can I use some safe subset of it? (Probably not, I know)
If not, isn't it a problem that only people with newer compilers can have a guidelines support libraries? Even though their older compilers support C++11 or even C++14?
Yes, there is one I know of: gsl-lite.
It worked fine for me so far. But I changed my compiler to a newer version and did not need it anymore.
You can also use (a rather small) subset of Microsofts implementation. If you do not need the span-classes. These are gsl_assert.h (Expects, Ensures) and gsl_utils.h (narrow, final_act, ...). I think I might have adjusted just some constexpr related things.

Compiler installation which is simple

Is there any compiler for C++ that works under W7 and is easy to install, except VC++?
I never get these scripts and linux emulations to work, and really just want to try another compiler.
The nuwen distribultion of the GCC compiler includes the compiler and all necessary supporting tools and libraries as a single Windows installer. You don't need any Linux emulation in order to use it. A similar, slightly smaller pacakage is TDM's MinGW build. Both of these are on GCC 4.5 (as of Aug-2010).
If you want an IDE, then Code::Blocks also comes as a complete system. This has recently (Jul-2010) been heavily improved, and comes with the GCC 4.4.1 compiler, if you want it. You might also want to look at CodeLite, which is also fairly easy to install.
Mingw is generally easier than cygwin. It doesn't come with a port of every unix tools as cygwin does, but the resulting .exes are native (no need for cygwin.dll)
Cygwin includes the gcc compiler and also provides a Unix look and feel which will be the other thing you need to get scripts and linux emulations to work. (This inlcude the libraries Unix libraries will have functions that VC does not have which might be the issue that you are having)
Qt for Windows comes with MingW, which I've found to be reasonably easy to use and install, and the LGPL version is priced right (free as in beer). You don't need to use any the Qt libraries in your application. I'm not sure which version of GCC is currenlty bundled with it. There are no licensing restrictions for the software you develop (unless you're actually modifying and redistributing source code of the LGPL version of Qt).