Link iOS app against both libstdc++ and libc++ - c++

Use case: I want to use a 3rd party static library that uses libstdc++ (cannot be changed), so I have to link my app against libstdc++. Now if I want to use C++11 features in my own code, I'd have to select libc++ in Xcode and additionally link against libstdc++ to satisfy the static library.
My problem is that even though I selected libc++ in "Build settings" and added "-lstdc++" to "Other linker flags" (also tried via "Build phases > Link Binary With Libraries"), I'm getting linker errors for the latter, that is for libstdc++ functions/classes referenced by the 3rd party lib.
How can I configure the project to link against both C++ standard libraries? It should theoretically be possible since libc++ will be in its own inline namespace std::__1.

I just ran into this , and my solution was that instead of adding -lstdc++ on the other flags, that you put /usr/lib/libstdc++.dylib.
My hunch is that when xcode/clang has -std=c++ set, the older .dylib needs to be explicitly loaded.

Related

Built GCC 5.4 from source; executables thus built try to link incompatible libstdc++ and fail to run

I have followed instructions to build GCC from source. The only modifications I made for the configure were:
using a binary suffix of -5.4 so that I can use the compiler as g++-5.4 for instance.
setting --configure-multilib because it wouldn't run otherwise.
I'm doing this for testing some of my code by compiling it with various different compilers. On this Centos 7 system I've got the system gcc (4.8.2) as well as clang (also compiled from source) running, and now I'd like to see 5.4 working.
Based on these instructions, inside the source code I've put these statements to make the linker happy.
#define _GLIBCXX_USE_CXX11_ABI 0
Now that the executables compile and link, I'm getting this when I run them...
/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by <program name>)
I can't quite tell here but I do know enough to see that the actual symlink /usr/lib64/libstdc++.so.6 links to the older one (/usr/lib64/libstdc++.so.6.0.19), and the one built as part of GCC 5.4 lives somewhere else (/usr/local/lib64/libstdc++.so.6.0.21). This would indicate that this program I built using 5.4 is looking at the right (old) stdlib shared lib, so something else is amiss.
The new compiler is generating code which expects to be linked to the newer libstdc++, rather than the system one. The linker finds that this expectation is not met, so it throws an error.
To fix this you will have to ensure that the correct path is being used to find and link libstdc++. There are a few options:
Use the -rpath linker option. This option adds a path to the directories to be used during dynamic linking. As it is a linker option, you pass it through using -Wl,<option> when invoking the compiler, for example:
g++ ... -Wl,-rpath=/usr/local/lib64 .... You may also need to add the path using the -L option.
Set environment variable LD_LIBRARY_PATH at runtime
See also: compiler-libstdc-version-vs-system-version
Since you are using Centos, you may also want to check out the devtoolset collection, which allows a parallel installation of newer GCC toolsets.
This would indicate that this program I built using 5.4 is looking at the right (old) stdlib shared lib
... as far as I can see, that is the wrong library, isn't it? Because it the program is built with the new g++ version, it should be using the new libstdc++, i.e. the one in /usr/local/lib64/libstdc++.so.6.0.21.
So then you might need to prepend that path to LD_LIBRARY_PATH to be able to load the program.

How can I see what libraries Mingw32 links by default?

I'm using Mingw32 compiler to build a C++ app.
I'm passing -nostdlib to the linker because I only want to link the libraries I'm going to actually use.
However I'm running into a problem with the C++ standard library.
When I link with libstdc++ I get the following error:
undefined reference to '_Unwind_SjLj_Register'
So clearly libstdc++ isn't the right library to link with.
Is there any way of seeing what libraries Mingw32 links with by default when building a C++ app?
What libraries are being excluded when the flag -nostdlib is passed to linker?
Thanks.

C++11 and static library that is linked against libstdc++

I have a library which is a static library for C and C++.
The problem is that the library is linked against libstdc++.
In Xcode when I switch to libc++ (to use C++11 features and use the mentioned C++ library) it throws many compile errors.
The authors of the library say that the library is not ready for C++11.
Is there still a way to use both?
Your 3-rd party static library should be linked against the same version of the C++ library it was compiled against. This includes not only the type of library (libstdc++), but also major/minor version numbers to ensure ABI compatibility. Any different library version would get you either build breaks in best case, or weird crashes in worst case. Read more about ABI versioning in GCC manual.
If the interface for 3-rd party library only has POD types, you can make a shared library out of your static library, and then use it from your app linked with libc++.

Link to specific stdc++ library

I have a c++ application which I am trying to build under Linux, it needs to be linked to a third party shared library, however this library has been built with a quite recent version of GCC/glibc (4.8.3/2.18). When I try and build my application using a less recent version of GCC/glibc (4.4.7/2.12), the linked phase of the build fails, with ld complaining of undefined references, which are references to functions defined in the newer libstdc++.
The third party has given me a precompiled version of libstdc++ and libgcc_s to use with the library, but how do I use these versions in my build?
How do I tell GCC to use the precompiled libraries instead of the system ones, while still using the system GCC?
I have tried using the "-nodefaultlibs" option and including "-lstdc++" and "-L" options, but it seems to have no effect on the undefined references.
Example of an error I get during linking:
undefined reference to std::__throw_bad_function_call()#GLIBCXX_3.4.14'
undefined reference to std::length_error::~length_error()#GLIBCXX_3.4.15'
I managed to get the application to build successfully by specifying the full path of the libstdc++ and libgcc_s shared objects in the objects list of the linking command (e.g. /home/mike/Downloads/libstdc++.so.6) . Going this way I didn't need to use any additional options such as "-nostdlibs" and only needed to ensure the linked shared objects were available via the LD_LIBRARY_PATH when running the application.

Compiled shared library has dependency on specific libicuuc.so.46 version

I am compiling a shared library using g++ on SUse Linux with cmake that depends on libicuuc.so and friends.
Suse has libicuuc.so, libicuuc.so.46 and libicuuc.so.46.1 in /usr/lib.
Now when I use ldd to list the dependencies of my library it tells me that it depends on libicuuc.so.46.
Since I want to distribute my library in binary form (it takes about 45 minutes to compile on a fast PC) this dependency is a problem. The target PCs have different versions of libicuuc.so.
What can I do so that my library depends on libicuuc.so and not libicuuc.so.46?
I tried to remove the so.46 versions in my /usr/lib folder before compiling but libicuuc.so depends on libicudata.so.46 so I keep that dependency on a 46 version what I try to avoid.
Read about external library versioning here.
What can I do so that my library depends on libicuuc.so and not libicuuc.so.46?
You can't do anything about that. The libicuuc.so that you have has SONAME set to libicuuc.so.46, and the linker dutifully records that dependency (as it should).
If developers release libicuuc.so.47, they would do so because the new library is not ABI-compatible with the old one (at least that's what they should do if they are not clueless).
If your library loaded libcuuc.so.47 (as you want it to), it would most likely crash due to the ABI incompatibility. Or worse: corrupt your end user's data. So achieving your desired result would get you into worse trouble than what you have now (not running is better than randomly crashing or corrupting data).
Update:
The libicuuc.so documentation explicitly states that "Binary compatibility is for versions that share the same major+minor number."
That means: you can't link a library compiled with version 4.6 (SONAME libicuuc.so.46) and expect it work with version 4.7.
You must either rebuild your library for each version of ICUUC, or distribute matching libicuuc.so.NN with your library (and hope that the user is not already using some other version of libicuuc).
Another possible alternative: statically link libicuuc.a into your library, and hide all of libicuuc.a symbols so they don't conflict with anything else. Note: this has licensing implications.