What compiler(s) can I use to link C++ with D? - d

I want to create a program with a mix of C++ and D, and I would like to be able to work on it as a single project.
My understanding is that I can use some D compiler to output *.obj files, then I can do the same with some C++ compiler, and then link all of the *.obj files into a single binary, is this correct?
If this is correct, can I use any C++ compiler with any D compiler? Or am I restricted to certain combinations like, DMD-DMC, LDC-Clang, and GDC-GCC?
Which linker do I use?
And which standard library do I use?

In theory, you could mix the compilers, but in practice you'd have object file format and standard library mixing issues from time to time, especially on 32 bit Windows. It'd be hard there, but not too bad elsewhere since most things are based on de-facto standards like MSVC and gcc.
Win32: use dmc++ (the digital mars compiler and C runtime) with dmd OR g++ and gdc. Other combinations can be done but are messy. Best way to mix code in Win32 across compiler families is to build a DLL with a C or COM api and use that from D.
Win64: Since dmd uses the 64 bit Microsoft format and C library, you should have little trouble mixing dmd with Visual C++ code. I'm not sure about g++ on Windows64 with dmd.
Most other platforms, including Linux: dmd works along well with g++, as does gdc + gcc. I'm not sure if ldc and g++ are compatible, but ldc should work fine with other LLVM based commpilers on any platform too.

Related

Are g++ and clang++ 100% binary compatible? [duplicate]

If I build a static library with llvm-gcc, then link it with a program compiled using mingw gcc, will the result work?
The same for other combinations of llvm-gcc, clang and normal gcc. I'm interested in how this works out on Linux (using normal non-mingw gcc, of course) and other platforms as well, but the emphasis is on Windows.
I'm also interested in all languages, but with a strong emphasis on C and C++ - obviously clang doesn't support Fortran etc, but I believe llvm-gcc does.
I assume they all use the ELF file format, but what about call conventions, virtual table layouts etc?
Yes, for C code Clang and GCC are compatible (they both use the GNU Toolchain for linking, in fact.) You just have to make sure that you tell clang to create compiled objects and not intermediate bitcode objects. C ABI is well-defined, so the only issue is storage format.
C++ is not portable between compilers in the slightest; different compilers use different virtual table calls, constructors, destruction, name mangling, template implementations, etc. As a rule you should assume objects from one C++ compiler will not work with another.
However yes, at the time of writing Clang++ is able to use GCC/C++ compiled libraries as well; I recently set up a rig to compile C++ programs with clang using G++'s standard runtime library and it compiles+links just fine.
I don't know the answer, but slide 10 in this presentation seems to imply that the ".o" files produced by llvmgcc contain LLVM bytecode (.bc) instead of the usual target-specific object code, so that link-time optimization is possible. However, the LLVM linker should be able to link LLVM code with code produced by "normal" GCC, as the next slide says "link in native .o files and libraries here".
LLVM is a Linux tool, I have sometimes found that Linux compilers don't work quite right on Windows. I would be curious whether you get it to work or not.
I use -m i386pep when linking clang's .o files by ld. llvm's devotion to integrating with gcc is seen openly at http://dragonegg.llvm.org/ so its very intuitive to guess llvm family will greatly be cross-compatible with gcc tool-chain.
Sorry - I was coming back to llvm after a break, and have never done much more than the tutorial. First time around, I kind of burned out after the struggle getting LLVM 2.6 to build on MinGW GCC - thankfully not a problem with LLVM 2.7.
Going through the tutorial again today I noticed in Chapter 5 of the tutorial not only a clear statement that LLVM uses the ABI (Application Binary Interface) of the platform, but also that the tutorial compiler depends on this to allow access to external functions such as sin and cos.
I still don't know whether the compatible ABI extends to C++, though. That's not an issue of call conventions so much as name mangling, struct layout and vtable layout.
Being able to make C function calls is enough for most things, there's still a few issues where I care about C++.
Hopefully they fixed it but I avoid llvm-gcc because I (also) use llvm as a cross compiler and when you use llvm-gcc -m32 on a 64 bit machine the -m32 is ignored and you get 64 bit ints which have to be faked on your 32 bit target machine. Clang does not have that bug nor does gcc. Also the more I use clang the more I like. As to your direct question, dont know, in theory these days targets have well known or used calling conventions. And you would hope both gcc and llvm conform to the same but you never know. the simplest way to find this out is to write a couple of simple functions, compile and disassemble using both tool sets and see how they pass operands to the functions.

Compiling and linking with a different versions of gcc on linux

