Compiling C++ source file using Boost.Thread - c++

I am trying to learn how to use the C++ Boost.Thread library. I have installed the Boost libraries on my Ubuntu 11.10 system. I am following the book "The Boost C++ Libraries" by Schaling - specifically example 6.1 on page 66. I am trying to compile the following code example:
#include <boost/thread.hpp>
#include <iostream>
void wait(int seconds)
{
boost::this_thread::sleep(boost::posix_time::seconds(seconds));
}
void thread()
{
for(int i = 0; i < 5; ++i)
{
wait(1);
std::cout << i << std::endl;
}
}
int main()
{
boost::thread t(thread);
t.join();
}
However, when I compile this with the following from the command line:
$ g++ example61.cpp -o example61 -I /usr/local/include
I get the following output:
/tmp/cc6bVu1F.o: In function `main':
example6.cpp:(.text+0x9d): undefined reference to `boost::thread::join()'
example6.cpp:(.text+0xae): undefined reference to `boost::thread::~thread()'
example6.cpp:(.text+0xc6): undefined reference to `boost::thread::~thread()'
/tmp/cc6bVu1F.o: In function `boost::detail::thread_data_base::thread_data_base()':
example6.cpp:(.text._ZN5boost6detail16thread_data_baseC2Ev[_ZN5boost6detail16thread_data_baseC5Ev]+0x24): undefined reference to `vtable for boost::detail::thread_data_base'
/tmp/cc6bVu1F.o: In function `void boost::this_thread::sleep<boost::posix_time::seconds>(boost::posix_time::seconds const&)':
example6.cpp:(.text._ZN5boost11this_thread5sleepINS_10posix_time7secondsEEEvRKT_[void boost::this_thread::sleep<boost::posix_time::seconds>(boost::posix_time::seconds const&)]+0x35): undefined reference to `boost::this_thread::sleep(boost::posix_time::ptime const&)'
/tmp/cc6bVu1F.o: In function `boost::thread::thread<void (*)()>(void (*)(), boost::disable_if<boost::is_convertible<void (*&)(), boost::detail::thread_move_t<void (*)()> >, boost::thread::dummy*>::type)':
example6.cpp:(.text._ZN5boost6threadC2IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE[_ZN5boost6threadC5IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE]+0x30): undefined reference to `boost::thread::start_thread()'
/tmp/cc6bVu1F.o: In function `boost::detail::thread_data<void (*)()>::~thread_data()':
example6.cpp:(.text._ZN5boost6detail11thread_dataIPFvvEED2Ev[_ZN5boost6detail11thread_dataIPFvvEED5Ev]+0x1f): undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
/tmp/cc6bVu1F.o:(.rodata._ZTIN5boost6detail11thread_dataIPFvvEEE[typeinfo for boost::detail::thread_data<void (*)()>]+0x10): undefined reference to `typeinfo for boost::detail::thread_data_base'
collect2: ld returned 1 exit status
I don't know how to interpret this. Can anyone help? Thank you so much!

That is a linking error. It means your code is correct and you include the correct headers, but the compiler doesn't link against the boost threading library. To fix this, you need to compile like this:
g++ example61.cpp -o example61 -I /usr/local/include -lboost_thread
If you've installed the Boost threading library to a non-standard path, you must also add it to the search path:
g++ example61.cpp -o example61 -I /usr/local/include -lboost_thread -L/usr/local/lib

You need to link with the library. Some Boost libraries are implemented entirely in the header files and do not need a library. But others, like thread, are implemented partly in headers and partly in compiled library code.
I believe that you need to add -lboost_thread-mt to your compile command.

Boost thread are not a template only library. You need to add a -lboost_thread while linking /compiling.
Most of the libraries in boost are implemented in headers. They can simply be included like you have done. Boost thread on the other hand, is of such a nature that you need to depend on its compiled units, only the declaration of its function are readily available to you in the header. So the compiler, or more correctly the linker, which is responsible for linking your calls to the declared functions /classes need to know where to look for these symbols. By invoking the compiler with a -lboost_thread you tell it to link to the library (-l) boost thread.

Following your comments I share with you compilation string for pocketcpp compilation tool:
g++ -static -I"\boost" "$(FULL_CURRENT_PATH)" -L"\MinGW\lib" -lboost_thread -lboost_system -o "$(CURRENT_DIRECTORY)\$(NAME_PART).exe"
Good luck,

I commented above, but wanted to share the full command line here.
g++ -std=c++11 thread_example.cpp -lboost_thread -lboost_system
[I'm using thread_example.cpp as the source filename; please replace with your own]

Related

Boost.test cannot find main

I'm working with gcc 4.8, boost 1.59 on kubuntu 12.04.
I wrote a simple main.cpp file:
#define BOOST_TEST_MODULE My_Module
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE( foo )
{}
This doesn't work when I build with
g++ -std=c++11 main.cpp -I/usr/local/include -L/usr/local/lib -lboost_unit_test_framework -o test
I get a bunch of linker errors:
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to 'main'
/tmp/cc57ppN0.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0x131): undefined reference to `boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(boost::unit_test::test_case*, unsigned long)'
/tmp/cc57ppN0.o: In function `boost::unit_test::make_test_case(boost::unit_test::callback0<boost::unit_test::ut_detail::unused> const&, boost::unit_test::basic_cstring<char const>)':
main.cpp:(.text._ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x6d): undefined reference to `boost::unit_test::test_case::test_case(boost::unit_test::basic_cstring<char const>, boost::unit_test::callback0<boost::unit_test::ut_detail::unused> const&)'
collect2: erreur: ld a retourné 1 code d'état d'exécution
What does undefined reference to 'main' means??? Well, I know that it is because it could not find main() but why? AFAIK the syntax of my file is correct. It should link, no?
You need to insert the following directive at the top of main.cpp:
#define BOOST_TEST_DYN_LINK
It seems that the example in the Boost.test documentation works for static linking only: the directive above is required, however, for dynamic linking.
See e.g C++ Unit Testing With Boost.Test for further details.
OK, I found the solution!
It seems that, since 1.34.1, boost.test no longer contains main() in dynamic (.so) version. See here. So I wanted to link with the static and I also learned that gcc prefers the dynamic libraries over the static ones for the same name!. Thus, I changed my compile command to:
g++ -std=c++11 main.cpp -I/usr/local/include -L/usr/local/lib -lboost_unit_test_framework -static -o test
...and it worked fine!
I also tested with two files ... main.cpp test1.cpp and the run executed all the test cases correctly.
Thank you, I hope this can help someone else!

c++ files to include for boost : asio

I'm following this tutorial however it does not state which libaries I need to include in order to get boost to work,current options for links are:
-I/usr/include/opencv2 -I/usr/include/boost_1_55_0 -I/usr/include/boost_1_55_0/boost -O0 -g3 -Wall -c -fmessage-length=0
however this returns the following erro:
which states that it can't find asio, am I doing something wrong or was assio the wrong library to link to? Or is there any other way to find out. Note that this is my 2nd c++ project(through I have a lot of java experience) and first with the heavy use of libraries so details are somewhat required.
Removing boost/asio gave me the following errors:
make all
Building target: DisplayImage
Invoking: GCC C++ Linker
g++ -L/usr/include/opencv2 -L/usr/include/boost_1_55_0/boost -L/usr/include/boost_1_55_0 -L/usr/include/opencv2 -L/usr/lib -o "DisplayImage" ./src/Cap.o ./src/DisplayImage.o ./src/Filters.o ./src/sender.o -lopencv_imgproc -lopencv_highgui -lopencv_core
./src/sender.o: In function `__static_initialization_and_destruction_0':
/usr/include/boost_1_55_0/boost/system/error_code.hpp:222: undefined reference to `boost::system::generic_category()'
/usr/include/boost_1_55_0/boost/system/error_code.hpp:223: undefined reference to `boost::system::generic_category()'
/usr/include/boost_1_55_0/boost/system/error_code.hpp:224: undefined reference to `boost::system::system_category()'
./src/sender.o: In function `error_code':
/usr/include/boost_1_55_0/boost/system/error_code.hpp:323: undefined reference to `boost::system::system_category()'
./src/sender.o: In function `boost::asio::error::get_system_category()':
/usr/include/boost_1_55_0/boost/asio/error.hpp:224: undefined reference to `boost::system::system_category()'
collect2: ld returned 1 exit status
make: *** [DisplayImage] Error 1
Build Finished **
I use an ubuntu (x64) laptop if it matters.
Most of boost is implemented in what's called "header-only" code. Through the generous use of C++ templates, there is no actual library code to which your code needs to link. However, there are, as you've seen some actual libraries as well. Generally, the help you seek is probably here: http://www.boost.org/doc/libs/1_55_0/more/getting_started/unix-variants.html#link-your-program-to-a-boost-library
Your particular program uses the timer and system libraries and so you can probably use this command line to link your program:
g++ timer.cpp -o timer -lboost_timer -lboost_system
You can look at the bjam in boost/libs/asio/example/cpp03/tutorial/Jamfile.v2:
project
: requirements
<library>/boost/system//boost_system
<library>/boost/thread//boost_thread
<define>BOOST_ALL_NO_LIB=1
<threading>multi
<os>SOLARIS:<library>socket
<os>SOLARIS:<library>nsl
<os>NT:<define>_WIN32_WINNT=0x0501
<os>NT,<toolset>gcc:<library>ws2_32
<os>NT,<toolset>gcc:<library>mswsock
<os>NT,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<os>HPUX,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
<os>HPUX:<library>ipv6
;
You can see that they build all the tutorial steps with
-lboost_system -lboost_thread -DBOOST_ALL_NO_LIB=1
on linux

Linking a DLL using xerces gives undefined symbols

I'm creating a shared library/DLL using cygwin which makes use of Xerces. When I call the xercesc functions from the main application everything is fine, but when I try to put some code into the library, then I get undefined symbols for all the static stuff that xerxesc defines.
For example:
std::string fromXMLString(XMLCh *oXMLString)
{
std::string result;
xercesc::DOMImplementation *impl = xercesc::DOMImplementationRegistry::getDOMImplementation(X("Core"));
char *temp = xercesc::XMLString::transcode(oXMLString);
result = temp;
xercesc::XMLString::release(&temp);
return result;
}
Linking:
g++ -shared -Wl,-soname,cygsupport.so -L /usr/local/lib -l xerces-c -o cygsupport.so obj/helper/xml_helper.o
When linking the library, I get:
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::DOMImplementationRegistry::getDOMImplementation(wchar_t const*)'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLPlatformUtils::fgMemoryManager'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLString::transcode(wchar_t const*, xercesc_3_1::MemoryManager*)'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLPlatformUtils::fgMemoryManager'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLString::release(char**, xercesc_3_1::MemoryManager*)'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLPlatformUtils::fgMemoryManager'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLString::release(wchar_t**, xercesc_3_1::MemoryManager*)'
/usr/local/include/xercesc/internal/XSerializable.hpp:37: undefined reference to `xercesc_3_1::XMLPlatformUtils::fgMemoryManager'
...
Finally after several days on looking into this issue I found the solution. It is as simple as stupid.
My original linker commandline looked like this:
g++ -shared -o mylib.so -L/usr/local/lib -lxerces-c objects...
Googling on this problem didn't yield anything usefull, so finally I decided to create a fresh new sample project with eclipse and suddenly it worked. The only difference was in the commandline to the linker. When I applied the same order to my main project it suddenly compiled.
g++ -L/usr/local/lib -shared -o mylib.so objects... -lxerces-c
Note that in the above line, the objects come before the library, and apperently this makes the difference. I thought that the ordering of the libs only applies to the libraries, but apparently also the objects must be ordered appropriately.

