How can I see what libraries Mingw32 links by default? - c++

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.

Related

undefined reference to std::__cxx11::basic_string when linking to boost [duplicate]

I use c++11, but also some libraries that are not configured for it, and need some type conversion. In particular I need a way to convert std::__cxx11::string to regular std::string, but googling I can't find a way to do this and putting (string) in front does not work.
If I do not convert I get linker errors like this:
undefined reference to `H5::CompType::insertMember(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, H5::DataType const&) const'
Is it possible that you are using GCC 5?
If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC. If the third-party library cannot be rebuilt with the new ABI then you will need to recompile your code with the old ABI.
Source: GCC 5 Release Notes/Dual ABI
Defining the following macro before including any standard library headers should fix your problem: #define _GLIBCXX_USE_CXX11_ABI 0
If you can recompile all incompatible libs you use, do it with compiler option
-D_GLIBCXX_USE_CXX11_ABI=1
and then rebuild your project. If you can't do so, add to your project's makefile compiler option
-D_GLIBCXX_USE_CXX11_ABI=0
The define
#define _GLIBCXX_USE_CXX11_ABI 0/1
is also good but you probably need to add it to all your files while compiler option do it for all files at once.
When I had similar issue it's happened because my lib was build using clang++, and it's linked to libstdc++.so by default on my system. While app binary was build using clang and linked with -lc++ option.
Easiest way to check dependencies is to perform ldd libName.so
To fix it you should use the same library on in app and library.
Easiest way. Build library using clang++ and compile app using clang++. Without extra linking options on both steps. Default stdlib will be used.
Build library with -stdlib=c++ and compile app with -lc++. In this case both library and app will use libc++.so.
Build library without extra options and link binary to -lstdc++. In this case both library and app will use libstdc++.so.
Answers here mostly focus on short way to fix it, but if that does not help, I'll give some steps to check, that helped me (Linux only):
If the linker errors happen when linking other libraries, build those libs with debug symbols ("-g" GCC flag)
List the symbols in the library and grep the symbols that linker complains about (enter the commands in command line):
nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout
If you got the method signature, proceed to the next step, if you got no symbols instead, mostlikely you stripped off all the symbols from the library and that is why linker can't find them when linking the library. Rebuild the library without stripping ALL the symbols, you can strip debug (strip -S option) symbols if you need.
Use a c++ demangler to understand the method signature, for example, this one
Compare the method signature in the library that you just got with the one you are using in code (check header file as well), if they are different, use the proper header or the proper library or whatever other way you now know to fix it
I got this, the only way I found to fix this was to update all of mingw-64 (I did this using pacman on msys2 for your information).
For me -D_GLIBCXX_USE_CXX11_ABI=0 didn't help.
It works after I linked to C++ libs version instead of gnustl.
I had a similar issue recently while trying to link with the pre-built binaries of hdf5 version 1.10.5 on Ubuntu 16.04. None of the solutions suggested here worked for me, and I was using g++ version 9.1. I found that the best solution is to build the hdf5 library from source. Do not use the pre-built binaries since these were built using gcc 4.9! Instead, download the source code archives from the hdf website for your particular distribution and build the library. It is very easy.
You will also need the compression libraries zlib and szip from here and here, respectively, if you do not already have them on your system.
In my case, I was having a similar problem:
/usr/bin/ld: Bank.cpp:(.text+0x19c): undefined reference to 'Account::SetBank(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' collect2: error: ld returned 1 exit status
After some researches, I realized that the problem was being generated by the way that Visual Studio Code was compiling the Bank.cpp file. So, to solve that, I just prompted the follow command in order to compile the c++ file sucessful:
g++ Bank.cpp Account.cpp -o Bank
With the command above, It was able to linkage correctly the Header, Implementations and Main c++ files.
OBS: My g++ version: 9.3.0 on Ubuntu 20.04
I've encountered similar problems
It turns out my project was using gcc 7 and g++ 9 and tried to link together object files compiled by those two and it all messed up.
Make sure you use the same compiler versions in all your project.

How to avoid errors when linking C++ shared libs into C programs

I'm using a library that comes with the usual AutoTools generated configure && make && make install procedure. The library contains a main (shared) library and some tools and is mostly written in C.
Now I am running into a problem, where one of the builds of one of the tools fails when using an instrumenter (Score-P which wraps compiler calls to do its magic).
I narrowed it down to the following facts:
libMain uses C files and 1 C++ file, C files get compiler with gcc and C++ file with g++. The library gets linked with g++ as a shared lib.
binTool uses C files only but links against libMain.
This works without the instrumenter. However when used, it adds extra libs when linking with g++ that use C++ features. Linking binTool with gcc then gives undefined reference to 'operator delete[](void*)' (and a few similar ones)
First: Could someone explain to me, why I have to be careful when linking against a shared library (use g++ even though the binary is only using C code)? I was under the impression, that linking of shared binaries is finalized so linking that should not pull in any new dependencies or that the dependencies are already resolved (in this case libMain would know it needs libc++ and have it already referenced/stored/whatever-elf-is-doing)
Second: From reading the AutoTools docu I found that the linker for a program is chosen based on its source files. As libMain uses a C++ file it is linked with g++. binTool uses C files only hence it is linked with gcc. But binTool links also libMain which was C++-linked and seems to require to be linked with g++.
So where is the culprit? Is it AutoTools issuing the wrong linker command for binTool? Or should g++ have done something different when linking libMain?
For reference: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
ldd libMain:
linux-vdso.so.1
librt.so.1
libpthread.so.0
libm.so.6
libc.so.6
libgcc_s.so.1
libdl.so.2
libnuma.so.1
libltdl.so.7
As I commented, you can link a shared library (when building that library) with another one. See this answer for details. Read Drepper's How To Write Shared Libraries paper.
Probably, you should re-configure and re-compile and re-build your libMain. You want to link it explicitly with -lstdc++ .
Perhaps passing some LDFLAGS=-lstdc++ or LIBES=-lstdc++ to the configure of that libMain might help. See this.
BTW, there are some autoconf-ed libraries coded in C++ and callable from a pure C program (for example libgccjit), and they are linked with -lstdc++
The idea to accomplish your problem is to write a wrapper library which its header is in C and the body internally is compiled with C++ compiler so that it can call your C++ library functions.
Later you can link your C++ library with its C header to your application
I found a solution (TL&DR jump down to the fat SOLUTION):
The situation was far more difficult than I thought. What happens is:
binTool links to shared library libMain which links to a shared library libExtraCxx.
binTool is a C program, hence linked with gcc
libMain contains a C++ file and is hence linked with g++. But it does not use any C++ library features so the linker omits libstdc++ from the libMain link process.
libExtraCxx is a C library intended to be linked into C programs by means of an automatic wrapper script. As libMain uses g++ it gets libExtraCxx linked in. This library is supposed to intercept the C++ new/delete calls and does so by using the GNU -wrap linker command and internally defines (manually) mangled versions of new/delete prefixed by __wrap_ and declares mangled versions of those prefixed by __real_.
Usually this works, because when a C++ linker would be used by binTool the wrapper would issue the -wrap commands and the libstdc++ provides the __real_ functions.
However the mistake is, that the libstdc++ does never get linked: libExtraCxx is a C library that just hooks into C++ functions. libMain does not use any C++ library functions and binTool is again a C program and no shared library linked into it has libstdc++ linked into that.
So one could point to 2 problems:
libExtraCxx should have been a C++ library and links libstdc++ but I guess this "tricks" are done to explicitly avoid the dependency on a C++ library so it can be used by the GNU, Intel or Clang C++ compiler which might have different standard libraries.
libMain should have libstdc++ not omitted. This can usually be done by passing -Wl,--no-as-needed to the compiler/linker as explained here.
I can't change libExtraCxx due to the amount of work involved, but I can pass arguments to the compiler, so I went with 2.
However simply doing configure <...> LDFLAGS=-Wl,--no-as-needed did not work. The flag was used but libstdc++ was not present.
I found the culprit to be libtool which is used by libMain: libtool 2.4.2 does not pass the flag at the right position AFAIK this bug#12880 is not fixed yet, so I was searching for more.
SOLUTION
I found a hack here: Simply use CXX="$CXX -Wl,--no-as-needed". This basically makes libtool think, that the flag is part of the compiler command and it won't reorder it leaving it at the beginning.
For reference: I was using starPU so libMain was actually libstarpu-1.2.so. The failed binary (binTool) is starpu_perfmodel_display. The "fake"-C++-Library is from Score-P libscorep_adapter_memory_event_cxx.so.5 I just changed the names to simplify them.
For SCORE-P the solution is a bit more complicated as one cannot simply change CXX. So full solution to compile starPU with ScoreP is:
SCOREP_WRAPPER=off ~/Downloads/starpu-1.2.3/configure --prefix /usr/local CC=scorep-gcc CXX=scorep-g++ FC=scorep-gfortran --with-mpicc=scorep-mpicc --with-mpifort=scorep-mpif77
And
make SCOREP_WRAPPER_INSTRUMENTER_FLAGS="--opencl --thread=pthread" SCOREP_WRAPPER_COMPILER_FLAGS="-Wl,--no-as-needed"
Explanation: SCOREP_WRAPPER_COMPILER_FLAGS will cause the wrapper to pass the flags to the compiler. As libTool is using the scorep wrapper it does not even see those flags so they get transparently added.

g++ linker error despite specifying the lib files [duplicate]

I use c++11, but also some libraries that are not configured for it, and need some type conversion. In particular I need a way to convert std::__cxx11::string to regular std::string, but googling I can't find a way to do this and putting (string) in front does not work.
If I do not convert I get linker errors like this:
undefined reference to `H5::CompType::insertMember(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, H5::DataType const&) const'
Is it possible that you are using GCC 5?
If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC. If the third-party library cannot be rebuilt with the new ABI then you will need to recompile your code with the old ABI.
Source: GCC 5 Release Notes/Dual ABI
Defining the following macro before including any standard library headers should fix your problem: #define _GLIBCXX_USE_CXX11_ABI 0
If you can recompile all incompatible libs you use, do it with compiler option
-D_GLIBCXX_USE_CXX11_ABI=1
and then rebuild your project. If you can't do so, add to your project's makefile compiler option
-D_GLIBCXX_USE_CXX11_ABI=0
The define
#define _GLIBCXX_USE_CXX11_ABI 0/1
is also good but you probably need to add it to all your files while compiler option do it for all files at once.
When I had similar issue it's happened because my lib was build using clang++, and it's linked to libstdc++.so by default on my system. While app binary was build using clang and linked with -lc++ option.
Easiest way to check dependencies is to perform ldd libName.so
To fix it you should use the same library on in app and library.
Easiest way. Build library using clang++ and compile app using clang++. Without extra linking options on both steps. Default stdlib will be used.
Build library with -stdlib=c++ and compile app with -lc++. In this case both library and app will use libc++.so.
Build library without extra options and link binary to -lstdc++. In this case both library and app will use libstdc++.so.
Answers here mostly focus on short way to fix it, but if that does not help, I'll give some steps to check, that helped me (Linux only):
If the linker errors happen when linking other libraries, build those libs with debug symbols ("-g" GCC flag)
List the symbols in the library and grep the symbols that linker complains about (enter the commands in command line):
nm lib_your_problem_library.a | grep functionNameLinkerComplainsAbout
If you got the method signature, proceed to the next step, if you got no symbols instead, mostlikely you stripped off all the symbols from the library and that is why linker can't find them when linking the library. Rebuild the library without stripping ALL the symbols, you can strip debug (strip -S option) symbols if you need.
Use a c++ demangler to understand the method signature, for example, this one
Compare the method signature in the library that you just got with the one you are using in code (check header file as well), if they are different, use the proper header or the proper library or whatever other way you now know to fix it
I got this, the only way I found to fix this was to update all of mingw-64 (I did this using pacman on msys2 for your information).
For me -D_GLIBCXX_USE_CXX11_ABI=0 didn't help.
It works after I linked to C++ libs version instead of gnustl.
I had a similar issue recently while trying to link with the pre-built binaries of hdf5 version 1.10.5 on Ubuntu 16.04. None of the solutions suggested here worked for me, and I was using g++ version 9.1. I found that the best solution is to build the hdf5 library from source. Do not use the pre-built binaries since these were built using gcc 4.9! Instead, download the source code archives from the hdf website for your particular distribution and build the library. It is very easy.
You will also need the compression libraries zlib and szip from here and here, respectively, if you do not already have them on your system.
In my case, I was having a similar problem:
/usr/bin/ld: Bank.cpp:(.text+0x19c): undefined reference to 'Account::SetBank(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' collect2: error: ld returned 1 exit status
After some researches, I realized that the problem was being generated by the way that Visual Studio Code was compiling the Bank.cpp file. So, to solve that, I just prompted the follow command in order to compile the c++ file sucessful:
g++ Bank.cpp Account.cpp -o Bank
With the command above, It was able to linkage correctly the Header, Implementations and Main c++ files.
OBS: My g++ version: 9.3.0 on Ubuntu 20.04
I've encountered similar problems
It turns out my project was using gcc 7 and g++ 9 and tried to link together object files compiled by those two and it all messed up.
Make sure you use the same compiler versions in all your project.

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.

linking boost.asio

I have a problem linking boost.asio. It uses boost.system and the linker errors start with:
/boost_1_39_0/boost/system/error_code.hpp:205: undefined reference to `boost::system::get_system_category()'
which means I need to link boost.system. I already built boost and I have now several lib files.
boost_system-mgw32-d-1_39.dll and lib
libboost_system-mgw34-d-1_39.lib
libboost_system-mgw34-mt-d-1_39.lib
libboost_system-mgw34-sd-1_39.lib
and some more. How do I link them? Which one do I use? Do I copy all of them together?
My system is win32+mingw+eclipse cdt+qt 4.5.2+qt integration for eclipse. I already learned that I need to at a LIBS= section to my .pro file.
Can you give my some hints?
Thank you.
The libraries are named based on whether or not multi-threading support is enabled, static and dynamic linkage, debug and release mode, and more. Here's some details:
http://www.boost.org/doc/libs/1_39_0/more/getting_started/unix-variants.html#library-naming
I'm not sure about eclipse as I don't use it, but with gcc (and mingw) you need to specify both a directory to find the libraries in (-L) and the file to link with. For example, if you wanted to link with the single-threaded debug version:
-L/path/to/libraries -lboost_system-mgw34-sd-1_39