I am planning to compile a static library (mylib.a) with gcc 4.7.1. I want to take the advantages of C++11, so -std=c++11 is used. The platform, where I compile this lib is x86_64 SLES 11 with glibc-2.8.
Then I want to link this static library on a legacy platform with a legacy code, therefore I must use gcc 4.1.2 for linking and compiling the legacy code. So in my library headers I will not use any C++11 specific code. Also I will link libstdc++.a from gcc.4.7.1. The platform, where I want to link mylib.a, libstdc++.a(gcc4.7.1) and the legacy object files is x86_64 SLES 10 with glibc-2.4.
I tried all of this mess with some dummy C++11 code (std::async()) in mylib.a and it worked. I think this is possible only becuase of the ELF requiriements. Am I thinking correctly, or ELF has nothing to do with it? What kind of errors should I expect if mylib.a will contain some truly complex logic?
Linux has a C++ Application Binary Interface (ABI), which has been around for a while. This means that the calling conventions and name mangling across compilers on Linux is fixed. Therefore, as long as the libraries are compatible, you should be able to compiler with different compilers (or different versions of the same compiler) and have code which correctly and reliably links together.
Not entirely the ELF requirements per se...
GCC guarantees binary compatibility all the way back to some ancient version of 3. As long as the libstdc++ you're linking to has the new library features, there's no reason you can't use them. You will just have to stay away from the new language and library features in code compiled with GCC 4.1.2.

MS vs Non-MS C++ compiler compatibility

Thinking of using MinGW as an alternative to VC++ on Windows, but am worried about compatibility issues. I am thinking in terms of behaviour, performance on Windows (any chance a MinGW compiled EXE might act up). Also, in terms of calling the Windows API, third-party DLLs, generatic and using compatible static libraries, and other issues encountered with mixing parts of the same application with the two compilers.
First, MinGW is not a compiler, but an environment, it is bundled with gcc.
If you think of using gcc to compile code and have it call the Windows API, it's okay as it's C; but for C++ DLLs generated by MSVC, you might have a harsh wake-up call.
The main issue is that in C++, each compiler has its own name mangling (or more generally ABI) and its own Standard library. You cannot mix two different ABI or two different Standard Libraries. End of the story.
Clang has a specific MSVC compatibility mode, allowing it to accept code that MSVC accepts and to emit code that is binary compatible with code compiled with MSVC. Indeed, it is even officially supported in Visual Studio.
Obviously, you could also simply do the cross-DLL communication in C to circumvent most issues.
EDIT: Kerrek's clarification.
It is possible to compile a large amount of C++ code developed for VC++ with the MinGW toolchain; however, the ease with which you complete this task depends significantly on how C++-standards-compliant the code is.
If the C++ code utilizes VC++ extensions, such as __uuidof, then you will need to rewrite these portions.
You won't be able to compile ATL & MFC code with MinGW because the ATL & MFC headers utilize a number of VC++ extensions and depend on VC++-specific behaviors:
try-except Statements
__uuidof
throw(...)
Calling a function without forward-declaring it.
__declspec(nothrow)
...
You won't be able to use VC++-generated LIB files, so you can't use MinGW's linker, ld, to link static libraries without recompiling the library code as a MinGW A archive.
You can link with closed-source DLLs; however, you will need to export the symbols of the DLL as a DEF file and use dlltool to make the corresponding A archive (similar to the VC++ LIB file for each DLL).
MinGW's inclusion of the w32api project basically means that code using the Windows C API will compile just fine, although some of the newer functions may not be immediately available. For example, a few months ago I was having trouble compiling code that used some of the "secure" functions (the ones with the _s suffix), but I got around this problem by exporting the symbols of the DLL as a DEF, preparing an up-to-date A archive, and writing forward declarations.
In some cases, you will need to adjust the arguments to the MinGW preprocessor, cpp, to make sure that all header files are properly included and that certain macros are predefined correctly.
What I recommend is just trying it. You will definitely encounter problems, but you can usually find a solution to each by searching on the Internet or asking someone. If for no other reason, you should try it to learn more about C++, differences between compilers, and what standards-compliant code is.

Is it possible to use libraries build under VC++ in cygwin gcc build?

I have libraries which are build using VC++. I want to use the same libraries in a program and build in cygwin gcc compiler. Is this scenario will work?
Since C++ doesn't have a standardized ABI, and since Visual C++ and g++ in particular almost certainly have different ABIs, I don't think you can do this. Your only real option is to restrict yourself to C, not C++.
Edit: If all of the libraries that you're using are straight C (extern "C", in C++ terms), then you ought to be able to share libraries between compilers. (Otherwise, your Cygwin and MinGW apps couldn't call the Windows API.) You'll need to be careful to match up calling conventions. For example, the Windows API uses __stdcall instead of the standard C calling convention. You can tell GCC which calling convention to use with function attributes. Google, and your library's header files, should have more information on what calling convention to use.
Probably not
There is mingw a port of GCC (and lots of gnu tools) to windows which uses standard windows libs - it's pretty much a drop in replacement for cygwin and should be easier to link to gcc.