Boost thread error: undefined reference

#include <boost/thread/thread.hpp>
#include <iostream>
void hello()
{
std::cout <<
"Hello world, I'm a thread!"
<< std::endl;
}
int main(int argc, char* argv[])
{
boost::thread thrd(&hello);
thrd.join();
return 0;
}
I ran tried to compile this program, and got these errors:
/usr/include/boost/thread/pthread/mutex.hpp:40: undefined reference to
`boost::thread_resource_error::thread_resource_error()'
/usr/include/boost/thread/pthread/mutex.hpp:40: undefined reference to
`boost::thread_resource_error::~thread_resource_error()'
/usr/include/boost/thread/pthread/mutex.hpp:40: undefined reference to
`typeinfo for boost::thread_resource_error'
./src/thread.o: In function `condition_variable':
/usr/include/boost/thread/pthread/condition_variable_fwd.hpp:33:
undefined reference to `boost::thread_resource_error::thread_resource_error()'
/usr/include/boost/thread/pthread/condition_variable_fwd.hpp:33:
undefined reference to `boost::thread_resource_error::~thread_resource_error()'
/usr/include/boost/thread/pthread/condition_variable_fwd.hpp:33: \
undefined reference to `typeinfo for boost::thread_resource_error'
./src/thread.o: In function `thread_data_base':
/usr/include/boost/thread/pthread/thread_data.hpp:54:
undefined reference to `vtable for boost::detail::thread_data_base'
./src/thread.o: In function `thread<void (*)()>':
/usr/include/boost/thread/detail/thread.hpp:188:
undefined reference to `boost::thread::start_thread()'
./src/thread.o: In function `~thread_data':
/usr/include/boost/thread/detail/thread.hpp:40:
undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
/usr/include/boost/thread/detail/thread.hpp:40: undefined reference to
`boost::detail::thread_data_base::~thread_data_base()'
Can any one tell me why i am getting this error?
compile with mt tag i.e -lboost_thread-mt
I had the same question, but -lboost_thread-mt is now deprecated see this answer on askubuntu.com. Instead what you now want in your makefile (at least for linux) is:
-lpthread -lboost_thread ...
Boost has simply given you the responsibility to link to your system's thread library.
Many boost libraries are fully implemented in header files. Boost.thread is not. It seems that it is not linking in the boost thread library. Check your linker search paths. Or, as the Stargazer712's comment on the OP says, check the installation. You should see something like libboost_thread-gcc-xxx-1_nn.o in your lib directory. If so, try referencing it explicitly in your link step (something like -L<path_to_lib> -lboost-thread-gcc-xx-1_nn). If not, then you apparently don't have a complete installation.
Instead of
g++ -pthread -lboost_thread X.cpp
Try
g++ X.cpp -pthread -lboost_thread
I had a similar problem with centos 6.5 when compiling povray 3.7 and this solved it - just add -lboost_thread-mt in your Makefile.
add compile option
-L<path_to_lib> -lboost-thread-gcc-xx-1_nn
gregg's answer is right!
I had the same error. I fixed it compiling with -lboost_thread

undefined referance to LibSerial

So i'm writing a serial transmision program, and have just changed over to using C++, it been a while since I used C++
(I've been working with C recently, and before that java)
Now I need to use LibSerial,
(it seems much simpler to use than C's termios)
my code is:
//gen1.cpp
#include "string2num.h" // a custom header
#include <iostream>
#include <SerialStream.h>
using namespace LibSerial;
//using namespace std;
int main(int argc, char*argv[])
{
if (argc<2)
{
std::cout<<argv[0]<<"requires the device name eg \"dev/tty0\" as a parameter\nterminating.\n";
return 1;
}
SerialStream theSerialStream(argv[1]); //open the device
return 0;
}
When I compile the output:
g++ -Wall -o gen1 gen1.cpp string2num.o
/tmp/cchPBWgx.o: In function `main':
gen1.cpp:(.text+0x121): undefined reference to `LibSerial::SerialStream::SerialStream(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Ios_Openmode)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x24): undefined reference to `LibSerial::SerialStreamBuf::showmanyc()'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x28): undefined reference to `LibSerial::SerialStreamBuf::xsgetn(char*, int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x2c): undefined reference to `LibSerial::SerialStreamBuf::underflow()'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x34): undefined reference to `LibSerial::SerialStreamBuf::pbackfail(int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x38): undefined reference to `LibSerial::SerialStreamBuf::xsputn(char const*, int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x3c): undefined reference to `LibSerial::SerialStreamBuf::overflow(int)'
collect2: ld returned 1 exit status
make: *** [gen1] Error 1
This is the linker complaining that it cannot find the functions referenced by the libserial header file.
If I look on my Linux system to see how the shared library is called:
$ dpkg -L libserial0
...
/usr/lib/libserial.so.0.0.0
/usr/lib/libserial.so.0
On my system this implies I would add -lserial as a g++ option (aka link with libserial.so) this would turn your compilation command into
g++ -Wall -lserial -o gen1 gen1.cpp string2num.o
Including the header file is not enough - you also need to link with the library that implements SerialStream. Assuming it is a static library called serstream.a (it is almost certainly actually called something else):
g++ -Wall -o gen1 gen1.cpp string2num.o serstream.a
old thread, but i still use Libserial. here the completed answer
My working setup.
Ubuntu 18.04
g++ 7.3.0
1) Install package for libserial
apt install libserial-dev
2) check for your headers(.h) and .so files
dpkg -l libserial0
dpkg -l libserial-dev
the first command give you the directory of shared library and the second gives you the headers location.
3) Your code.
I have to change a little your code, first i delete the custom header and modifing the constuctor call to this.
SerialStream theSerialStream;
4) compile with g++
Here my compiling command
g++ -o test -I/usr/include test.cpp -L/usr/lib/x86_64-linux-gnu -lserial -lpthread
check for the -lpthread linking option, beacuse Libserial uses mutex.
In Ubuntu/Debian make sure you have to libserial-dev package installed and use the '-lserial' flag for gcc.