Boost (1.50.0) Thread Library Linking with MinGW - c++

I'm trying to link the thread library of boost 1.50.0 and am having some problems. The problem is that the implementation of the thread cannot be found.
I've checked around here, on random sites and on the official manuals and concluded that there can only be one reason for this (since the actual library I'm linking contains the correct files). There is no auto-linking in MinGW. This means there can be no platform implementation for the threads available (and hence the error).
One of the errors I'm getting is:
undefined reference to `imp__ZN5boost6thread4joinEv'
that comes from myTread.join().
So my questions is, what is the library (or libraries) I need to link in addition to the boost thread library (in this case named libboost_thread-mgw46-mt-1_50.a)?
And furthermore, is there any documentation for all library dependencies in boost?
I could of course be completely wrong, so any help appreciated!
Currenty I'm linking only boosts libraries; threads, chrono and system.
EDIT
To clarify, I'm linking with the following command:
g++ -LPATH_TO_BOOST\lib -o test-boost-thread.exe src\test-boost-thread.o -lboost_thread-mgw46-mt-1_50 -lboost_chrono-mgw46-mt-1_50 -lboost_system-mgw46-mt-1_50
I've tried changing positions of the libraries, but that didn't help.

In your case, given the file name that you posted, the linker line would be -lboost_thread-mgw46-mt-1_50 (remove lib and .a/.so/.lib). There might be (or you might want to create) a symlink that points to it like libboost_thread.a -> libboost_thread-mgw46-mt-1_50.a, in which case you can use the shorter -lboost_thread.

Hmm, seems like I completely forgot about the BOOST_THREAD_USE_LIB flag. Setting this made it work.
Strange error though.

Related

BOOST & GCC, undefined reference to boost

I must say, I'm new to using Boost libs, but I have used them for a few of my projects, and have been super pleased with them.
Now, I would like to get all files with certain extension in one of my folders, so, looking it up online, I found this>How to get list of files with a specific extension in a given folder
I'm using Code Blocks on Windows 7.
I have done everything it seemed required, and when I try to compile it, I get three errors>
C:\boost_1_58_0\boost\system\error_code.hpp|221|undefined reference to
boost::system::generic_category()'|
C:\boost_1_58_0\boost\system\error_code.hpp|222|undefined reference to
boost::system::generic_category()'|
C:\boost_1_58_0\boost\system\error_code.hpp|223|undefined reference to
`boost::system::system_category()'|
I was looking it up online, and found that, besides pointing my "Search directories (compiler and linker) to boost installation, I need to point it directly to boost system lib somehow.
I tried -lboost_system in my Linker settings, but that didn't solve it.
I'm hardly an expert here, so I'm asking you guys if you can help me.
Does anyone have any ideas?
You need to provide the path where your lib is with the -L option of GCC.
Check this section of Boost documentation

First time using boost - why did I not have to explicitly link to it when building?

In answer to one of my recent questions, it was suggested that I use a function in boost to solve my problem. This is my first time using boost so I added the following .hpp file
#include <boost/algorithm/string.hpp>
and function call
boost::replace_all(marketPrices, "\\:", "-COLON-");
to my source file, then ran make to build my application using g++ as normal.
At this point I realized I had not added any new library to the link step in my makefile and fully expected the link step to fail. To my surprise it did not fail - not only that but the code ran exactly as it should have done without any complaint.
This surprises me to say the least - how did g++ know what to link to and why did it automatically do so? Or am I missing something fundamental with the way the boost libraries operate? I know that boost uses a lot of templating and this is an aspect of C++ that I am not overly familiar with so I am wondering if perhaps this has something to do with what I am seeing.
Some of the boost libraries are header-only meaning that there is no binary to link against. Other libraries like boost::thread will require you to add a new lib to the linker.

Problem linking c++ code using boost with mingw