Difference between CC, gcc and g++?

What are the difference between the 3 compilers CC, gcc, g++ when compiling
C and C++ code in terms of assembly
code generation, available libraries, language features, etc.?
The answer to this is platform-specific; what happens on Linux is different from what happens on Solaris, for example.
The easy part (because it is not platform-specific) is the separation of 'gcc' and 'g++':
gcc is the GNU C Compiler from the GCC (GNU Compiler Collection).
g++ is the GNU C++ Compiler from the GCC.
The hard part, because it is platform-specific, is the meaning of 'CC' (and 'cc').
On Solaris, CC is normally the name of the Sun C++ compiler.
On Solaris, cc is normally the name of the Sun C compiler.
On Linux, if it exists, CC is probably a link to g++.
On Linux, cc is a link to gcc.
However, even on Solaris, it could be that cc is the old BSD-based C compiler from /usr/ucb. In practice, that usually isn't installed and there's just a stub that fails, wreaking havoc on those who try to compile and install self-configuring software.
On HP-UX, the default 'cc' is still a K&R-only C compiler installed to permit relinking of the kernel when necessary, and unusable for modern software work because it doesn't support standard C. You have to use alternative compiler names ('acc' IIRC). Similarly, on AIX, the system C compiler goes by names such as 'xlc' or 'xlc32'.
Classically, the default system compiler was called 'cc' and self-configuring software falls back on that name when it doesn't know what else to use.
POSIX attempted to legislate its way around this by requiring the programs c89 (originally) and later c99 to exist; these are the compilers compatible with the ISO/IEC 9899:1989 and 9899:1999 C standards. It is doubtful that POSIX succeeded.
The question asks about the differences in terms of features and libraries. As before, the answer is platform specific in part, and generic in part.
The big divide is between the C compilers and the C++ compilers. The C++ compilers will accept C++ programs and will not compile arbitrary C programs. (Although it is possible to write C in a subset that is also understood by C++, many C programs are not valid C++ programs). Similarly, the C compilers will accept C programs and will reject most C++ programs (because most C++ programs use constructs not available in C).
The set of libraries available for use depends on the language. C++ programs can usually use C libraries on a given platform; C programs cannot usually use C++ libraries. So, C++ has a larger set of libraries available.
Note that if you are on Solaris, the object code produced by CC is not compatible with the object code produced by g++ -- they are two separate compilers with separate conventions for things such as exception handling and name mangling (and the name mangling is deliberately different to ensure that incompatible object files are not linked together!). This means that if you want to use a library compiled with CC, you must compile your whole program with CC. It also means that if you want to use one library compiled with CC and another compiled with g++, you are out of luck. You have to recompile one of the libraries at least.
In terms of quality of assembler generated, the GCC (GNU Compiler Collection) does a very good job. But sometimes the native compilers work a bit better. The Intel compilers have more extensive optimizations that have not yet been replicated in GCC, I believe. But any such pontifications are hazardous while we do not know what platform you are concerned with.
In terms of language features, the compilers all generally hew fairly close to the current standards (C++98, C++2003, C99), but there are usually small differences between the standard language and the language supported by the compiler. The older C89 standard support is essentially the same (and complete) for all C compilers. There are differences in the darker corners of the language. You need to understand 'undefined behaviour', 'system defined behaviour' and 'unspecified behaviour'; if you invoke undefined behaviour, you will get different results at different times. There are also many options (especially with the GCC) to tweak the behaviour of the compiler. The GCC has a variety of extensions that make life simpler if you know you are only targetting that compiler family.
CC is an environment variable referring to the system's C compiler. What it points to (libraries accessible, etc) depend on platform. Often it will point to /usr/bin/cc, the actual c complier (driver). On linux platforms, CC almost always points to /usr/bin/gcc.
gcc is the driver binary for the GNU compiler collection. It can compile C, C++, and possibly other languages; it determines the language by the file extension.
g++ is a driver binary like gcc, but with a few special options set for compiling C++. Notably (in my experience), g++ will link libstdc++ by default, while gcc won't.
I wanna add just one information what cc in Linux. It is linked with gcc. To check it.
Similarly, the same thing with c++.
uddhavpgautam#UbuntuServer1604:~/Desktop/c++$ whereis c++
c++: /usr/bin/c++ /usr/include/c++ /usr/share/man/man1/c++.1.gz
uddhavpgautam#UbuntuServer1604:~/Desktop/c++$ ls -l /usr/bin/c++
lrwxrwxrwx 1 root root 21 Jul 31 14:00 /usr/bin/c++ -> /etc/alternatives/c++
uddhavpgautam#UbuntuServer1604:~/Desktop/c++$ ls -l /etc/alternatives/c++
lrwxrwxrwx 1 root root 12 Jul 31 14:00 /etc/alternatives/c++ -> /usr/bin/g++