Commit d7653648 authored by Dominik Charousset's avatar Dominik Charousset

Fix setup for Qt and Protobuf examples

parent 52110a9b
FROM centos:7 FROM centos:7
RUN yum update -y \ RUN yum update -y \
&& yum install -y centos-release-scl \ && yum install -y centos-release-scl \
&& yum install -y epel-release \ && yum install -y epel-release \
&& yum update -y \ && yum update -y \
&& yum clean all && yum install -y \
cmake3 \
RUN yum install -y \ devtoolset-7 \
cmake3 \ devtoolset-7-libasan-devel \
devtoolset-7 \ devtoolset-7-libubsan-devel \
devtoolset-7-libasan-devel \ git \
devtoolset-7-libubsan-devel \ make \
git \ openssl-devel \
make \ && yum clean all
openssl-devel \
&& yum clean all
ENV CXX=/opt/rh/devtoolset-7/root/usr/bin/g++ ENV CXX=/opt/rh/devtoolset-7/root/usr/bin/g++
FROM centos:8 FROM centos:8
RUN yum install -y \ RUN dnf update -y \
cmake \ && dnf install -y \
gcc-c++ \ cmake \
libasan \ gcc-c++ \
libubsan \ git \
git \ libasan \
make \ libubsan \
openssl-devel \ make \
&& yum clean all openssl-devel \
&& dnf clean all
FROM debian:10 FROM debian:10
RUN apt update -y && \ RUN apt update -y \
apt upgrade -y && apt upgrade -y \
&& apt install -y \
RUN apt install -y \ cmake \
cmake \ g++ \
g++ \ git \
git \ libssl-dev \
libssl-dev \ make \
make \ && apt autoclean
&& apt autoclean
FROM debian:9 FROM debian:9
RUN apt update -y && \ RUN apt update -y \
apt upgrade -y && apt upgrade -y \
&& apt install -y \
RUN apt install -y \ clang-7 \
clang-7 \ cmake \
libc++-7-dev \ git \
libc++abi-7-dev \ libc++-7-dev \
cmake \ libc++abi-7-dev \
git \ libprotobuf-dev \
libssl-dev \ libssl-dev \
make \ make \
&& apt autoclean && apt autoclean
ENV CXX=/usr/bin/clang++-7 ENV CXX=/usr/bin/clang++-7
ENV CXXFLAGS=-stdlib=libc++ ENV CXXFLAGS=-stdlib=libc++
FROM fedora:31 FROM fedora:31
RUN dnf update -y && \ RUN dnf update -y \
dnf clean all && dnf clean all \
&& dnf install -y \
RUN dnf install -y \ cmake \
git \ gcc-c++ \
make \ git \
cmake \ libasan \
gcc-c++ \ libubsan \
openssl-devel \ make \
libasan \ openssl-devel \
libubsan \ && dnf clean all
&& dnf clean all
FROM fedora:32 FROM fedora:32
RUN dnf update -y && \ RUN dnf update -y \
dnf clean all && dnf clean all \
&& dnf install -y \
RUN dnf install -y \ cmake \
git \ gcc-c++ \
make \ git \
cmake \ libasan \
gcc-c++ \ libubsan \
openssl-devel \ make \
libasan \ openssl-devel \
libubsan \ && dnf clean all
libcurl-devel \
qt5-devel \
protobuf-devel \
&& dnf clean all
FROM ubuntu:16.04 FROM ubuntu:16.04
RUN \ RUN apt update -y \
apt update -y \ && apt upgrade -y \
&& apt upgrade -y \ && apt install -y \
&& apt install -y \ clang-8 \
clang-8 \ cmake \
libc++-8-dev \ git \
libc++abi-8-dev \ libc++-8-dev \
cmake \ libc++abi-8-dev \
git \ libssl-dev \
libssl-dev \ make \
make \ && apt autoclean
&& apt autoclean
ENV CXX=/usr/bin/clang++-8 ENV CXX=/usr/bin/clang++-8
ENV CXXFLAGS=-stdlib=libc++ ENV CXXFLAGS=-stdlib=libc++
FROM ubuntu:18.04 FROM ubuntu:18.04
RUN apt update -y && \ RUN apt update -y \
apt upgrade -y && apt upgrade -y \
&& apt install -y \
RUN apt install -y \ cmake \
cmake \ g++-8 \
g++-8 \ git \
git \ libssl-dev \
libssl-dev \ make \
make \ && apt-get autoclean
&& apt-get autoclean
ENV CXX=/usr/bin/g++-8 ENV CXX=/usr/bin/g++-8
FROM ubuntu:20.04 FROM ubuntu:20.04
ENV TZ=Europe/Berlin RUN apt update -y \
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && apt upgrade -y \
&& DEBIAN_FRONTEND="noninteractive" apt install -y \
RUN apt update -y && \ cmake \
apt upgrade -y g++ \
git \
RUN apt install -y \ libssl-dev \
cmake \ make \
g++ \ && apt-get autoclean
git \
libssl-dev \
make \
&& apt-get autoclean
...@@ -59,4 +59,7 @@ SpacesInParentheses: false ...@@ -59,4 +59,7 @@ SpacesInParentheses: false
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
Standard: Cpp11 Standard: Cpp11
UseTab: Never UseTab: Never
---
Language: Proto
DisableFormat: true
... ...
...@@ -17,8 +17,9 @@ config = [ ...@@ -17,8 +17,9 @@ config = [
], ],
// Default CMake flags by build type. // Default CMake flags by build type.
buildFlags: [ buildFlags: [
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=ON',
'CAF_ENABLE_ACTOR_PROFILER:BOOL=ON', 'CAF_ENABLE_ACTOR_PROFILER:BOOL=ON',
'CAF_ENABLE_EXAMPLES:BOOL=ON',
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=ON',
], ],
extraDebugFlags: [ extraDebugFlags: [
'CAF_LOG_LEVEL:STRING=TRACE', 'CAF_LOG_LEVEL:STRING=TRACE',
...@@ -107,25 +108,16 @@ config = [ ...@@ -107,25 +108,16 @@ config = [
'LDFLAGS=-fno-sanitize-recover=undefined', 'LDFLAGS=-fno-sanitize-recover=undefined',
], ],
]], ]],
// One extra debug build with all examples. // Other UNIX systems. On macOS, we also build *all* examples.
['fedora-32', [
numCores: 4,
tags: ['docker'],
builds: ['debug'],
extraBuildFlags: [
'CAF_ENABLE_EXAMPLES:BOOL=ON',
'CAF_ENABLE_QT5_EXAMPLES:BOOL=ON',
'CAF_ENABLE_CURL_EXAMPLES:BOOL=ON',
'CAF_ENABLE_PROTOBUF_EXAMPLES:BOOL=ON',
],
]],
// Other UNIX systems.
['macOS', [ ['macOS', [
numCores: 4, numCores: 4,
builds: ['debug', 'release'], builds: ['debug', 'release'],
extraBuildFlags: [ extraBuildFlags: [
'CAF_ENABLE_CURL_EXAMPLES:BOOL=ON',
'CAF_ENABLE_PROTOBUF_EXAMPLES:BOOL=ON',
'CAF_ENABLE_QT5_EXAMPLES:BOOL=ON',
'OPENSSL_ROOT_DIR:PATH=/usr/local/opt/openssl', 'OPENSSL_ROOT_DIR:PATH=/usr/local/opt/openssl',
'OPENSSL_INCLUDE_DIR:PATH=/usr/local/opt/openssl/include', 'Qt5_DIR:PATH=/usr/local/opt/qt/lib/cmake/Qt5',
], ],
extraDebugBuildFlags: [ extraDebugBuildFlags: [
'CAF_SANITIZERS:STRING=address', 'CAF_SANITIZERS:STRING=address',
...@@ -145,7 +137,7 @@ config = [ ...@@ -145,7 +137,7 @@ config = [
//builds: ['debug', 'release'], //builds: ['debug', 'release'],
builds: ['release'], builds: ['release'],
extraBuildFlags: [ extraBuildFlags: [
'CAF_ENABLE_OPENSSL_MODULE:BOOL=OFF' 'CAF_ENABLE_OPENSSL_MODULE:BOOL=OFF',
], ],
]], ]],
], ],
......
...@@ -70,7 +70,6 @@ Influential Environment Variables (only on first invocation): ...@@ -70,7 +70,6 @@ Influential Environment Variables (only on first invocation):
CXX C++ compiler command CXX C++ compiler command
CXXFLAGS Additional C++ compiler flags CXXFLAGS Additional C++ compiler flags
LDFLAGS Additional linker flags LDFLAGS Additional linker flags
CMAKE_GENERATOR Selects a custom generator
" "
# Appends a CMake cache entry definition to the CMakeCacheEntries variable. # Appends a CMake cache entry definition to the CMakeCacheEntries variable.
......
...@@ -82,28 +82,31 @@ if(TARGET CAF::io) ...@@ -82,28 +82,31 @@ if(TARGET CAF::io)
if(CAF_ENABLE_QT5_EXAMPLES) if(CAF_ENABLE_QT5_EXAMPLES)
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
message(STATUS "Found Qt5") qt5_wrap_ui(GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui)
#include(${QT_USE_FILE}) qt5_wrap_cpp(GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp)
QT5_ADD_RESOURCES(GROUP_CHAT_RCS )
QT5_WRAP_UI(GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui)
QT5_WRAP_CPP(GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp)
# generated headers will be in cmake build directory # generated headers will be in cmake build directory
include_directories(qtsupport
${CMAKE_CURRENT_BINARY_DIR}
${Qt5Core_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS})
set(GROUP_CHAT_SRC qtsupport/qt_group_chat.cpp qtsupport/chatwidget.cpp)
add_executable(qt_group_chat add_executable(qt_group_chat
${GROUP_CHAT_SRC} qtsupport/qt_group_chat.cpp
qtsupport/chatwidget.cpp
${GROUP_CHAT_MOC_SRC} ${GROUP_CHAT_MOC_SRC}
${GROUP_CHAT_UI_HDR}) ${GROUP_CHAT_UI_HDR})
target_link_libraries(qt_group_chat target_link_libraries(qt_group_chat
CAF::io
CAF::internal
Qt5::Core Qt5::Core
Qt5::Gui Qt5::Gui
Qt5::Widgets Qt5::Widgets)
CAF::io target_include_directories(qt_group_chat PRIVATE
CAF::internal) qtsupport
${CMAKE_CURRENT_BINARY_DIR}
${Qt5Core_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS})
if (CMAKE_VERSION VERSION_LESS 3.8)
message(STATUS "Note: build fails if Qt5 sets incompatible -std=ARG flag")
else()
set_property(TARGET qt_group_chat PROPERTY CXX_STANDARD 17)
endif()
add_dependencies(qt_group_chat all_examples) add_dependencies(qt_group_chat all_examples)
endif() endif()
......
#include <vector> #include <iostream>
#include <string>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <iostream> #include <string>
#include <vector>
#include "caf/all.hpp" #include "caf/all.hpp"
#include "caf/io/all.hpp" #include "caf/io/all.hpp"
#ifdef CAF_WINDOWS #ifdef CAF_WINDOWS
#include <winsock2.h> # include <winsock2.h>
#else #else
#include <arpa/inet.h> # include <arpa/inet.h>
#endif #endif
CAF_PUSH_WARNINGS CAF_PUSH_WARNINGS
...@@ -25,15 +25,13 @@ CAF_END_TYPE_ID_BLOCK(protobuf_example) ...@@ -25,15 +25,13 @@ CAF_END_TYPE_ID_BLOCK(protobuf_example)
namespace { namespace {
using namespace std;
using namespace caf; using namespace caf;
using namespace caf::io; using namespace caf::io;
// utility function to print an exit message with custom name // utility function to print an exit message with custom name
void print_on_exit(scheduled_actor* self, const std::string& name) { void print_on_exit(scheduled_actor* self, const std::string& name) {
self->attach_functor([=](const error& reason) { self->attach_functor([=](const error& reason) {
aout(self) << name << " exited: " << to_string(reason) << endl; aout(self) << name << " exited: " << to_string(reason) << std::endl;
}); });
} }
...@@ -43,14 +41,16 @@ struct ping_state { ...@@ -43,14 +41,16 @@ struct ping_state {
behavior ping(stateful_actor<ping_state>* self, size_t num_pings) { behavior ping(stateful_actor<ping_state>* self, size_t num_pings) {
print_on_exit(self, "ping"); print_on_exit(self, "ping");
return {[=](kickoff_atom, const actor& pong) { return {
self->send(pong, ping_atom_v, 1); [=](kickoff_atom, const actor& pong) {
self->become([=](pong_atom, int value) -> message { self->send(pong, ping_atom_v, 1);
if (++(self->state.count) >= num_pings) self->become([=](pong_atom, int value) -> result<ping_atom, int> {
self->quit(); if (++(self->state.count) >= num_pings)
return make_message(ping_atom_v, value + 1); self->quit();
}); return {ping_atom_v, value + 1};
}}; });
},
};
} }
behavior pong(event_based_actor* self) { behavior pong(event_based_actor* self) {
...@@ -62,44 +62,43 @@ behavior pong(event_based_actor* self) { ...@@ -62,44 +62,43 @@ behavior pong(event_based_actor* self) {
void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) { void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) {
print_on_exit(self, "protobuf_io"); print_on_exit(self, "protobuf_io");
aout(self) << "protobuf broker started" << endl; aout(self) << "protobuf broker started" << std::endl;
self->monitor(buddy); self->monitor(buddy);
self->set_down_handler( self->set_down_handler([=](const down_msg& dm) {
[=](const down_msg& dm) { if (dm.source == buddy) {
if (dm.source == buddy) { aout(self) << "our buddy is down" << std::endl;
aout(self) << "our buddy is down" << endl; self->quit(dm.reason);
self->quit(dm.reason); }
} });
}); auto write = [=](const org::caf::PingOrPong& p) {
auto write = [=](const org::libcppa::PingOrPong& p) { std::string buf = p.SerializeAsString();
string buf = p.SerializeAsString();
auto s = htonl(static_cast<uint32_t>(buf.size())); auto s = htonl(static_cast<uint32_t>(buf.size()));
self->write(hdl, sizeof(uint32_t), &s); self->write(hdl, sizeof(uint32_t), &s);
self->write(hdl, buf.size(), buf.data()); self->write(hdl, buf.size(), buf.data());
self->flush(hdl); self->flush(hdl);
}; };
message_handler default_bhvr = { auto default_callbacks = message_handler{
[=](const connection_closed_msg&) { [=](const connection_closed_msg&) {
aout(self) << "connection closed" << endl; aout(self) << "connection closed" << std::endl;
self->send_exit(buddy, exit_reason::remote_link_unreachable); self->send_exit(buddy, exit_reason::remote_link_unreachable);
self->quit(exit_reason::remote_link_unreachable); self->quit(exit_reason::remote_link_unreachable);
}, },
[=](ping_atom, int i) { [=](ping_atom, int i) {
aout(self) << "'ping' " << i << endl; aout(self) << "'ping' " << i << std::endl;
org::libcppa::PingOrPong p; org::caf::PingOrPong p;
p.mutable_ping()->set_id(i); p.mutable_ping()->set_id(i);
write(p); write(p);
}, },
[=](pong_atom, int i) { [=](pong_atom, int i) {
aout(self) << "'pong' " << i << endl; aout(self) << "'pong' " << i << std::endl;
org::libcppa::PingOrPong p; org::caf::PingOrPong p;
p.mutable_pong()->set_id(i); p.mutable_pong()->set_id(i);
write(p); write(p);
} },
}; };
auto await_protobuf_data = message_handler { auto await_protobuf_data = message_handler {
[=](const new_data_msg& msg) { [=](const new_data_msg& msg) {
org::libcppa::PingOrPong p; org::caf::PingOrPong p;
p.ParseFromArray(msg.buf.data(), static_cast<int>(msg.buf.size())); p.ParseFromArray(msg.buf.data(), static_cast<int>(msg.buf.size()));
if (p.has_ping()) { if (p.has_ping()) {
self->send(buddy, ping_atom_v, p.ping().id()); self->send(buddy, ping_atom_v, p.ping().id());
...@@ -109,20 +108,20 @@ void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) { ...@@ -109,20 +108,20 @@ void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) {
} }
else { else {
self->quit(exit_reason::user_shutdown); self->quit(exit_reason::user_shutdown);
cerr << "neither Ping nor Pong!" << endl; std::cerr << "neither Ping nor Pong!" << std::endl;
} }
// receive next length prefix // receive next length prefix
self->configure_read(hdl, receive_policy::exactly(sizeof(uint32_t))); self->configure_read(hdl, receive_policy::exactly(sizeof(uint32_t)));
self->unbecome(); self->unbecome();
} },
}.or_else(default_bhvr); }.or_else(default_callbacks);
auto await_length_prefix = message_handler { auto await_length_prefix = message_handler {
[=](const new_data_msg& msg) { [=](const new_data_msg& msg) {
uint32_t num_bytes; uint32_t num_bytes;
memcpy(&num_bytes, msg.buf.data(), sizeof(uint32_t)); memcpy(&num_bytes, msg.buf.data(), sizeof(uint32_t));
num_bytes = htonl(num_bytes); num_bytes = htonl(num_bytes);
if (num_bytes > (1024 * 1024)) { if (num_bytes > (1024 * 1024)) {
aout(self) << "someone is trying something nasty" << endl; aout(self) << "someone is trying something nasty" << std::endl;
self->quit(exit_reason::user_shutdown); self->quit(exit_reason::user_shutdown);
return; return;
} }
...@@ -130,8 +129,8 @@ void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) { ...@@ -130,8 +129,8 @@ void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) {
auto nb = static_cast<size_t>(num_bytes); auto nb = static_cast<size_t>(num_bytes);
self->configure_read(hdl, receive_policy::exactly(nb)); self->configure_read(hdl, receive_policy::exactly(nb));
self->become(keep_behavior, await_protobuf_data); self->become(keep_behavior, await_protobuf_data);
} },
}.or_else(default_bhvr); }.or_else(default_callbacks);
// initial setup // initial setup
self->configure_read(hdl, receive_policy::exactly(sizeof(uint32_t))); self->configure_read(hdl, receive_policy::exactly(sizeof(uint32_t)));
self->become(await_length_prefix); self->become(await_length_prefix);
...@@ -139,14 +138,14 @@ void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) { ...@@ -139,14 +138,14 @@ void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) {
behavior server(broker* self, const actor& buddy) { behavior server(broker* self, const actor& buddy) {
print_on_exit(self, "server"); print_on_exit(self, "server");
aout(self) << "server is running" << endl; aout(self) << "server is running" << std::endl;
return { return {
[=](const new_connection_msg& msg) { [=](const new_connection_msg& msg) {
aout(self) << "server accepted new connection" << endl; aout(self) << "server accepted new connection" << std::endl;
auto io_actor = self->fork(protobuf_io, msg.handle, buddy); auto io_actor = self->fork(protobuf_io, msg.handle, buddy);
// only accept 1 connection in our example // only accept 1 connection in our example
self->quit(); self->quit();
} },
}; };
} }
...@@ -158,30 +157,30 @@ public: ...@@ -158,30 +157,30 @@ public:
config() { config() {
opt_group{custom_options_, "global"} opt_group{custom_options_, "global"}
.add(port, "port,p", "set port") .add(port, "port,p", "set port")
.add(host, "host,H", "set host (ignored in server mode)") .add(host, "host,H", "set host (ignored in server mode)")
.add(server_mode, "server-mode,s", "enable server mode"); .add(server_mode, "server-mode,s", "enable server mode");
} }
}; };
void run_server(actor_system& system, const config& cfg) { void run_server(actor_system& system, const config& cfg) {
cout << "run in server mode" << endl; std::cout << "run in server mode" << std::endl;
auto pong_actor = system.spawn(pong); auto pong_actor = system.spawn(pong);
auto server_actor = system.middleman().spawn_server(server, cfg.port, auto server_actor = system.middleman().spawn_server(server, cfg.port,
pong_actor); pong_actor);
if (!server_actor) if (!server_actor)
cerr << "unable to spawn server: " << to_string(server_actor.error()) std::cerr << "unable to spawn server: " << to_string(server_actor.error())
<< endl; << std::endl;
} }
void run_client(actor_system& system, const config& cfg) { void run_client(actor_system& system, const config& cfg) {
cout << "run in client mode" << endl; std::cout << "run in client mode" << std::endl;
auto ping_actor = system.spawn(ping, 20u); auto ping_actor = system.spawn(ping, 20u);
auto io_actor = system.middleman().spawn_client(protobuf_io, cfg.host, auto io_actor = system.middleman().spawn_client(protobuf_io, cfg.host,
cfg.port, ping_actor); cfg.port, ping_actor);
if (!io_actor) { if (!io_actor) {
cout << "cannot connect to " << cfg.host << " at port " << cfg.port << ": " std::cout << "cannot connect to " << cfg.host << " at port " << cfg.port
<< to_string(io_actor.error()) << endl; << ": " << to_string(io_actor.error()) << std::endl;
return; return;
} }
send_as(*io_actor, ping_actor, kickoff_atom_v, *io_actor); send_as(*io_actor, ping_actor, kickoff_atom_v, *io_actor);
......
...@@ -75,7 +75,10 @@ void ChatWidget::sendChatMessage() { ...@@ -75,7 +75,10 @@ void ChatWidget::sendChatMessage() {
// Ignore empty lines. // Ignore empty lines.
} else if (line.startsWith('/')) { } else if (line.startsWith('/')) {
vector<string> words; vector<string> words;
split(words, line.midRef(1).toUtf8().constData(), is_any_of(" ")); auto utf8 = line.midRef(1).toUtf8();
auto sv = caf::string_view{utf8.constData(),
static_cast<size_t>(utf8.size())};
split(words, sv, is_any_of(" "));
if (words.size() == 3 && words[0] == "join") { if (words.size() == 3 && words[0] == "join") {
if (auto x = system().groups().get(words[1], words[2])) if (auto x = system().groups().get(words[1], words[2]))
send_as(as_actor(), as_actor(), join_atom_v, std::move(*x)); send_as(as_actor(), as_actor(), join_atom_v, std::move(*x));
......
package org.libcppa; syntax = "proto2";
package org.caf;
message Ping { message Ping {
required int32 id = 1; required int32 id = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment