Are C and C++ .lib files portable? - c++

Assuming the code compiled is actually portable (just using standard library stuff or whatever), could I use the same .lib for my projects across multiple platforms, or can they only run on the platform they were compiled on?
I'm porting my C++ project from Windows to Linux and I use a few 3rd party libraries including openAL, FreeType and FreeImage, and I would like to know if I have to get/recompile new library files.

The dynamic linkers on Windows and Linux work in completely different ways. On Linux the linker will expect elf format .so files. Windows however uses .lib and .dll files which are in a different, incompatible format.
Even if you were to find a way around this, the default calling conventions between the two OSes are different. C function calls place the arguments into different registers so it would be impossible to call functions in these lib files without having the compiler use a custom calling convention, however this would prevent any other code from calling your libraries.
The Wine Project has created a compatibility layer to allow Windows binaries to call into libraries compiled for Linux, however there is a significant performance and complexity penalty to such a layer.
In short, you would be best off in nearly every case to recompile the project for both OSes separately. The libraries you mention (afaik) are all available for Linux also so porting should be a breeze.

The entire purpose of languages like C++ is to provide a platform-agnostic source code abstraction that is portable, because the code created by compiling your C++ is not.
You shall have to rebuild it for your target platform.

.lib files contain platform-specific object code. You will need different ones for each platform.
You will have to recompile the other libraries on each platform you port to.

Related

qt dll compatibility between compilers

Qt library states binary compatibility across major releases. But what about compatibility between different compilers?
For example, I have an application and 2 dlls that use Qt (dynamically linked). But one of them is built with MSVC and the other with MinGW. Thus they are linked to different builds of Qt library (of the same version).
The question is: is it possible for these dlls to work together using one shared Qt dll?
If not then what workarounds are possible considering that changing the compiler is not an option?
I looked at Qt dlls with dependency walker and I see that there are dozens of exported functions which have compiler-scpecific name mangling. So it seems that it is not possible to make them work together.
C++ does not have standard ABI. That means, binaries including DLL files aren't usually compatible between compilers (they may not even be compatible between different build options on same compiler...). This is is the case with MSVC vs. MinGW, no DLL compatibility.
Plain C libraries have a defined ABI on Windows, so they may be used with any compiler (you may still run into problems with libraries having incompatible dependencies, even if ABI is compatible).
If recompiling one library is not an option, then the only workaround I know is to have separate processes, which then communicate using some IPC mechanism. If both libraries offer GUI elements, and you want to mix them in same GUI, that's not possible (or at least it is hard, you need to open window of other app in the window of another, sort of like an overlay).

Compiler Libraries vs. Operating System Libraries

