I set Eclipse (Actually Xilinx SDK but based on Eclipse), and g++4.9.2, to compile a project which uses standalone ASIO and I used -std=c++11 in the Properties -> C/C++ Build -> Settings -> Tool Settings -> Other flags so it can compile using all C++11 features.
I also set ASIO_HAS_STD_THREAD, ASIO_STANDALONE
and so on in C/C++ General Symbols, and I expect that the ASIO header will use std::thread
instead of pthread
. However, I still see Error from make:
undefined reference to pthread_create,
..asio-1.10.6\include\asio\detail\impl\posix_thread.ipp
and posix_tss_ptr.hpp
so the problem is, since I am using C++11, and specified ASIO_HAS_STD_THREAD
but not ASIO_HAS_PTHREADS
, the posix_thread.ipp
should not be even included (through posix_thread.hpp), according to thread.hpp in ASIO:
#if !defined(ASIO_HAS_THREADS)
# include "asio/detail/null_thread.hpp"
#elif defined(ASIO_WINDOWS)
# if defined(UNDER_CE)
# include "asio/detail/wince_thread.hpp"
# else
# include "asio/detail/win_thread.hpp"
# endif
#elif defined(ASIO_HAS_PTHREADS)
# include "asio/detail/posix_thread.hpp"
#elif defined(ASIO_HAS_STD_THREAD)
# include "asio/detail/std_thread.hpp"
#else
# error Only Windows, POSIX and std::thread are supported!
#endif
Suspect 1 -pthread
Contrary to most people believe, C++11 doesn't need the -pthread
and I have tried to compile a simple project without -pthread
in Eclipse. However, you can correct me if I am wrong. When I put -pthread
in the linker option, it does compile, however I felt I don't want the pthread if not necessary.
Suspect 2 - ASIO makefile
When I search the posix_tss_ptr.hpp, I found also in Makefile.am. I wonder whether this affect the error?
So what is the cause of the problem? If not the above two suspect? I hope the solution can be still using pure C++11 way, not to use pthread if my reasoning is correct.
Update
I found that ASIO_HAS_PTHREADS is defined not by me and that's why ASIO uses POSIX threads somewhere and the linker then needs the option -pthread. Then I traced down to the asio/detail/signal_blocker.hpp by using #error directive. There are only two places that it is defined and they are in ASIO config.hpp
# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)
# define ASIO_HAS_PTHREADS 1
# elif defined(_POSIX_THREADS)
# define ASIO_HAS_PTHREADS 1
ASIO still replies on POSIX THREADS or Windows for signal_blocker.hpp shown below. That's why ASIO still needs pthread.
#if !defined(ASIO_HAS_THREADS) || defined(ASIO_WINDOWS) \
|| defined(ASIO_WINDOWS_RUNTIME) \
|| defined(__CYGWIN__) || defined(__SYMBIAN32__)
typedef null_signal_blocker signal_blocker;
#elif defined(ASIO_HAS_PTHREADS)
typedef posix_signal_blocker signal_blocker;
#endif
And _PTHREADS is defined from the gnu cross compiler (arm-xilinx-linux-gnueabi) include files such as features.h, posix_opt.h, and etc. I am not going to track down which truly defined the macro, but ASIO is the source which uses _POSIX_THREADS and so the linker option -pthread should be there.
Again, non ASIO C++11 thread doesn't need -pthread for g++ 4.9.2 but standalone ASIO needs it. The following code is built correctly without -pthread in g++4.9.2 (Xilinx SDK which is based on Eclipse):
#include <thread>
void test() {
for(int i=0;i<100;i++);
}
int main()
{
std::thread thread1(test);
thread1.join();
return 0;
}