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
#include
#include
#include
class t {
private:
boost::asio::io_service ios;
std::unique_ptrboost::asio::io_service::work work_ios;
boost::thread_group tg;
int f;
boost::mutex mx;
public:
// Constructor
t( int p ) : work_ios{std::make_uniqueboost::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
#include
#include
#include
class t {
private:
boost::asio::io_service ios;
std::unique_ptrboost::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_uniqueboost::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