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();
}

Reply via email to