Package: libcaf-dev Version: 0.13.2-3 Severity: normal Dear maintainers, i tried to compile a the sample from the libcaf webpage (dining_philosophers) but the build fails: https://actor-framework.org/doc/dining_philosophers_8cpp-example.html (see added cpp file)
My gcc is georg@xps:~$ c++ --version c++ (Debian 5.3.1-20) 5.3.1 20160519 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. The build: georg@xps:~$ c++ --std=c++14 main2.cpp -lcaf_core -lcaf_io -o test /tmp/ccc1IRHB.o:(.rodata+0x358): undefined reference to `caf::abstract_actor::message_types[abi:cxx11]() const' /tmp/ccc1IRHB.o:(.rodata+0x810): undefined reference to `caf::abstract_actor::message_types[abi:cxx11]() const' /tmp/ccc1IRHB.o: In function `caf::actor_ostream::operator<<(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)': main2.cpp:(.text._ZN3caf13actor_ostreamlsENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN3caf13actor_ostreamlsENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x3e): undefined reference to `caf::actor_ostream::write(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' /tmp/ccc1IRHB.o: In function `std::enable_if<(!std::is_convertible<unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::value)&&(!std::is_convertible<unsigned int, caf::message>::value), caf::actor_ostream&>::type caf::actor_ostream::operator<< <unsigned int>(unsigned int&&)': main2.cpp:(.text._ZN3caf13actor_ostreamlsIjEENSt9enable_ifIXaantsrSt14is_convertibleIT_NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5valuentsrS3_IS4_NS_7messageEE5valueERS0_E4typeEOS4_[_ZN3caf13actor_ostreamlsIjEENSt9enable_ifIXaantsrSt14is_convertibleIT_NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5valuentsrS3_IS4_NS_7messageEE5valueERS0_E4typeEOS4_]+0x3c): undefined reference to `caf::actor_ostream::write(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)' /tmp/ccc1IRHB.o:(.rodata._ZTVN3caf26abstract_event_based_actorINS_14typed_behaviorIJNS_9typed_mpiINS_6detail9type_listIJNS_13atom_constantILNS_10atom_valueE266759210EEEEEENS4_IJNS5_ILS6_17072589491EEEEEENS4_IJNS5_ILS6_262123070EEEEEEEENS2_INS4_IJNS5_ILS6_4153017EEEEEENS4_IJvEEENS4_IJEEEEEEEELb1EEE[_ZTVN3caf26abstract_event_based_actorINS_14typed_behaviorIJNS_9typed_mpiINS_6detail9type_listIJNS_13atom_constantILNS_10atom_valueE266759210EEEEEENS4_IJNS5_ILS6_17072589491EEEEEENS4_IJNS5_ILS6_262123070EEEEEEEENS2_INS4_IJNS5_ILS6_4153017EEEEEENS4_IJvEEENS4_IJEEEEEEEELb1EEE]+0x38): undefined reference to `caf::abstract_actor::message_types[abi:cxx11]() const' /tmp/ccc1IRHB.o:(.rodata._ZTVN3caf26abstract_event_based_actorINS_8behaviorELb1EEE[_ZTVN3caf26abstract_event_based_actorINS_8behaviorELb1EEE]+0x38): undefined reference to `caf::abstract_actor::message_types[abi:cxx11]() const' /tmp/ccc1IRHB.o:(.rodata._ZTVN3caf5mixin16sync_sender_implINS_11local_actorES2_NS_31nonblocking_response_handle_tagEEE[_ZTVN3caf5mixin16sync_sender_implINS_11local_actorES2_NS_31nonblocking_response_handle_tagEEE]+0x38): undefined reference to `caf::abstract_actor::message_types[abi:cxx11]() const' /tmp/ccc1IRHB.o: In function `caf::typed_mpi<caf::detail::type_list<caf::atom_constant<(caf::atom_value)266759210> >, caf::detail::type_list<caf::atom_constant<(caf::atom_value)17072589491> >, caf::detail::type_list<caf::atom_constant<(caf::atom_value)262123070> > >::static_type_name()': main2.cpp:(.text._ZN3caf9typed_mpiINS_6detail9type_listIJNS_13atom_constantILNS_10atom_valueE266759210EEEEEENS2_IJNS3_ILS4_17072589491EEEEEENS2_IJNS3_ILS4_262123070EEEEEEE16static_type_nameEv[_ZN3caf9typed_mpiINS_6detail9type_listIJNS_13atom_constantILNS_10atom_valueE266759210EEEEEENS2_IJNS3_ILS4_17072589491EEEEEENS2_IJNS3_ILS4_262123070EEEEEEE16static_type_nameEv]+0x93): undefined reference to `caf::replies_to_type_name(unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*)' /tmp/ccc1IRHB.o: In function `caf::typed_mpi<caf::detail::type_list<caf::atom_constant<(caf::atom_value)4153017> >, caf::detail::type_list<void>, caf::detail::type_list<> >::static_type_name()': main2.cpp:(.text._ZN3caf9typed_mpiINS_6detail9type_listIJNS_13atom_constantILNS_10atom_valueE4153017EEEEEENS2_IJvEEENS2_IJEEEE16static_type_nameEv[_ZN3caf9typed_mpiINS_6detail9type_listIJNS_13atom_constantILNS_10atom_valueE4153017EEEEEENS2_IJvEEENS2_IJEEEE16static_type_nameEv]+0x74): undefined reference to `caf::replies_to_type_name(unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*)' collect2: error: ld returned 1 exit status --- System information. --- Architecture: amd64 Kernel: Linux 4.5.0-2-amd64 Debian Release: stretch/sid 500 testing ftp.de.debian.org 500 stable dl.google.com --- Package information. --- Package's Depends field is empty. Package's Recommends field is empty. Package's Suggests field is empty. -- pgp key: 0x702C5BFC Fingerprint: 267F DC06 7F96 3375 969A 9EE6 8E37 7CF4 702C 5BFC
/******************************************************************************\ * This example is an implementation of the classical Dining Philosophers * * exercise using only libcaf's event-based actor implementation. * \ ******************************************************************************/ #include <map> #include <vector> #include <chrono> #include <sstream> #include <iostream> #include "caf/all.hpp" using std::cout; using std::cerr; using std::endl; using std::chrono::seconds; using namespace caf; namespace { // atoms for chopstick interface using put_atom = atom_constant<atom("put")>; using take_atom = atom_constant<atom("take")>; using busy_atom = atom_constant<atom("busy")>; using taken_atom = atom_constant<atom("taken")>; // atoms for philosopher interface using eat_atom = atom_constant<atom("eat")>; using think_atom = atom_constant<atom("think")>; // a chopstick using chopstick = typed_actor<replies_to<take_atom> ::with_either<taken_atom> ::or_else<busy_atom>, reacts_to<put_atom>>; chopstick::behavior_type taken_chopstick(chopstick::pointer self, actor_addr); // either taken by a philosopher or available chopstick::behavior_type available_chopstick(chopstick::pointer self) { return { [=](take_atom) { self->become(taken_chopstick(self, self->current_sender())); return taken_atom::value; }, [](put_atom) { cerr << "chopstick received unexpected 'put'" << endl; } }; } chopstick::behavior_type taken_chopstick(chopstick::pointer self, actor_addr user) { return { [](take_atom) { return busy_atom::value; }, [=](put_atom) { if (self->current_sender() == user) { self->become(available_chopstick(self)); } } }; } /* Based on: http://www.dalnefre.com/wp/2010/08/dining-philosophers-in-humus/ * * * +-------------+ {busy|taken} * /-------->| thinking |<------------------\ * | +-------------+ | * | | | * | | {eat} | * | | | * | V | * | +-------------+ {busy} +-------------+ * | | hungry |----------->| denied | * | +-------------+ +-------------+ * | | * | | {taken} * | | * | V * | +-------------+ * | | granted | * | +-------------+ * | | | * | {busy} | | {taken} * \-----------/ | * | V * | {think} +-------------+ * \---------| eating | * +-------------+ */ class philosopher : public event_based_actor { public: philosopher(const std::string& n, const chopstick& l, const chopstick& r) : name(n), left(l), right(r) { // a philosopher that receives {eat} stops thinking and becomes hungry thinking.assign( [=](eat_atom) { become(hungry); send(left, take_atom::value); send(right, take_atom::value); } ); // wait for the first answer of a chopstick hungry.assign( [=](taken_atom) { become(granted); }, [=](busy_atom) { become(denied); } ); // philosopher was able to obtain the first chopstick granted.assign( [=](taken_atom) { aout(this) << name << " has picked up chopsticks with IDs " << left->id() << " and " << right->id() << " and starts to eat\n"; // eat some time delayed_send(this, seconds(5), think_atom::value); become(eating); }, [=](busy_atom) { send(current_sender() == left ? right : left, put_atom::value); send(this, eat_atom::value); become(thinking); } ); // philosopher was *not* able to obtain the first chopstick denied.assign( [=](taken_atom) { send(current_sender() == left ? left : right, put_atom::value); send(this, eat_atom::value); become(thinking); }, [=](busy_atom) { send(this, eat_atom::value); become(thinking); } ); // philosopher obtained both chopstick and eats (for five seconds) eating.assign( [=](think_atom) { send(left, put_atom::value); send(right, put_atom::value); delayed_send(this, seconds(5), eat_atom::value); aout(this) << name << " puts down his chopsticks and starts to think\n"; become(thinking); } ); } protected: behavior make_behavior() override { // start thinking send(this, think_atom::value); // philosophers start to think after receiving {think} return ( [=](think_atom) { aout(this) << name << " starts to think\n"; delayed_send(this, seconds(5), eat_atom::value); become(thinking); } ); } private: std::string name; // the name of this philosopher chopstick left; // left chopstick chopstick right; // right chopstick behavior thinking; // initial behavior behavior hungry; // tries to take chopsticks behavior granted; // has one chopstick and waits for the second one behavior denied; // could not get first chopsticks behavior eating; // waits for some time, then go thinking again }; void dining_philosophers() { scoped_actor self; // create five chopsticks aout(self) << "chopstick ids are:"; std::vector<chopstick> chopsticks; for (size_t i = 0; i < 5; ++i) { chopsticks.push_back(spawn_typed(available_chopstick)); aout(self) << " " << chopsticks.back()->id(); } aout(self) << endl; // spawn five philosophers std::vector<std::string> names {"Plato", "Hume", "Kant", "Nietzsche", "Descartes"}; for (size_t i = 0; i < 5; ++i) { spawn<philosopher>(names[i], chopsticks[i], chopsticks[(i + 1) % 5]); } } } // namespace <anonymous> int main(int, char**) { dining_philosophers(); // real philosophers are never done await_all_actors_done(); shutdown(); }