Boost logo

Boost Users :

Subject: [Boost-users] make file starting out
From: Peter Koukoulis (pkoukoulis_at_[hidden])
Date: 2017-08-07 08:54:54


Hi

I am new to setting up make files, and even newer to Boost. I've been using Geany on Ubuntu to learn Boost. When I compile and link using a single file with the following :

g++ -g -Wall -std=c++14 -o "%e" "%f" -lboost_thread -DBOOST_THREAD_VERSION=5 -lboost_system -ldl

then everything works as expected, for the following that is:

#include <iostream>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

class t {
  private:
    boost::asio::io_service ios;
    std::unique_ptr<boost::asio::io_service::work> work_ios;
    boost::thread_group tg;
    int f;
    boost::mutex mx;

  public:
    // Constructor
    t( int p ) : work_ios{std::make_unique<boost::asio::io_service::work>(ios)}, f{p} {
      if(p>0) p = boost::thread::hardware_concurrency()*2;
      for ( int i = 0; i < p; ++i )
        tg.create_thread( boost::bind( &boost::asio::io_service::run, &ios ) );
    }
    // Destructor
    ~t () {
      work_ios.reset();
      tg.join_all();
      ios.stop();
    }

    template <typename Job>
    void run_job( Job job ) {
      boost::unique_lock< boost::mutex > lock( mx );
      if ( 0 == f ) return;
      --f;
      ios.dispatch( boost::bind( &t::wrap_job, this, boost::function< void() >(job) ));
    }
  private:
    void wrap_job( boost::function< void() > job ) {
      try { job(); }
      catch ( const std::exception& ) {}
      boost::unique_lock< boost::mutex > lock( mx );
      ++f;
    }
};

int main() {
  t tp{2};
  tp.run_job( [] () { std::cout << "some work \n"; } );
  return 0;

}

But when I attempt to split "t" into a .h and .cpp file with a separate file for main to test with, my linking does not work. The make output is:

g++ test_t.o t.o -o test_t
test_t.o: In function `__static_initialization_and_destruction_0(int, int)':
test_t.cpp:(.text+0x6e9): undefined reference to `boost::system::generic_category()'
test_t.cpp:(.text+0x6f5): undefined reference to `boost::system::generic_category()'

The files look as follows:

# the makefile:
CC=g++
CFLAGS=-c -Wall -std=gnu++14 -lboost_system -lboost_thread -DBOOST_THREAD_VERSION=5 -ldl -lpq
all: test_t

test_t: t.o test_t.o
$(CC) test_t.o t.o -o test_t

t.o: t.cpp
$(CC) $(CFLAGS) t.cpp

test_t.o: test_t.cpp
$(CC) $(CFLAGS) test_t.cpp

clean:
rm *o test_t.o test_t

// .h file
#ifndef T_H_
#define T_H_

#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

class t {
private:
  boost::asio::io_service ios;
  std::unique_ptr<boost::asio::io_service::work> work_ios;
  boost::thread_group tg;
  int f;
  boost::mutex mx;

public:
  t( int p = 0 );
  ~t();

  template <typename Job>
  void run_job( Job job ) {
    boost::unique_lock< boost::mutex > lock( mx );
    if ( 0 == f ) return;
    --f;
    ios.dispatch( boost::bind( &t::wrap_job, this, boost::function< void() >(job) ));
      }

private:
  void wrap_job( boost::function< void() > job ) {
    try { job(); }
    catch ( const std::exception& ) {}
    boost::unique_lock< boost::mutex > lock( mx );
    ++f;
  }

};

#endif

// .cpp file
#include "t.h"

// Constructor
t::t( int p ) : work_ios{std::make_unique<boost::asio::io_service::work>(ios)}, f{p} {
  if(p>0)
    p = boost::thread::hardware_concurrency()*2;
  for ( int i = 0; i < p; ++i )
    tg.create_thread( boost::bind( &boost::asio::io_service::run, &ios ) );
}

// Destructor
t::~t () {
  work_ios.reset();
  tg.join_all();
  ios.stop();
}

// main file
#include <iostream>
#include "t.h"

int main() {
  t tp{4};
  tp.run_job( [] () { std::cout << "some work \n"; } );

  return 0;
}

Could somebody point out how the make file should look like ?

thanks
pkl


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net