make file starting out

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

AMDG On 08/07/2017 02:54 AM, Peter Koukoulis via Boost-users wrote:
<snip> 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
Libraries (-lboost_system) need to be passed to the linker, not the compiler. In Christ, Steven Watanabe

El 07/08/17 a las 05:54, Peter Koukoulis via Boost-users escribió:
The files look as follows:
# the makefile: CC=g++ CFLAGS=-c -Wall -std=gnu++14 -lboost_system -lboost_thread -ldl -lpq
CFLAGS=-c -Wall -std=gnu++14 -DBOOST_THREAD_VERSION=5 LDFLAGS= -lboost_system -lboost_thread -ldl -lpq -- Gonzalo Garramuño

On 07.08.2017 21:33, Gonzalo Garramuño via Boost-users wrote:
El 07/08/17 a las 05:54, Peter Koukoulis via Boost-users escribió:
The files look as follows:
# the makefile: CC=g++ CFLAGS=-c -Wall -std=gnu++14 -lboost_system -lboost_thread -ldl -lpq
CFLAGS=-c -Wall -std=gnu++14 -DBOOST_THREAD_VERSION=5 LDFLAGS= -lboost_system -lboost_thread -ldl -lpq
Yes, and LDFLAGS should then be used in test_t rule. But, both by convention and by implicit rules implementation, the C++ compiler is contained in CXX variable (and not CC, which is supposed to be C compiler) with its compile flags being stored in CXXFLAGS variable. By properly setting CPPFLAGS (preprocessor flags (-I, -D, ...) for both CC and CXX) , CXXFLAGS, and LDFLAGS you can build test_t purely by using implicit rules. Cheers, Leon
participants (4)
-
Gonzalo Garramuño
-
Leon Mlakar
-
Peter Koukoulis
-
Steven Watanabe