Use of MSVC-compiled Boost binaries in a MinGW-compiled project - c++

I've downloaded Boost Binaries from here. My project depends on boost_system and boost_filesystem, and builds correctly if I add the proper dependencies to Linker Options when using Visual Studio for compilation, but I'm now trying to compile under Code::Blocks (MinGW compiler) and running into the following:
"directve `/FAILIFMISMATCH:"_MSC_VER=1800" /FAILIFMISMATCH:"_ITERATOR_DEBUG_LEVEL=0" /FAILIFMISMATCH:"RuntimeLibrary=MD_DynamicRelease" /DEFAULTLIB:"msvcprt" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" "
Though that's a warning, it keeps me from finding the dependencies, because my project fails to build with undefined reference to 'boost::system::generic_category()' and plenty of other related undefined references.
Question: Should I compile Boost from source using MinGW, in order to solve my problem?
Of course, I'm using the proper libraries for my build configuration (Release, dynamic runtime library).

I'm making an answser based on the comments posted below my question, just to make things proper.
So, building boost from the source code using the same compiler (I used TDM-GCC with gcc 4.8.1) did solve the linking issues.
As noted by Rup, one "can't mix C++ compiled with GCC and Visual Studio: they have different C++ ABI implementations, and generate different 'manglings' of identifier names so that linker symbols won't match up."
Additional reference: Interoperability of Libraries Created by Different Compiler Brands

Related

Linking a MinGW library to a MSVC app with a C interface

