GCC runtime libraries vs Microsoft Visual C++ runtime redistributables - c++

Could anyone shed some light on C++ library versioning and distribution of
GCC library (libgcc, libstdc++,..?)
Microsoft Visual C++ runtime libraries (6.0, 2005, 2008, 2010, 2012, 2013, 2015,....)
With my limited exposure to GCC programming, I have never seen C++ runtime libraries being distributed along with program. That is often the case with MS Windows programs.
Can a relatively old linux system run a newer C++14 program (which is compiled on a newer system and then copied over to old system)?
Do GCC programmers distribute runtime libraries along with programs? If no, Why do Windows programs distribute them? How GCC distributions ensure that a C++ program always works when installed?
What about the frameworks such as Qt, How does Qt handle versioning and distribution on Linux and Windows? Does Qt also distribute runtimes for different versions?
May be it has to do with platform, how Linux is designed vs How Windows is designed.
What is so fundamentally different in approaches GCC & MS Windows take?

GCC's runtime libraries, like GNU's C library, provide a stable binary interface (small footnote: GCC 5.1 kind of blew this up, due to new C++ features that had to be implemented).
Microsoft's libraries don't, and each little version difference may and probably will break the ABI (application binary interface).
Additionally, Microsoft compilers change their ABI with version increments as well, making it a bad idea to combine code built by different versions of their tools. Also here, GCC maintains a strict ABI, which makes object code perfectly compatible (if no ABI breaking codegen options are given of course).
This ABI consists of object size and layout, which a compiler uses when generating code. Therefore running code built against one version but using a different version at runtime may produce unexpected results because the memory layout and use is just different.
GNU/Linux is quite strong in this regard, and is generally able to maintain strong backwards compatibility.
As long as the compiled program was compiled against an older version of the library, it will run perfectly if loaded with a newer version that a user has installed.
The same story goes for Qt, which only breaks ABI between major version numbers (Qt 4 and Qt 5 cannot be loaded at runtime interchangeable).
There are some small exceptions, GCC 5's libstdc++ being a big problem there. I know of no big glibc ABI breakages though.
The new Microsoft Universal CRT attempts to solve this issue, by providing a stable C runtime interface and as the story would have us believe, provide a glibc style library ABI stability. This UCRT is available for Windows Vista and up, but applications need to be compiled specifically against this. The first version of VS that has this capability, is VS2015.

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.

C++ Standard for Visual Studio 2015

I am trying to install MongoDB driver and is reading this following section
https://github.com/mongodb/mongo-cxx-driver/wiki/Download-and-Compile-the-Legacy-Driver
SCons Options when Compiling the C++ Driver
Select options as appropriate for your environment. Please note that some flags may not be available on older versions.
Important note about C++11/C++14: The boost libraries do not offer a stable ABI across different versions of the C++ standard. As a result, you must ensure that your application, the C++ driver, and boost are all built with the same language standard. In particular, if you are building the C++ driver with C++11 enabled, you must also build your application with C++11 enabled, and link against a C++11 compiled boost. Note that on most systems, the system or package installed boost distribution is not built with C++11, and is therefore incompatible with a C++11 build of the legacy driver.
Important note about the C++ standard library: Much like the C++11 issues, it is again critical that all three components (your application, boost, and the C++ driver) be built against the same C++ runtime library. You cannot mix components that have linked against libc++ with those that have linked against libstdc++.
Important 26compat Note: If you are using the 26compat branch, the install-mongoclient target is only enabled when the --full flag is provided. Similarly, you must use the --use-system-boost flag when building 26compat.*
My main question, I am trying to find out what standard my visual studio 2015 is running on when I build solution. I have tried to read around but I think I misunderstood the concept of C++11 and C++14. On Microsoft page it mentioned that VS2015 supports C++11,C++14 and C++17. But how do I know what am I using now? I can't find a way to explicitly configure. I am new to C++ and have been coding Java for many years. C++ is confusing to me because there are so many variety such as compilers and standards. Please help me understand and possibly find out what standard I am running.
The text is mostly nonsense.
ABI's are dictated by compilers, not standards. There is no ABI for C++11, there's one for GCC and a different one for MSVC2015.
"C++11 enabled" is a setting on GCC, and it does affect their ABI. The same applies to libc++ versus libstdc++, neither is part of the C++11 standard. Also, the mixing of build environments and the OS ("system Boost version") is mostly a Linux thing.
MSVC++ isn't GCC, and it doesn't use libstdc++, so all this does not affect you. And Boost versions aren't even a MSVC++ setting anymore, for the last few versions library configuration has been a per-project setting instead. (Tip: Create a Boost.vsprops file for that)

