I am developing a hwdriver driver for the Chr-UM6 IMU and I am trying to test it before I put a MRPT CGeneraicSensor class compatible wrapper around it.
My code for the driver compiles but I'm getting link errors. I believe it's related to my CMakeLists.txt. Instead of attaching all my files, I've created a small test case that results in the same errors:
Scanning dependencies of target ChrUM6_driver_exe
[ 50%] Building CXX object CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o
[100%] Building CXX object CMakeFiles/ChrUM6_driver_exe.dir/src/main2.cpp.o
Linking CXX executable ChrUM6_driver_exe
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `CThread::stop()':
CThread.cpp:(.text+0x11): undefined reference to `boost::thread::interrupt()'
CThread.cpp:(.text+0x1c): undefined reference to `boost::thread::interrupt()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `CThread::~CThread()':
CThread.cpp:(.text+0xa7): undefined reference to `boost::thread::~thread()'
CThread.cpp:(.text+0xc5): undefined reference to `boost::thread::~thread()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `CThread::~CThread()':
CThread.cpp:(.text+0xf7): undefined reference to `boost::thread::~thread()'
CThread.cpp:(.text+0x102): undefined reference to `boost::thread::~thread()'
CThread.cpp:(.text+0x11d): undefined reference to `boost::thread::~thread()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `CThread::CThread()':
CThread.cpp:(.text+0x14c): undefined reference to `boost::thread::thread()'
CThread.cpp:(.text+0x157): undefined reference to `boost::thread::thread()'
CThread.cpp:(.text+0x16f): undefined reference to `boost::thread::~thread()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `CThread::start()':
CThread.cpp:(.text+0x2b3): undefined reference to `vtable for boost::detail::thread_data_base'
CThread.cpp:(.text+0x479): undefined reference to `boost::thread::start_thread()'
CThread.cpp:(.text+0x51b): undefined reference to `boost::thread::~thread()'
CThread.cpp:(.text+0x526): undefined reference to `boost::thread::~thread()'
CThread.cpp:(.text+0x566): undefined reference to `vtable for boost::detail::thread_data_base'
CThread.cpp:(.text+0x729): undefined reference to `boost::thread::start_thread()'
CThread.cpp:(.text+0x7dd): undefined reference to `boost::thread::~thread()'
CThread.cpp:(.text+0x7e8): undefined reference to `boost::thread::~thread()'
CThread.cpp:(.text+0xa42): undefined reference to `boost::thread::~thread()'
CThread.cpp:(.text+0xbcd): undefined reference to `boost::thread::~thread()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `CThread::~CThread()':
CThread.cpp:(.text+0xb7): undefined reference to `boost::thread::~thread()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `CThread::joinRxThread()':
CThread.cpp:(.text+0x1e2): undefined reference to `boost::thread::join()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `CThread::joinTxThread()':
CThread.cpp:(.text+0x222): undefined reference to `boost::thread::join()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, CThread>, boost::_bi::list1<boost::reference_wrapper<CThread> > > >::~thread_data()':
CThread.cpp:(.text._ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv7CThreadEENS2_5list1INS_17reference_wrapperIS6_EEEEEEED2Ev[_ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv7CThreadEENS2_5list1INS_17reference_wrapperIS6_EEEEEEED5Ev]+0x11): undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o: In function `boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, CThread>, boost::_bi::list1<boost::reference_wrapper<CThread> > > >::~thread_data()':
CThread.cpp:(.text._ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv7CThreadEENS2_5list1INS_17reference_wrapperIS6_EEEEEEED0Ev[_ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv7CThreadEENS2_5list1INS_17reference_wrapperIS6_EEEEEEED5Ev]+0x14): undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
CMakeFiles/ChrUM6_driver_exe.dir/src/CThread.cpp.o:(.rodata._ZTIN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv7CThreadEENS2_5list1INS_17reference_wrapperIS6_EEEEEEEE[typeinfo for boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, CThread>, boost::_bi::list1<boost::reference_wrapper<CThread> > > >]+0x8): undefined reference to `typeinfo for boost::detail::thread_data_base'
CMakeFiles/ChrUM6_driver_exe.dir/src/main2.cpp.o: In function `main':
main2.cpp:(.text+0x1e): undefined reference to `TestThread::TestThread()'
main2.cpp:(.text+0x2e): undefined reference to `TestThread::~TestThread()'
main2.cpp:(.text+0x56): undefined reference to `TestThread::~TestThread()'
collect2: ld returned 1 exit status
make[2]: *** [ChrUM6_driver_exe] Error 1
make[1]: *** [CMakeFiles/ChrUM6_driver_exe.dir/all] Error 2
make: *** [all] Error 2
================================================
I've attached (Oops! can't attach source so here they are inline:)
main2.cpp:
------------------------------------------------
#include "CThread.h"
/*
*
*/
class TestThread : public CThread {
public:
TestThread() ;
virtual ~TestThread();
protected:
void msleep(uint32_t ms) {
clock_t end = clock() + (CLOCKS_PER_SEC/1000) * ms ;
clock_t diff;
while ((diff = end - clock()) > 0) {
diff = (1000 * diff) / CLOCKS_PER_SEC;
if (diff > 1000)
sleep(diff / 1000);
else
usleep(diff * 1000);
}
}
void receiveLoop() {
msleep(1000) ;
}
void transmitLoop() {
msleep(900) ;
}
} ;
int main(int argc, char** argv) {
TestThread test ;
//
test.start() ;
return (EXIT_SUCCESS);
}
---------------------------------
CThread.h and CThread.cpp:
-------------------------------------
#ifndef CTHREAD_H
#define CTHREAD_H
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
class CThread {
public:
CThread() ;
virtual ~CThread() ;
void join() ;
virtual bool start() ;
virtual void stop() ;
protected:
virtual void receiveLoop() = 0 ;
virtual void transmitLoop() = 0 ;
void joinRxThread() ;
void joinTxThread() ;
private:
boost::thread rxThread;
boost::thread txThread;
bool isRunning ;
};
#endif /* CTHREAD_H */
------------------------------
// CThread.cpp
#include "CThread.h"
CThread::CThread() :
isRunning(false) {
}
CThread::~CThread() {
}
bool CThread::start() {
try {
rxThread = boost::thread( boost::bind( &CThread::receiveLoop,
boost::ref(*this) )
);
} catch (std::exception &e) {
std::cerr << "CThread::start(): Exception - While creating Rx thread: " << e.what() << std::endl ;
return false ;
}
try {
txThread = boost::thread( boost::bind( &CThread::transmitLoop,
boost::ref(*this) )
);
} catch (std::exception &e) {
std::cerr << "CThread::start(): Exception - While creating Tx thread: " << e.what() << std::endl ;
return false ;
}
isRunning = true ;
return true ;
}
void CThread::stop() {
try {
txThread.interrupt() ;
rxThread.interrupt() ;
isRunning = false ;
} catch (std::exception &e) {
std::cerr << "CPortListener::stopPortListener(): Exception - while trying to interrupt a thread: " << e.what() << std::endl ;
}
}
void CThread::join() {
std::cerr << "CThread::join(): Not implemented - Call has no effect\n" ;
//t.join() ;
}
void CThread::joinRxThread() {
std::cout << "CThread::joinRxThread(): Called.\n" ;
rxThread.join() ;
}
void CThread::joinTxThread() {
std::cout << "CThread::joinTxThread(): Called.\n" ;
txThread.join() ;
}
------------------------------
CMakelists.com
See attached....
==============================
I'm building these files outside of the mrpt/hwdrivers source tree so that I can use an IDE (Netbeans). I used the same approach to extract the XSens driver stuff and it built without similar errors, albeit it doesn't use boost/thread.hpp.
The provided main was only for the purpose of illustrating the error with minimal code. I know it's a poor execution example.
As you can see, I'm using more boost functionality but not resolving it properly. Any constructive advice or suggestions?
Thanks in advance.
| Attachment | Size |
|---|---|
| 745 bytes |
I've resolved the boost
I've resolved the boost related errors. I had to include name of boost library explicitly. It didn't find them like expected.
I'm still struggling to understand what key words to provide CMake so that it can find needed libraries and include paths.
I'm still at a loss why the constructors and destructors are not resolved.
Thanks
Hope this perhaps sheds some
Hope this perhaps sheds some light on your problem with CMake: http://stackoverflow.com/questions/3808775/cmake-doesnt-find-boost
OTOH, for code to be included into mrpt libs, I would rather recommend to call the mrpt::system::createThread* methods. I know boost is *almost* a standard lib nowadays, but mostly thinking of windows users I decided time ago to try avoiding depending on Boost as long as possible...
These are the MRPT threads functions: http://reference.mrpt.org/svn/group__mrpt__thread.html
And here goes an example: http://mrpt.googlecode.com/svn/trunk/samples/threadsTest/test.cpp
Cheers,
JL
Good news!...for me. I
Good news!...for me. I worked through all the problems. I haven't developed on g++ for a long time. They were all my errors but I am very disappointed in the quality of error messages from ld, and g++ for that matter. Here's a summary of the problems I fixed in the more complete set of code.
1) forgetting to define a default (non)virtual function in the implementation resulted in "unresolved reference" errors.
2) I had implemented a 'blocking" queue class using templates...what a mistake!! I finally removed the template structure but implemented with void* element type...call me stupid.
3) objects/variables I not encapsulated in a class but namespace and I wanted visible and accessible by including header file must have extern on the header file declaration and defined in the implementation file. Otherwise, "unresolved reference" errors resulted.
4) Another error that that was present in the more complete code was caused by forgetting to have a ';' after the declaration of a class. I think the punisment I suffered for that mistake was paid back in triplicate.
Thanks