I noticed that both my compiler (MinGW) and the Windows 8 SDK come with the same libraries, save the naming conventions (i.e. win32.lib on the Windows 8 SDK is libwin32.a in the MinGW libraries).
Do all compilers come with libraries such as these?
Are these libraries for multiple operating systems?
What is the difference (if any) between the libraries that come with the Windows 8 SDK and those that come with the compiler?
There are two kinds of libraries:
Import libraries:
These libraries only list where to find references to variables/functions/etc., but they don't contain the code itself.
"Normal" libraries (which contain object files that contain machine code):
These libraries contain object files, which contain the actual machine code.
The libraries that ship with an operating system are generally import libraries.
The actual code, after all, is in the operating system itself; the import libraries merely tell you how to use the code provided in the operating system.
Why is this necessary? Because there is no way for a program to "discover" the libraries available on an operating system while it is running, so the program has to know what will be available when it is compiled.
Those that come with a compiler are generally code libraries; they contain code that the compiler requires (which varies depending on your particular compiler) in order to comple your program.
However, there is no single "standard format" for a library; Microsoft uses COFF, but *nix tools use ELF.
So when Microsoft ships the import libraries for a system, it only ships them in COFF format, which is great for the Visual C++ compiler -- but not so useful for other compilers.
This causes compiler vendors such as MinGW to be forced to create their own import libraries for the operating systems which they intended to target -- the purpose of these libraries is exactly the same as as those provided by the operating system vendor (such as Microsoft), but their format is different.
That's why you see seemingly similar libraries provided in multiple ways.
MinGW comes with its own set of SDK libraries for the simple reason that MinGW is intended to provide a freely available compiler implementation that can produce Windows programs, but the Windows SDK is not freely available in the sense that the MinGW developers want/need. Because of the license on the Microsoft Windows SDK, it is not something that can simply be distributed with the MinGW compiler. So a significant part of the MinGW development effort is a set of headers and libraries that provide the Windows SDK functionality without infringing on Microsoft's licensing terms.
A fair bit of the MinGW WinSDK is public domain (maybe even most or all of it). All of it is freely distributable open source.
There may also be compatibility issues with MinGW using MS object files and libraries, but I was surprised to find that MinGW can often link to object files and libraries produced by MS compilers (though I'm not sure if there are any guarantees that it is supported).
A related issue is that MinGW relies heavily on the msvcrt.dll C runtime DLL provided by Microsoft. But that DLL is not distributed by MinGW - it's a part of every Windows OS, so MinGW relies on it simply being present as a base OS facility.

Is it possible to use same DLL for clients using both Windows and Linux

I am looking to create a C++ library that can be used by both Linux and Windows clients. The OS specific functionality will be hooked up by the client by implementing the interfaces provided by the library.
Is this possible to achieve? Do I need to recompile the C++ project again in linux.
P.S: I am using CodeBlocks IDE
The short answer is no, you still need to compile your library for each targetted platform -- however, assuming your code is written such that it is cross-platform, you can set up your build to target both Windows and Linux environments with little fuss. I do this now using CMake to generate both Visual Studio projects for Windows environments and Makefiles for Linux environments.
I'm pretty confident that Linux will not accept a .dll :) And yes, you will need to recompile. Unless you run windows as a virtual machine under linux which sort of preempts the question.
It certainly cannot be the same binary file: shared objects ELF format on Linux, DLL "PE" format on Windows. And dynamic loading has different semantics on both systems. See Levine's linker and loader book for details.
You could, if done carefully, have the same source code giving the two different files (the DLL on Windows, the dynamic shared object on Linux).
But you probably would need some conditional compilation tricks like #ifdef WINDOWS etc...
You might use libraries providing you a common abstraction for such things. For instance, both GTK/Glib and Qt have some mechanism giving a common abstraction of dynamically linked (or dynamically loaded - ie dlopen-ed) libraries.
You probably want to read the Program Library Howto (at least for Linux).

Convert from MinGW .a to VC++ .lib

I have an old library (in C++) that I'm only able to build on MinGW+MSYS32 on Windows. From that I can produce a .a static library file generated from GNU libtool. My primary development is done in Visual Studio 2008. If I try to take the MinGW produced library and link it in Visual Studio, it complains about missing externals. This is most likely due to the C++ symbol mangling that is done, and that it doesn't match whats in the .a file. Is there any know way to convert a static .a file to VC++ library format?
If symbols are mangled differently, the compilers are using a different ABI and you won't be able to "convert" or whatever the compiled libraries: the reason names are mangled in different ways is intentional to avoid users from ever succeeding with building an executable from object files using different ABIs. The ABI defines how arguments are passed, how virtual function tables are represented, how exceptions are thrown, the size of basic data types, and quite a number of other things. The name mangling is also part of this and carefully chosen to be efficient and different from other ABIs on the same platform. The easiest way to see if the name mangling is indeed different is to compiler a file with a couple of functions using only basic types with both compilers and have a look at the symbols (on UNIX I would use nm for this; I'm not a Windows programmer and thus I don't know what tool to use there).
Based on Wikipedia it seems that MinGW also uses a different run-time library: the layout and the implementation of the standard C++ library used by MinGW (libstdc++) and Visual Studio (Dinkumware) is not compatible. Even if the ABI between the two compilers is the same, the standard C++ library used isn't. If the ABI is the same you would need to replace set things up so that one compiler uses the standard library of the respective other compiler. There is no way to do this with the already compiled library. I don't know if this is doable.
Personally I wouldn't bother with trying to link things between these two different compiler because it is bound not to work at all. Instead, you'd need to port the implementation to a common compiler and go from there.
Search for the def file and run the command e.g. lib /machine:i386 /def:test.def it will generate
an import lib file.

C++ Dynamic Library Compiling/Linking

I know that if I link my c++ program to a dynamic library (DLL) that was built with a different version of Visual Studio, it won't work because of the binary compatibility issue.
(I have experienced this with Boost library and VS 2005 and 2008)
But my question is: is this true for all versions of MSVS? Does this apply to static libraries(LIB) as well? Is this an issue with GCC & Linux as well? and finally how about linking in VS to a DLL built with MinGW?
By the way aside from cross-platform or cross-compiler, why can't two version of the same compiler(VS) be compatibile?
Hi. I know that if I link my c++ program to a dynamic library (DLL) that was built with a different version of Visual Studio, it won't work because of the binary compatibility issue. (I have experienced this with Boost library and VS 2005 and 2008)
I do not remember ever seeing MS changing the ABI, so technically different versions of the compiler will produce the same output (given the same flags (see below)).
Therefore I don't think this is not incompatibilities in Dev Studio but changes in Boost.
Different versions of boost are not backwards compatible (in binary, source they are backward compatible).
But my question is: is this true for all versions of MSVS?
I don't believe there is a problem. Now if you use different flags you can make the object files incompatible. This is why debug/release binaries are built into separate directories and linked against different versions of the standard run-time.
Does this apply to static libraries(LIB) as well?
You must link against the correct static library. But once the static library is in your code it is stuck there all resolved names will not be re-resolved at a later date.
Is this an issue with GCC & Linux as well?
Yes. GCC has broken backwards compatability in the ABI a couple of times (several on purpose (some by mistake)). This is not a real issue as on Linux code is usually distributed as source and you compile it on your platform and it will work.
and finally how about linking in VS to a DLL built with MinGW?
Sorry I don't know.
By the way aside from cross-platform or cross-compiler, why can't two version of the same compiler(VS) be compatibile?
Well fully optimized code objects may be compressed more thus alignment is different. Other compiler flags may affect the way code is generated that is incompatible with other binary objects (changing the way functions are called (all parameters on the stack or some parameters in registers)). Technically only objects compiled with exactly the same flags should be linked together (technically it is a bit looser than that as a lot of flags don't affect the binary compatibility).
Note some libraries are released with multiple versions of the same library that are compiled in different ways. You usually distinguish the library by the extension on the end. At my last job we used the following convention.
libASR.dll // A Sincgle threaded Relase version lib
libASD.dll // A Single threaded Debug version
libAMR.dll // A Multi threaded Release version
libAMD.dll // A Multi threaded Debug version
If properly built, DLLs should be programming-language and version neutral. You can link to DLLs built with VB, C, C++, etc.
You can use dependency walker to examine the exported functions in the dll.
To answer part of your question, GCC/Linux does not have this problem. At least, not as often. libstdc++ and glibc are the standard C++/C libraries on GNU systems, and the authors of those libraries go to efforts to avoid breaking compatibility. glibc is pretty much always backward compatible, but libstdc++ has broken ABI several times in the past and probably will again in the future.
It is very difficult to write stable ABIs in C++ compared to C, because the automatic features in C++ take away some of the control you need to maintain an ABI. Especially once you get into templates and inline functions, where some of the code gets embedded in your application rather than staying contained in the shared library. That means that the object's structure can't ever change without requiring a recompilation of the application.
In practice, it isn't a huge deal on Windows. It would be fantastic if Microsoft just made the MSI installer know how to grab Microsoft-provided DLLs from Windows Update when an app is installed that needs them, but simply adding the redistributable to an InnoSetup-generated installer works well enough.