I am extracting code designed for an embedded system that uses math functions from NEWLIB and I would like to compile that code with Visual C++ Express Edition. However, it seems that part of the code inside NEWLIB is designed to be compiled only with GCC.
Question: Can NEWLIB be somehow modified to be compiled with a compiler other than GCC? How?
Am I asking unreasonable things here?
As an example, the following symbols are not understood by the Visual Compiler:
__extension__
__ULong
_mbtowc_state
__attribute__
Note, I would content myself if I could compile with LCC. Would this be easier?
Building newlib with MSVC would take a large porting effort. You are better off porting your code to the libc provided by MSVC. They should be mostly compatible. Simply remove newlib from you build system, MSVC will automatically link you code against it's own libc.
If you can built your code under MSVC you've probably already ported it to MSVC's libc anyway. Unless you are explicitly including headers from newlib. For example, if you include stdio.h, by default it will pickup MSVC's version unless you override this behavior to get it to use newlib's version.
Related
TL;DR
Is it possible to compile Boost.Regex 1.76 in Header Only Mode (non BOOST_REGEX_CXX03 mode) with a C++/CLI i.e. /clr i.e. _MANAGED project?
We have been using Boost.Regex for years in our regular Visual C++ projects. A very few of our projects are compiled with Common Language Runtime Support (/clr) which enables C++/CLI, (and for these we always linked in the boost regex library statically). We always pre-built the boost regex DLL and static lib and then linked these from MSVC.
Now, with Boost 1.76 Boost.Regex newly is header only, unless compiling in C++03 mode.
( Version 1.76.0 ) ...
Regex:
Regex is now header only except in C++03 mode
Support for C++03 is now deprecated.
...
However, our C++/CLI project will -- through the boost config magic -- automatically select to build Boost.Regex in the C++03 == BOOST_REGEX_CXX03 mode!
Our current MSVC is Visual Studio 19.7.6, _MSC_FULL_VER 192729112
Since no longer having to pre-build any Boost.Regex binaries would be quite handy, we're currently looking into whether we can get the C++/CLI project to compile in the non BOOST_REGEX_CXX03 mode:
Does anybody know how through the magic of boost/config the macro BOOST_REGEX_CXX03 is selected for a C++ _MANAGED project? (I currently suspect _CPPLIB_VER, but I'm not even sure what version that is.)
Can we switch this? ->
Is it possible to compile Boost.Regex 1.76 in Header Only Mode with a C++/CLI i.e. /clr i.e. _MANAGED project?
To answer the question quickly: No it is not possible to compile Boost.Regex in C++11 mode, that is non C++03 mode with the /clr flag on.
The reason BOOST_REGEX_CXX03 gets selected under /clr is that boost\regex\config.hpp will select it if any of ... BOOST_NO_CXX11_HDR_MUTEX ... BOOST_NO_CXX11_HDR_ATOMIC ... are set, and these are set under /clr because C++/CLI only supports C++03, or rather it supports all of C++03 whereas e.g. std::mutex is not supported in C++/CLI.
As others have written:
It is not supported because the std::mutex implementation uses
GetCurrentThreadId(). That's a winapi function that is not supposed to
be use in managed code since it might be running on a custom CLR host
that doesn't use threads to implement threading.
This is the good kind of problem to have, it shows that you are
building your code wrong. Your native C++ is being compiled with /clr
in effect. Which works rather too well, all C++03 compliant code can
be compiled to MSIL ....
So, IFF you need Boost.regex in a translation unit what is compiled /clr, you must use the C++03 mode.
As for the OP problem: Should check whether the given VC++ project that uses C++/CLI really needs to compile all files with /clr on, or maybe the translation units that actually use Boost.Regex are native C++ anyway and could be compiled without /clr and then just linked together with the C++/CLI object files.
Can I compile files (e.g. C or C++ source code) using for my android device using the arm-linux-gnueabi-* toolchain?
My question might seem a bit silly, but will I get the same result as compiling with the arm-linux-androideabi-* toolchain?
A compilation might mean more than just converting source code to binary. A compiler like GCC also provides certain libraries, in this case libgcc for handling what hardware can't handle. When a compiler becomes a toolchain, it also provides runtime libraries standardised by the programming language similar to ones provided in target system. In arm-linux-gnueabi-'s case that might be libc and for arm-linux-androideabi- that's bionic.
You can produce compatible object files to be used by different compilers, that's what elf is for.
You can produce static executable which can be mighty in size and they should work on any matching hardware/kernel, because in that case toolchains aim for that.
But if you produce dynamic executables, those ones can only run on systems that's supporting their dependencies. Because of that a simple "hello world" application that's not static build by arm-linux-gnueabi- won't work on an Android system since it provides bionic, not libc.
I have my project currently compiling under gcc. It uses Boost, ZeroMQ as static .a libraries and some .so libraries like SDL. I want to go clang all the way but not right now. I wonder if it is possible to compile code that uses .a and .so libraries that were compiled under gcc with clang?
Yes, you usually can use clang with GCC compiled libraries (and vice versa, use gcc with CLANG compiled libraries), because in fact it is not compilation but linking which is relevant. You might be unlucky and get unpleasant suprises.
You could in principle have some dependencies on the version of libstdc++ used to link the relevant libraries (if they are coded in C++). Actually, that usually does not matter much.
In C++, name mangling might in theory be an issue (there might be some corner cases, even incompatibilities between two different versions of g++). Again, in practice it is usually not an issue.
So usually you can mix CLANG (even different but close versions of it) with GCC but you may have unpleasant surprises. What should be expected from any C++ compiler (be it CLANG or GCC) is just to be able to compile and link an entire software (and all libraries) together using the same compiler and version (and that includes the same C++ standard library implementation). This is why upgrading a compiler in a distribution is a lot of work: the distribution makers have to ensure that all the packages compile well (and they do get surprises!).
Beware that the version of libstdc++ does matter. Both Clang & GCC communities work hard to make its ABI compatible for compiler upgrades, but there are subtle corner cases. Read the documentation of your particular and specific C++ standard library implementation. These corner cases could explain mysterious crashes when using a good C++ library binary (compiled with GCC 5) in your code compiled with GCC 8. The bug is not in the library, but the ABI evolved incompatibly.
At least for Crypto++ library this does not work (verified :-( ). So for c++ code it is less likely to work, while pure c code would probably link OK.
EDIT: The problem started appearing with Mac OS X 10.9 Mavericks and Xcode-5, which switched the default C++ library for clang from libstdc++ to libc++. It did not exist on Mac OS X 10.8 and earlier.
The solution appears to be: if you need to compile C++ code with clang, and link it to a gcc-compiled library, use "clang++ -stdlib=libstdc++". The linking is successful, and the resulting binary runs correctly.
CAVEAT: It does not seem to work the other way: even though you can build a library compiled with "clang++ -stdlib=libstdc++" and link gcc-compiled code with it, this code will crash with SEGV. So far I found the only way to link with a clang-compiled library is compiling your code with clang, not gcc.
EDIT2:
GCC-12 seems to include -stdlib= flag. Compiling with g++ -stdlib=libc++ creates Clang++-compatible object files. Very nice.
I do have an additional data point to contribute, on the topic of "unpleasant surprises" mixing code from different versions of different compilers. Therein, I link Victor Shoup's C++-based NTL number theory library with a small piece of driver code that just prints out a large factorial computed by the NTL code, a number with a decimal representation that might span multiple lines if sufficiently large.
I have built and installed SageMath (and its version of NTL) on my system running OS X 10.11.6, and also have a current installation of MacPorts. In /usr/bin I find for gcc --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
My MacPorts gcc gives
gcc (MacPorts gcc9 9.1.0_2) 9.1.0
Now, the SageMath build system requires that MacPorts be moved out of the way, so I assume SageMath builds NTL using Apple's development toolset. The SageMath build log is full of invocations of gcc. SageMath actually builds gcc from source if the system on which the makefile is run has too old a version of Apple's developer tools.
My driver code computes big factorials and uses methods of the NTL class ZZ; I initially had tested this by linking to an NTL static library I built myself, and I changed it to link to the SageMath version because I find it pleasing not to duplicate libraries. Now I understand a bit more about the pitfalls which may arise in this process.
The old makefile invoked g++ to make the executable, but this failed at linking phase with the message:
Undefined symbols for architecture x86_64:
"NTL::operator<<(std::basic_ostream<char, std::char_traits<char> >&, NTL::ZZ const&)",
referenced from:
prn_factorial(int, NTL::ZZ&) in print.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
I had to think about this and run experiments for about 15 minutes before deciding on my own to change the makefile to invoke clang++ which in my current path invokes the MacPorts version
clang version 7.0.1 (tags/RELEASE_701/final)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /opt/local/libexec/llvm-7.0/bin
This time, the makefile successfully linked and built my executable. I conclude that this represents one of those edge cases with "unpleasant surprises". Probably I should conclude that working with details of C++ is not for me; big software systems like SageMath are developed just so hobbyists don't really have to muck around with details like these.
I don't quite understand the difference between the following C/C++ compilers: GCC, MinGW, Cygwin and MSVC. Are the MinGW and Cygwin implementations of GCC or something entirely different? If I intend to compile for Windows, do I ever need anything other than the MSVC (Visual Studio) compiler?
GCC for Windows is mostly useful for makefiles and code written with gcc-specific non-portable syntax.
cygwin is not a compiler, it's a set of libraries that create a Linux-like environment inside Windows, and common linux tools compiled with those libraries.. It is useful for code written with Unixisms (expect files to behave a certain way, or assume the directory separator is /, or assume Linux paths).
If you have pure Windows code, you'll be happiest with Visual C++ (MSVC). Or, if that doesn't optimize well enough, the Intel C++ compiler.
Visual C++ also works well for portable ISO-conformant code... but Microsoft is a little behind the curve on implmenting C++11 and C++14 features. So that's another reason you might want to use gcc (or clang).
Does anyone know if LLVM binary compatibility is planned for visual studio combiled .obj and static .lib files?
Right now I can only link LLVM made .obj files with dynamic libs that loads a DLL at runtime (compiled from visual studio).
While there probably is very small chances that binary compatibility will happen between the two compilers, does anybody know why it is so difficult achieving this between compilers for one platform?
As Neil already said, the compatibility includes stuff like calling convention, name mangling, etc. Though these two are the smallest possible problems. LLVM already knows about all windows-specific calling conventions (stdcall, fastcall, thiscall), this is why you can call stuff from .dll's.
If we speak about C++ code then the main problem is C++ ABI: vtable layout, rtti implementation, etc. clang follows Itanium C++ ABI (which gcc use, for example, among others), VCPP - doesn't and all these are undocumented, unfortunately. There is some work going in clang in this direction, so stuff might start to work apparently. Note that most probably some parts will never be covered, e.g. seh-based exception handling on win32, because it's patented.
Linking with pure C code worked for ages, so, you might workaround these C++ ABI-related issues via C stubs / wrappers.
Apart from anything else, such as calling conventions, register usage etc, for C++ code to binary compatible the two compilers must use the same name-mangling scheme. These schemes are proprietory (so MS does not release the details if its scheme) and are in any case in a constant state of flux.