I'm trying to link to the OpenAL soft library as compiled with the Media Autobuild Suite, and I'm getting the following error from Visual Studio:
libopenal.a(source.cpp.o) : fatal error LNK1143: invalid or corrupt file: no symbol for COMDAT section 0xA
My application is in C++ and compiled directly in Visual Studio 2019 (however, with the VS2017 toolset). OpenAL soft is written in C++ but exposes a C interface, and the MAB Suite compiles using MinGW/gcc and generates a libopenal.a static library file.
I've read from multiple other questions such as From MinGW static library (.a) to Visual Studio static library (.lib) and How to use libraries compiled with MingW in MSVC? that object files compiled with different compilers are generally not compatible for C++ due to name mangling, but often are compatible with C linkage. Because C does not use name mangling, and because the ABI is (usually) OS-dependent, libraries with a C interface compiled on the same platform are generally compatible.
Nevertheless, I've been running into linker errors, namely the LNK1143 above. I've confirmed that the included headers use extern "C" { to hint C linkage and that the target platform (x64) is the same for both builds. I also linked to libgcc.a as this answer recommends, and did not get any linker errors for it.
Does this mean the claim that C interfaces are generally compatible across compilers is not true? Or is this a special case in which it's not working? If the latter, what could be causing the linking to fail? Would I have better luck if I recompiled as shared libraries (dlls) instead of static libraries (even if I still use MinGW's .a files instead of .lib)?
I cannot change compilers from MSVC for my main app. I intend to use more libraries from the MAB Suite in the future, so I'd prefer to stay with MinGW for those dependencies if possible because I don't want to recompile all 70+ by hand.
Any help is appreciated. Thanks in advance.
Mixing compilers is tricky and prone to issues.
In some very simple cases it may work, but there are definitely a number of cases where you will run in to issues, for example:
if the different components use different runtime libraries
if memory management is being mixed (e.g. forget about freeing memory allocated with malloc() in MSVC using free() in MinGW)
when using exception handling in C++
My advice to do it all with the same compiler (and even the same version of this compiler).
Specifically in your case OpenAL can be built with MinGW-w64. So maybe you should look into that instead of downloading some prebuilt version from the web.
Or - somewhat easier - use MSYS2 and use its pacman package manager to get its own MinGW-w64 build of OpenAL.
I figured out what works for me, so I'll share.
I was not able to link a static library between compilers as I originally attempted. My understanding is that the extra info kept in the lib to allow link-time code generation is compiler-specific. Brecht Sanders's answer outlines a few possible reasons why the code wouldn't be compatible.
I was, however, able to link to a shared library, with a few extra steps.
Using the same suite (see the question), I compiled as shared and got libopenal.dll, libopenal.dll.a, and libopenal.def. In my case, the .def file was generated by the suite. Accoding to this answer, you can generate a .def file with gcc using:
gcc -shared -o your_dll.dll your_dll_src.c -Wl,--output-def,your_dll.def
Trying to link to libopenal.dll.a still gave me errors (I don't know exactly why, and I already discarded the logs.) What I did instead was generate a .lib file from the .def file. In Visual Studio's built-in terminal:
lib /machine:x64 /def:libopenal.def
This generated a libopenal.lib file in the working directory. Linking to this file worked perfectly, and I was able to successfully load the dll at runtime.
I've tested this same method with many other MinGW-compiled libraries from the suite, including libavformat, libavcodec, libavutil, libavdevice, swresample, and swscale, and thus far all of them have worked.
Kind of convoluted, but it seems to work well for me, so I hope this helps anyone else with the same problem.

Build boost library with specific name

I am trying to compile my program, which uses boost library, with MSVC 2013 and I get link error:
Cannot open input file boost_iostreams-vc120-1.57.lib
I already built boost successfully a few times with many combinations of options (for example "bjam toolset=msvc --build-type=complete"), but I don't have boost_iostreams-vc120-1.57.lib in my stage directory. I have there libraries with names libboost_iostreams.lib, libboost_iostreams-vc-120-mt-1_57.lib and others. Also I don't want to change any settings in MSVC, because my project was generated by CMake.
So the question is: How do I build library boost_iostreams-vc120-1.57.lib with Windows?
Thanks for answers and sorry for my english
-mt suffix means build with multithreading support that is always on for MSVC. Single threaded CRT was dropped in VS 2008 or even 2005, so both your code and boost will be multithreading aware anyway. If you don't want to change your build config you can simply remove "-mt" suffix from libraries names. But since boost has MSVC autolink support (#pragma comment (lib, "...") in header files) it may be better to make an exception for MSVC and not to link to boost libraries manually at all.

Issues with Boost Linking/Build in Dev-C++

I'm trying to compile a personal program that uses the Boost/Regex library in Orwell Dev-C++ with TDM-GCC 4.8.2 64 bit Release, and when I attempt to initialize a Boost::Regex object I get these error messages.
text$_ZN5boost9re_detail27cpp_regex_traits_char_layerIcEC2ERKNS0_21cpp_regex_traits_baseIcEE[_ZN5boost9re_detail27cpp_regex_traits_char_layerIcEC2ERKNS0_21cpp_regex_traits_baseIcEE]+0x2b): undefined reference to `boost::re_detail::cpp_regex_traits_char_layer<char>::init()'
regex_tester_main.cpp:(.text$_ZN5boost9re_detail11raw_storage6extendEy[_ZN5boost9re_detail11raw_storage6extendEy]+0x5f): undefined reference to `boost::re_detail::raw_storage::resize(unsigned long long)'
regex_tester_main.o: bad reloc address 0x5f in section `.text$_ZN5boost9re_detail11raw_storage6extendEy[_ZN5boost9re_detail11raw_storage6extendEy]'
I've followed this guide to install Boost and I used gcc as my toolkit parameters for the bootstrap.bat and the b2 builder. I've included the include and lib paths in my includes and library options. And lastly linked the appropriate libboost_regex*.a file. Before this I tried using the mingw toolkit option for the bootstrap and gcc option for b2 like the tutorial linked above does, and encountered the same errors. Can anyone shed insight into what has gone wrong?
SOLVED!
I also have the Haskell GHC installed which comes packaged with a mingw/GCC package which was located earlier in the PATH environment variable than the TDM-GCC/minGW-64 package I was aiming to use to build Boost. And so when I specified my toolset it was targeting the wrong complier and thus when I tried to build other programs with Boost it probably ran into some name-mangling issues. I removed GHC's mingw/GCC complier package from PATH and rebuilt Boost, it complies and links fine now :).

g++ linking issues: undefined reference to functions

I used CMake and Visual C++ to build the HyDE library. Then, still in VC++, I was able to successfully create code and build an executable that links into HyDE.lib and the HyDE header files.
I then discovered that in order to work with others at my company, it would be preferable to develop in Eclipse CDT. Knowing very little about Eclipse CDT, I created a default hello world project, deleted the code and then dumped in all of my code into the src folder. Then I attempted to change the includes and lib path and libs to mirror what had worked in VC++. At this point everything seems to compile, but I get an error in linking:
/cygdrive/c/EclipseWorkspace/425HyDE/Debug/../src/FS5HyDE.cpp:16: undefined reference to `HyDEAPI::HyDE::HyDE(HyDESystemModel::SystemModel*, bool)'
(There are many more errors like this, all referring to HyDE methods.) Here is what is being run at the command line:
g++ -L"C:\Progra~1\boost\boost_1_42\lib" -L"C:\EclipseWorkspace\HyDE" -o"425HyDE.exe" ./src/Adapter_FS5HyDE.o ./src/EPSCommands.o ./src/EPSCurrentSensor.o ./src/EPSFault.o ./src/FS5HyDE.o ./src/HyDEObservation.o ./src/MCDH.o ./src/MCDH_Module.o ./src/PDBComponent.o ./src/PowerSystem.o ./src/Program.o ./src/SSPCComponent.o ./src/Telemetry.o ./src/TelemetryReport.o -l:libboost_thread-vc90-mt-gd-1_42.lib -lHyDE
This is definitely not a library ordering problem because I've the other ordering as well (there are only two). Is it possible that there is a problem with compiling HyDE.lib in VC++ (which uses a Windows compiler) and compiling my program with g++? Could there be a problem in the way that Eclipse CDT is autogen'ing the makefiles? Any other ideas?
(Note: there appear to be plenty of others questions on SO with similar problems, but after reading through them I have yet to find one that addresses my problem.)
Classic missing symbol error. Which source file defines:
HyDEAPI::HyDE::HyDE(HyDESystemModel::SystemModel*, bool)' ?
Was this file added to the compilation? Can you spot it on the command line you pasted?
If this symbol belongs to an external library, after adding the directory path with -L , you could add the name of the specific library you want to link with your program using -l.
I'm going to suggest that you try to add to the compilation command the directory path to HyDE.lib, followed immediately by the library name, like this:
-L"C:\path_to_hyde_library" -l:HyDE.lib
and then tell us what happened.
Solution: Since the HyDE library was compiled with the Visual Studios compiler and I'm attempting to build the code that links to it with the Cygwin toolchain the two compilers use different name mangling schemes so that the latter linker can not find the expected symbols in the HyDE library. The only solution that I've found is to recompile the HyDE library with the Cygwin toolchain or compile the new code with whatever compiler Visual Studios is using. (grumble grumble)
./src/FS5HyDE.o and ./src/HyDEObservation.o should be the latest parameter if other object files (*.o files) need them, it means that the most needed object files should be appeared as last as possible in the parameters list.

Mysql++ "undefined reference to __imp___ZN7mysqlpp10ConnectionC1Eb"

I am trying to install the mysql++ in Code::Blocks, but When I try to run the example code I get this error:
undefined reference to __imp___ZN7mysqlpp10ConnectionC1Eb
What I am doing wrong?
You must build MySQL++ with the exact same compiler and compiler options as you're using to build your program. What you're seeing is a name mangling and/or ABI mismatch due to mixing compilers and/or build options. This can be anything from a drastic error like trying to use a Visual C++ DLL with MinGW, to something more subtle like trying to use a MinGW DLL built with g++ 3.4.5 in a program you're building with MinGW g++ 4.4.
Unlike C, C++ doesn't try to preserve binary compatibility between greatly different compilers.
You probably have a linker issue. It could well be that a DLL you need isn't present, or mysql++ was compiled but not correctly linked.