7

I was trying to compile the following simple thread example for the Boost library:

        #include <iostream>
        #include <boost/thread.hpp>
        #include <boost/chrono.hpp>

        using namespace std;

        void thread()
        {
          for (int i = 0; i < 5; ++i)
          {
            cout << i << '\n';
          }
        }

        int main()
        {
          boost::thread t{thread};
          t.join();
        }

using

  g++ -std=c++11 -I /usr/local/boost_1_57_0 simpleThreadExample.cpp

and the compiler gave this back to me:

       Undefined symbols for architecture x86_64:
        "boost::detail::thread_data_base::~thread_data_base()", referenced from:
        boost::detail::thread_data<void (*)()>::~thread_data() in simpleThreadExample-7cec5e.o
        "boost::system::system_category()", referenced from:
        ___cxx_global_var_init2 in simpleThreadExample-7cec5e.o
        boost::thread_exception::thread_exception(int, char const*) in simpleThreadExample-7cec5e.o
       "boost::system::generic_category()", referenced from:
      ___cxx_global_var_init in simpleThreadExample-7cec5e.o
      ___cxx_global_var_init1 in simpleThreadExample-7cec5e.o
      "boost::thread::join_noexcept()", referenced from:
          boost::thread::join() in simpleThreadExample-7cec5e.o
      "boost::thread::native_handle()", referenced from:
          boost::thread::get_id() const in simpleThreadExample-7cec5e.o
      "boost::thread::start_thread_noexcept()", referenced from:
          boost::thread::start_thread() in simpleThreadExample-7cec5e.o
      "boost::thread::detach()", referenced from:
          boost::thread::~thread() in simpleThreadExample-7cec5e.o
      "typeinfo for boost::detail::thread_data_base", referenced from:
          typeinfo for boost::detail::thread_data<void (*)()> in simpleThreadExample-7cec5e.o
      "vtable for boost::detail::thread_data_base", referenced from:
          boost::detail::thread_data_base::thread_data_base() in simpleThreadExample-7cec5e.o
      NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

Now, the following two programs compile and run just fine:

        #include <locale>
        #include <boost/date_time/gregorian/gregorian.hpp>
        #include <boost/date_time/posix_time/posix_time.hpp>

        using namespace std;
        using namespace boost::gregorian;
        using namespace boost::posix_time;

        int main() 
        {

          date today = day_clock::local_day(); 
          cout << today << endl;

        }

And

        #include <iostream>
        #include <iomanip>
        #include <boost/geometry.hpp>
        #include <boost/geometry/geometries/point.hpp>

        using namespace std;

        int main()
        {

            //point_type p = boost::geometry::make<point_type>(1, 2, 3);
            //std::cout << boost::geometry::dsv(p) << std::endl;
            //return 0;


            boost::geometry::model::point<int, 3, boost::geometry::cs::cartesian> p;
            boost::geometry::assign_values(p,1, 2, 3);

            boost::geometry::model::point<int, 3, boost::geometry::cs::cartesian> p2;

            p2 = p;

            cout << boost::geometry::dsv(p) << endl;

            cout << boost::geometry::dsv(p2) << endl;

            return 0;
        }

And, when I compile, I do:

g++ -std=c++11 -I /usr/local/boost_1_57_0 <nameOfProgram.cpp>

So, I'm wondering why the thread program won't compile while these other two will when the only thing I'm changing is the name of the program?

If it helps, I am using Boost 1.57 and the path to it is:

 /usr/local/Cellar/boost/1.57.0

And the path to the header files is:

/usr/local/Cellar/boost/1.57.0/include/boost

If anyone could provide some insight, that would be brilliant. Thanks!

busebd12
  • 997
  • 2
  • 12
  • 24
  • Not all boost libraries are "header only". – Drew Dormann Apr 09 '15 at 15:17
  • 1
    If you have access to a C++11 compiler you should use `std::thread` instead of `boost::thread`; the API is essentially the same, since the C++11 threading library was designed by the guy that did `boost::thread`. –  Apr 09 '15 at 15:22

1 Answers1

9

You have to link against the boost library too:

-lboost_thread

Possibly with additional -L argument for path, and likely the standard -lpthread too.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • So, like g++ -std=c++11 -I /usr/local/boost_1_57_0 -lboost_thread -lpthread ? – busebd12 Apr 09 '15 at 15:55
  • In addition to linking against the boost library, you actually have to make sure you've built the library as well. Check the boost thread documentation on how to build the library. Also, as previously stated, if you have access to a C++11 compiler, just use std::thread the exact same way you used boost::thread. – RyanP Apr 09 '15 at 15:58
  • @xXAnointedXx Yeah. If that doesn't find it, you may need to provide the path to the directory via [`-L`](https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options). – Barry Apr 09 '15 at 16:09
  • I'm not sure why, but for me it was just a matter of running `autoreconf` and `make` again (without having to add any links or directory paths). – Josh Hibschman May 25 '18 at 17:40
  • This was my issue too. What gave me the hint that I was missing this was using `-v` with `g++` to show exactly what libraries it was and wasn't aware of. – Sridhar Sarnobat Mar 19 '23 at 07:18