I'm trying to port/build some of my code written for gcc (on linux) as a dll on windows. First I tried to build in under VC++ but there were so many errors/warnings (mainly in VC's own include files, which didn't really make much sense to me :)) so I installed MinGW distro (which includes Boost libraries). Compilation went quite smoothly, however linking failed with undefined references to functions from boost libraries. The "-t" parameter showed that the linker doesn't actually use the boost libraries for some reason (yes, the -L path is correct, the libraries are there, linker doesn't complain when I use -l).
After much googling I found out that the order is the problem, that I have to place my -l parameters after all my .o files (because of dependencies). This seemed to solve all the problems except one undefined reference to thread library. Again -t showed that this library is actually not used by the linker (not in the list) the others are (I use boost_system and boost_date_time as well). I played with the order of the parameters again but the result was the same. Any idea what am I missing?
The error is:
c:/x5/cpp/build//timed_cond.o:timed_cond.cpp:(.text$_ZN5boost6detail24basic_condition_variable7do_waitINS_11unique_lockINS_5mutexEEEEEbRT_NS0_7timeoutE[bool boost::detail::basic_condition_variable::do_wait<boost::unique_lock<boost::mutex> > (boost::unique_lock<boost::mutex>&, boost::detail::timeout)]+0x246): undefined reference to `_imp___ZN5boost11this_thread18interruptible_waitEPvNS_6detail7timeoutE'
I use same versions of Boost library (1.44.0) on both platforms
Ok, I found the answer. Looks like the problem is in boost libraries being static in MinGW-distro. Normally they are configured to be linked dynamically and that caused above issue. This answer explains it...

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

Adding Boost makes Debug build depend on "non-D" MSVC runtime DLLs

I have an annoying problem which I might be able to somehow circumvent, but on the other hand would much rather be on top of it and understand what exactly is going on, since it looks like this stuff is really here to stay.
Here's the story: I have a simple OpenGL app which works fine: never a major problem in compiling, linking, or running it. Now I decided to try to move some of the more intensive calculations into a worker thread, in order to possibly make the GUI even more responsive — using Boost.Thread, of course.
In short, if I add the following fragment in the beginning of my .cpp file:
#include <boost/thread/thread.hpp>
void dummyThreadFun() { while (1); }
boost::thread p(dummyThreadFun);
, then I start getting "This application has failed to start because MSVCP90.dll was not found" when trying to launch the Debug build. (Release mode works ok.)
Now looking at the executable using the Dependency Walker, who also does not find this DLL (which is expected I guess), I could see that we are looking for it in order to be able to call the following functions:
?max#?$numeric_limits#K#std##SAKXZ
?max#?$numeric_limits#_J#std##SA_JXZ
?min#?$numeric_limits#K#std##SAKXZ
?min#?$numeric_limits#_J#std##SA_JXZ
Next, I tried to convert every instance of min and max to use macros instead, but probably couldn't find all references to them, as this did not help. (I'm using some external libraries for which I don't have the source code available. But even if I could do this — I don't think it's the right way really.)
So, my questions — I guess — are:
Why do we look for a non-debug DLL even though working with the debug build?
What is the correct way to fix the problem? Or even a quick-and-dirty one?
I had this first in a pretty much vanilla installation of Visual Studio 2008. Then tried installing the Feature Pack and SP1, but they didn't help either. Of course also tried to Rebuild several times.
I am using prebuilt binaries for Boost (v1.36.0). This is not the first time I use Boost in this project, but it may be the first time that I use a part that is based on a separate source.
Disabling incremental linking doesn't help. The fact that the program is OpenGL doesn't seem to be relevant either — I got a similar issue when adding the same three lines of code into a simple console program (but there it was complaining about MSVCR90.dll and _mkdir, and when I replaced the latter with boost::create_directory, the problem went away!!). And it's really just removing or adding those three lines that makes the program run ok, or not run at all, respectively.
I can't say I understand Side-by-Side (don't even know if this is related but that's what I assume for now), and to be honest, I am not super-interested either — as long as I can just build, debug and deploy my app...
Edit 1: While trying to build a stripped-down example that anyway reproduces the problem, I have discovered that the issue has to do with the Spread Toolkit, the use of which is a factor common to all my programs having this problem. (However, I never had this before starting to link in the Boost stuff.)
I have now come up with a minimal program that lets me reproduce the issue. It consists of two compilation units, A.cpp and B.cpp.
A.cpp:
#include "sp.h"
int main(int argc, char* argv[])
{
mailbox mbox = -1;
SP_join(mbox, "foo");
return 0;
}
B.cpp:
#include <boost/filesystem.hpp>
Some observations:
If I comment out the line SP_join of A.cpp, the problem goes away.
If I comment out the single line of B.cpp, the problem goes away.
If I move or copy B.cpp's single line to the beginning or end of A.cpp, the problem goes away.
(In scenarios 2 and 3, the program crashes when calling SP_join, but that's just because the mailbox is not valid... this has nothing to do with the issue at hand.)
In addition, Spread's core library is linked in, and that's surely part of the answer to my question #1, since there's no debug build of that lib in my system.
Currently, I'm trying to come up with something that'd make it possible to reproduce the issue in another environment. (Even though I will be quite surprised if it actually can be repeated outside my premises...)
Edit 2: Ok, so here we now have a package using which I was able to reproduce the issue on an almost vanilla installation of WinXP32 + VS2008 + Boost 1.36.0 (still pre-built binaries from BoostPro Computing).
The culprit is surely the Spread lib, my build of which somehow requires a rather archaic version of STLPort for MSVC 6! Nevertheless, I still find the symptoms relatively amusing. Also, it would be nice to hear if you can actually reproduce the issue — including scenarios 1-3 above. The package is quite small, and it should contain all the necessary pieces.
As it turns out, the issue did not really have anything to do with Boost.Thread specifically, as this example now uses the Boost Filesystem library. Additionally, it now complains about MSVCR90.dll, not P as previously.
Boost.Thread has quite a few possible build combinations in order to try and cater for all the differences in linking scenarios possible with MSVC. Firstly, you can either link statically to Boost.Thread, or link to Boost.Thread in a separate DLL. You can then link to the DLL version of the MSVC runtime, or the static library runtime. Finally, you can link to the debug runtime or the release runtime.
The Boost.Thread headers try and auto-detect the build scenario using the predefined macros that the compiler generates. In order to link against the version that uses the debug runtime you need to have _DEBUG defined. This is automatically defined by the /MD and /MDd compiler switches, so it should be OK, but your problem description suggests otherwise.
Where did you get the pre-built binaries from? Are you explicitly selecting a library in your project settings, or are you letting the auto-link mechanism select the appropriate .lib file?
I believe I have had this same problem with Boost in the past. From my understanding it happens because the Boost headers use a preprocessor instruction to link against the proper lib. If your debug and release libraries are in the same folder and have different names the "auto-link" feature will not work properly.
What I have done is define BOOST_ALL_NO_LIB for my project(which prevents the headers from "auto linking") and then use the VC project settings to link against the correct libraries.
Looks like other people have answered the Boost side of the issue. Here's a bit of background info on the MSVC side of things, that may save further headache.
There are 4 versions of the C (and C++) runtimes possible:
/MT: libcmt.lib (C), libcpmt.lib (C++)
/MTd: libcmtd.lib, libcpmtd.lib
/MD: msvcrt.lib, msvcprt.lib
/MDd: msvcrtd.lib, msvcprtd.lib
The DLL versions still require linking to that static lib (which somehow does all of the setup to link to the DLL at runtime - I don't know the details). Notice in all cases debug version has the d suffix. The C runtime uses the c infix, and the C++ runtime uses the cp infix. See the pattern? In any application, you should only ever link to the libraries in one of those rows.
Sometimes (as in your case), you find yourself linking to someone else's static library that is configured to use the wrong version of the C or C++ runtimes (via the awfully annoying #pragma comment(lib)). You can detect this by turning your linker verbosity way up, but it's a real PITA to hunt for. The "kill a rodent with a bazooka" solution is to use the /nodefaultlib:... linker setting to rule out the 6 C and C++ libraries that you know you don't need. I've used this in the past without problem, but I'm not positive it'll always work... maybe someone will come out of the woodwork telling me how this "solution" may cause your program to eat babies on Tuesday afternoons.
This is a classic link error. It looks like you're linking to a Boost DLL that itself links to the wrong C++ runtime (there's also this page, do a text search for "threads"). It also looks like the boost::posix::time library links to the correct DLL.
Unfortunately, I'm not finding the page that discusses how to pick the correctly-built Boost DLL (although I did find a three-year-old email that seems to point to BOOST_THREAD_USE_DLL and BOOST_THREAD_USE_LIB).
Looking at your answer again, it appears you're using pre-built binaries. The DLL you're not able to link to is part of the TR1 feature pack (second question on that page). That feature pack is available on Microsoft's website. Or you'll need a different binary to link against. Apparently the boost::posix::time library links against the unpatched C++ runtime.
Since you've already applied the feature pack, I think the next step I would take would be to build Boost by hand. That's the path I've always taken, and it's very simple: download the BJam binary, and run the Boost Build script in the library source. That's it.
Now this got even a bit more interesting... If I just add this somewhere in the source:
boost::posix_time::ptime pt = boost::posix_time::microsec_clock::universal_time();
(together with the corresponding #include stuff), then it again works ok. So this is one quick and not even too dirty solution, but hey — what's going on here, really?
From memory various parts of the boost libraries need you to define some preprocessor flags in order to be able to compile correctly. Stuff like BOOST_THREAD_USE_DLL and so on.
The BOOST_THREAD_USE_DLL won't be what's causing this particular error, but it may be expecting you to define _DEBUG or something like that. I remember a few years ago in our boost C++ projects we had quite a few extra BOOST_XYZ preprocessor definitions declared in the visual studio compiler options (or makefile)
Check the config.hpp file in the boost thread directory. When you pull in the ptime stuff it's possibly including a different config.hpp file, which may then define those preprocessor things differently.