We have managed to get our code building and running on Ubuntu 10.10. The code uses both C++ compiled with GCC 4.5 and fortran compiled with the latest version of ifort. We may be required to support an older embedded linux platform with a version of GCC several years old (still awaiting specs from client). Unfortunately their software and hardware has been speced for military use so it can't be upgraded. My question is are we likely to face ABI issues building our application with the older version of GCC and linking it with libraries compiled with the latest version of ifort?
Are you trying to call the Fortran code from C++, call the C++ code from Fortran, or both? If you're calling Fortran code from C++, I don't think you'll have a problem, especially if you're using the same Fortran compiler.
If you're trying to access C++ code from Fortran, this will depend on the nature of the C++ code. If the Fortran-accessible functions use C linkage, then you should be okay, because the C ABI is standardized. If the functions use C++ linkage, I would expect to have some trouble, because the C++ ABI isn't standardized and I'm sure GCC has made minor (and possibly major) changes to their ABI over the years.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 months ago.
Improve this question
Context
I am developing a cross-platform project that depends on a highly performance sensitive open-source library. This library supports a number of different compilers, but the most performant version is compiled via clang, due to inline assembly which isn't supported by the MSVC compiler (cl). This has highlighted to me that clang is capable of compiling code on Windows, and emitting highly performant dll libraries, but that there is also a deficit in my understanding of the interoperability of the MSVC toolchain and the clang ecosystem.
Question
To what extent is code compiled with clang, interoperable with the MSVC toolchain?
Are binaries emitted by clang ABI compatible with binaries emitted by cl, up to and including the latest language standard?
Specifically, can a static library (.a) compiled with clang be consumed by the MSVC toolchain? (ie. symbol definitions are not dllexport/imported).
Can clang emit 32-bit binaries?
I recognise clang-cl is simply a driver for clang, but are there any practical limitations or other reasons not to favour clang-cl over cl for new projects?
Specifically, can a static library (.a) compiled with clang be consumed by the MSVC toolchain? (ie. symbol definitions are not
dllexport/imported).
Yes. I have a fairly large Windows (MFC-based) project in which I use the native MSVC compiler to build all components that actually use any MFC (or other WinAPI) code, but use clang-cl for one particular "core" module (built as a static library). All code in that core module is strictly Standard-compliant (C++17, currently, but vide infra). I have been using this MSVC+clang combination for some years and have yet to experience any issues related to ABI incompatibility. (But note that static libraries on Windows have the ".lib" extension, not ".a".)
Are binaries emitted by clang ABI compatible with binaries emitted by cl, up to and including the latest language standard?
Yes – but you'll need VS 2022 for C++20 or later: The clang-cl compiler (V11) that comes with VS 2019 only recognizes up to (and including) C++17; however, clang-cl V13 (as installed by VS 2022) can be set to use C++20 or C++23. (Also note that the library I mentioned above makes heavy use of the "STL" containers, like std::vector.)
Can clang emit 32-bit binaries?
Yes. Switching between 64-bit and 32-bit target architectures within the VS IDE works equally well for both MSVC and clang-cl projects. This also seems to work when switching to ARM64 targets (assuming you have installed the required tools), but I can't verify the final output, as I don't have access to an ARM64-based Windows system.
I recognise clang-cl is simply a driver for clang, but are there any practical limitations or other reasons not to favour clang-cl over cl
for new projects?
I have tried building my entire project with the clang-cl tools but – so far – without success. This may be due to the fact that I am using MFC (I get a whole chunk of duplicate and/or missing symbols at link time). However, building simple, console-mode programs for Windows with clang-cl works just fine.
And, one further note: The run-time performance of my final program is considerably greater (i.e. faster) when compiling that core library with clang-cl, compared to the same code compiled with MSVC.
It was very misinterpretative that you called the compiler clang. Your ment clang-cl.exe, not clang, because clang demangle g++ cpmpatible, clang-cl.exe demangle msvc compatible. If you had put into a compile example, maybe : cmake -G Ninja -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE=Release -DCMAKE_LINKER="llvm-link.exe" .
everyone would have understoodd it immediately (so do I now). In Inforamtion theory one example explains more than text only (I'm a mathematician and in math the theory is the meat in informations theory the examples - code snipped - are the meat). The compiler options from clang-cl.exe are exactly the options from msvc, but the option from clang are totally different (g++ options). Hopefully it helps the next reader to understand immediately, that clang-cl.exe is ment, not clang.
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.
I am having trouble understanding the different compilers that are available to me.
I mainly use Xcode for writing and compiling, and in Xcode's preferences, there are all of these options for C++ compilation:
C++ Language Dialect:
C++98[-std=c++98] through C++14[-std=c++14]
GNU++98[-std=gnu++98] through GNU++14[-std=gnu++14]
C++ Standard Library:
libstdc++ (GNU C++ standard library)
libc++ (LLVM C++ standard library with C++11 support)
Can someone explain what exactly all of that ^ is?
I understand that (and correct me if I'm wrong), that apple no longer distributes GCC with Xcode and use Clang instead?
If that were the case, then why does Xcode have the option for GNU C++ standard library? Doesn't GNU make GCC?
What compiler is invoked when I run C++ code in my local terminal with g++ filename.cpp?
Is there any way to make sure that this g++ "compiler" is up to date?
What's the difference between compiling with g++ in the terminal and using Xcode?
Also, what would be the difference if I tried running C++ programs with Clang?
My class requires us to test our programs on the department's server's compiler via ssh from my terminal. The server is a Unix machine and I know that its compiler is GNU's GCC compiler and we also access it using g++. Does this mean that the local g++ in my terminal is also GCC?
edit: Grammar
1.
C++ language dialect
C++98[-std=c++98] through C++14[-std=c++14]
GNU++98[-std=gnu++98] through GNU++14[-std=gnu++14]
The C++ language has evolved over time. These are the various versions of the language that are available to you. If you have to be compatible with something old, you might be forced to use an old one. Otherwise you'd probably want ot use the newest available, which is c++14 in the list above. 14 stands for 2014, 98 for 1998 - it is supposed to represent the year that version of the standard was blessed.
In addition to standard C++ there are non-standard extensions. Gnu is a compiler "manufacturer", the "GNU" above is the non-stanadard extensions as specified by GNU for a particular documented version.
C++ Standard Library:
libstdc++ (GNU C++ standard library)
libc++ (LLVM C++ standard library with C++11 support)
In addition to the base language, the standard library is also a part of the standard. These are two different implementations of the standard library. The first is by GNU, the second by llvm. llvm are a different compiler manufacturer.
On osx you'd probably use libc++ as I believe the llvm compiler (clang++) is now standard there. The llvm compiler will support the gnu extensions if you need them. You probably don't. Just use the latest version of whatever is default.
Yes
two different pieces, the compiler and the standard library. You can use clang++ with libstd++
g++ -v will tell you
not really. Update xcode to the newest or start looking at homebrew or ports to get the latest and greatest they package of whatever compiler you like.
Probably the same compiler, you can set it either to point at any compiler you have installed. So what each points at is your choice.
both g++ and clang++ are standards compliant. You're unlikely to notice much difference. They will complile the same source files into equivalent binaries.
run g++ -v in any terminal to see exactly what it is.
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.
For my own education I am curious what compilers use which C++ front-end and back-end.
Can you enlighten me where the following technologies are used and what hallmarks/advantages they have if any?
Open64 - is it back-end, front-end, or both? Which compilers use it? I encounter it in CUDA compiler.
EDG - as far as I can tell this is a front-end use by Intel compilers and Comeau. do other compilers use it? I found quite a few references to it in boost source code.
ANTLR - this is general parser. Do any common compilers use it?
Regarding compilers:
with front-end/back-end does gcc compiler suite uses? does it have common heritage with any other compiler?
what front-end/back-end PGI and PathScale compilers use?
what front-end/back-end XL compiler uses (IBM offering).
in-depth links on the Internet or your personal know-how would be great.
I did some Google searching, but information I generally encountered was rather superficial.
Thanks.
EDG is a front-end used by Intel and Comeau. See EDG's list of customers for other users.
ANTLR is a parser generator. I'm not aware of any C++ compiler built around a parser that was built with ANTLR (that doesn't mean it couldn't exist though).
GCC is a suite of compilers, with front ends for C, C++, Fortran, Ada, Java, etc., and back-ends for more processors than I'd care to think about.
Open64 is also a suite of compilers including several front-ends (for C, C++, Fortran, and possibly others I don't remember at the moment) and back-ends (targeting X64, Itanium, ARM, and, again, probably others I don't remember and/or don't know about). I believe its origin (pun noted by not intended) is SGI's compiler(s). I seem to remember reading something hinting that Open64 was derived from some version of the GCC front end(s), but offhand I don't know 1) how similar it remains to GCC internally, or 2) the version of GCC from which it derived -- but it's been around long enough that I'd guess it was GCC 3.x at the most recent, and quite possibly GCC 2.x.
I believe PathScale has created at least one compiler derived from Open64, but they may have others as well.
As far as I know, IBM's compiler is entirely their own creation. I'd guess IBM's (now discontinued) VisualAge for C++ shared some heritage/development/code with XL C++, but don't know that for sure, and can't even begin to guess at the extent of it, even assuming it's true.
The Clang project provides new front-ends for C/C++/Objective C on top of the LLVM backend. The LLVM project also provide a LLVM-gcc, using the GCC front end and the LLVM backend. The DragonEgg project seeks to replace the GCC backend with LLVM.
The Codeplay VectorC, Sieve and Offload compilers use a custom front-end and back-end
with front-end/backend does gcc compiler suite uses? does it have common heritage with any other compiler?
The acronym “GCC” stands for “GNU compiler collection” (originally “GNU C compiler”) and this already gives a hint: GNU compilers are a collection of compilers, most notably for C and C++ but also for Fortran, Objective-C and others. They share a common back-end and intermediate representation that was developed for GCC specifically.
The front-ends are all custom-written for the GCC. Some were contributed by third parties, most notably the Objective-C front-end, which was contributed by Apple.
Visual studio uses EDG for its intellisense engine.