Is MSVC strictly necessary to compile on windows?

Some open source projects explicitly state that in order to compile on windows, they need a microsoft compiler (often a specific version as well, as latter versions are incompatible or will refuse to compile older code).
Since it seems absurd to me that, since there are foss compilers that can compile for windows, a microsoft compiler would be necessary for any fundamental task, I'm assuming this is because those projects use api calls to libraries (such as msvcrt*.dll) that, for some reason, mingw-gcc, clang and other ports of compilers for windows are unable to compile against.
My understanding of these requirements is shallow, since my experience with compiled code comes primarily from linux and this worries me, since getting a microsoft compiler is non-trivial. the only way to get them is through the express editions of microsoft's visual c++, and even then, the most recent version will completely refuse to install on an old winxp machine like mine and the only version available at the moment is vc++express2010, which requires registrations to turn from trialware into freeware (and even then i'm not clear on if that'll work or what it entails - perhaps OS hooks to "debug" and other intereference?).
1) My question is, do these projects depend on microsoft compilers due to building against these microsoft-only libraries (which apparently foss compilers can't do)?
It would seem absurd if the reason is the build script or preprocessor directives, since those can be relatively easily ported.
2) Also, is it possible that, even if I avoid any msvcrt/.net/etc. calls, i can still find myself needing a microsoft compiler to compile native windows software (assuming no usage of libraries that do perform those calls)?
3) Can I simply use clang and some widget library to make native windows software just as well?
4) Can I modify the source of a project so that it doesn't depend on a microsoft compiler?
(ok that's 4 questions, sorry, this is quite hard for me to express clearly).
1) My question is, do these projects depend on microsoft compilers due
to building against these microsoft-only libraries (which apparently
foss compilers can't do)?
Compiler vendors and GUI framework vendors can supply DLLs that perform similar to the MS DLLs. Some of the MS DLLs are system DLLs and are used by the other compiler and framework vendors.
If you are using compiler or framework specific DLLs, they need to accompany the installation of your programs (projects).
2) Also, is it possible that, even if I avoid any msvcrt/.net/etc.
calls, i can still find myself needing a microsoft compiler to compile
native windows software (assuming no usage of libraries that do
perform those calls)?
No. If you scan through the posts on StackOverflow, there are many people who are using the Windows API directly, I guess what you are calling native windows software. Usually, the code for these API are located in a system API. The compiler translates the function call to a call into these DLLs, loading them as necessary.
3) Can I simply use clang and some widget library to make native
windows software just as well?
No, you can't. That's why they exist.
Again, many people are using frameworks like Qt and xWidgets without the MS compilers. I did that for a while. I switched over to Visual Studio, primarily for the debugger. I didn't like how other IDEs tried to use GDB. Otherwise, I wouldn't use MS because they tend to go by the Microsoft Standard language rather than the ISO.
4) Can I modify the source of a project so that it doesn't depend on a
microsoft compiler?
No, that is why there are freeware and other compilers out there.
Hmmm, one can use Java to create GUIs that don't use the MS compiler, but they use the Windows API.
Try installing Cygwin. When you look at all the libraries you will realize that projects can be created that don't use the MS Compiler. Again, read through the StackOverflow posts and you will find that people are using other compilers, such as Intel, GNU, Clang, Greenhills and others. Some compilers for embedded systems will also compile for Windows OS, so you can write code that works on both platforms.
Looks like you need to search the web for "GNU GUI tutorial C++" and see what pops up. Also, search for "wxWidgets" and "Qt" for other frameworks.

C++ windows binaries: conditions to be used with MinGW

I am new to C++ and I am now struggling with compiling and linking.
Recently I have been using cmake and make to recompile a library (mlpack) that makes usage of Boost (Cmake does not find boost 1.51 (windows 8)).
In a first attempt, I downloaded precompiled binaries for windows. This did not work out well and I have been explained the binaries I was using were for MSVC, not MinGW, therefore troubles. And indeed, after recompiling boost using MinGW, things went ok.
Here I would just like to get an intuition what would be the differences between binaries for MSVC and MinGW. I (naively?) thought binaries were specific to OS/processor. What do the binaries for MSVC contains that make them unusable by MinGW ?
It is relatively easy to combine artifacts (static/shared libraries) produced by MSVC and MinGW (this applies to other C compilers in general) as long as they export pure C API. This makes C API to be very portable and that's one of the main reasons why so many popular libraries still prefer to use pure C API.
The story with C++ is completely different. The most notorious obstacles for proper interoperability between artifacts produced by different C++ compilers are differences in name mangling and application binary interface (ABI). This applies to all C++ compilers in general, and not only MinGW and MSVC. If you want to learn more about interoperability pitfalls between MSVC and MinGW in particular, I encourage you to read the following articles:
Interoperability of Libraries Created by Different Compiler Brands
Binary-compatible C++ Interfaces
To be simple.
Windows speaks French.
MinGW speaks French, German and English.
Unix systems speak German.
The MSVC binaries are written in French.
The MinGW binaries are written in FrenchAngloGerman.
The UNIX binaries are written in German.
Windows needs MinGW to translate some of the German and English to French before it can understand everything.
MinGW is not like the other programs. It is basically a mini OS between Windows and Linux. So mostly it needs a modified form of binaries to work properly. The fact that you develop your program on Windows on MinGW doesn't mean they will run on pure Windows with out any problems. You still need to ship or distribute the MinGW libraries and executables that you used with your program.

MinGW as a reliable 64-bit GCC compiler

I am worried about the reliability of the MinGW compiler for 64-bit, as an alternative to the Visual C++ compiler.
For example, assuming C++ code builds and runs perfectly under Linux using GCC 4.6.2, will the corresponding MinGW produce similarly reliable executables/libraries under 64-bit Windows?
Is Cygwin a better option in terms of reliablity? Is neither to the Visual C++ compiler?
First, some misconceptions:
MinGW(.org) does not provide a 64-bit version of its runtime. MinGW-w64 does, in addition to their 32-bit CRT. They are also working on ARM support. And support various additional APIs (Win32 and others).
Cygwin <-> MinGW-w64: Cygwin does not use the MS CRT (msvcrt.dll). It instead inserts a POSIX compatibility layer in between your Cygwin app and the system's OS libraries (kernel32.dll, ntdll.dll, etc.), namely cygwin1.dll.
On to the question then...
I have found the MinGW-w64 compilers very good, and GCC 4.6 and above (actually, 4.5.1 and above) are very capable of producing good 64-bit code for Windows. Please remember that MinGW provides essentially the same C API as msvcrt.dll, so go to msdn.com for documentation (and be sure to look at the "MSVC++ 2003" version of documentation, some functions differ with the newer runtimes), do not think that because it's GCC, glibc documentation suddenly applies to Windows. Your code will have to be cross-platform. Also note that sizeof(long)!=sizeof(T*) on x64 Windows. A commonly encountered error when porting *nix or x86 Windows code to x64 Windows.