Git Product home page Git Product logo

chrberger / libcluon Goto Github PK

View Code? Open in Web Editor NEW
96.0 2.0 13.0 463.21 MB

libcluon is a small and efficient, single-file and header-only library written in modern C++ to power microservices.

License: Mozilla Public License 2.0

Makefile 0.23% CMake 5.03% Shell 1.75% Roff 0.04% Inno Setup 0.31% C++ 92.25% Python 0.32% Dockerfile 0.06%
cpp header-only protobuf lcm msgpack json javascript robotics cpp14 linux

libcluon's Introduction

libcluon

Linux & OSX Build (TravisCI) Win64 Build (AppVeyor) Test Coverage Coverity Analysis CII Best Practices
Build Status Build status codecov Coverity Scan CII Best Practices

License API documentation Win (x86_64) Ubuntu (x86_64) Ubuntu (armhf) Ubuntu (aarch64) Ubuntu (s390x) Ubuntu (powerpc) Alpine (x86_64) Alpine (armhf) Alpine (aarch64)

libcluon is a small single-file, header-only library written in modern C++ library to glue microservices - in a clever way - simply: cluon. Its name is inspired by gluon, an elementary particle acting as exchange particle.

libcluon is distributed as single-file, header-only library - just drop cluon-complete.hpp into your project, #include "cluon-complete.hpp", and compile your project with a modern C++ compiler (C++14 or newer)

Say you want to quickly realize a distributed software system where individual software components exchange messages and you want to keep your project as simple and clean as possible - that's a typical use-case for libcluon. Getting Started Tutorial using an online C++ compiler.

Table of Contents

Features

  • Written in highly portable and high quality C++14
  • Available as header-only, single-file distribution - just drop cluon-complete.hpp into your project, #include "cluon-complete.hpp", and compile your project with a modern C++ compiler (C++14 or newer)
  • Message compiler produces fully self-contained messages that do only depend on C++14 - external libraries are not needed allowing easy embedding into existing projects
  • Native implementation of Protobuf for data serialization & deserialization: Example
  • Native implementation of LCM/ZCM for data serialization & deserialization: Example
  • Native implementation of JSON for data serialization & deserialization: Example
  • Native implementation of MsgPack for data serialization & deserialization: Example
  • libcluon natively available for JavaScript via Emscripten: libcluon.js
  • Portable implementation of publish/subscribe communication (Linux, MacOSX, Windows): Example
  • Intermediate Data Representation (IDR) enables flexible message transformations at runtime; for example: Convert Protobuf to JSON or convert OD4 to JSON or convert LCM to JSON at runtime without generating any data structures beforehand
  • Message self-reflection to extract portable message specifications at runtime: Examples
  • Message transformatiom into platform-independent CSV format: Examples

Dependencies

No dependencies! All you need is a C++14-compliant compiler as the project ships the following dependencies as part of the source distribution:

As part of our CI strategy thanks to TravisCI and AppVeyor, we are continuously building with:

  • Darwin 16.7.0 (x86_64)/AppleClang 9.0.0.9000038

  • FreeBSD 11.1 (x86_64)/GCC 6.4.0

  • NetBSD 8.0 (x86_64)/GCC 5.5.0

  • OpenBSD 6.3 (x86_64)/clang 5.0.1

  • Windows (x86_64)/MSVC 19.13.26129.0

  • Ubuntu 18.04 LTS (x86_64)/GCC 7.4.0

  • Ubuntu 18.04 LTS (x86_64)/clang 7.0.0

  • Ubuntu 16.04 LTS (x86_64)/GCC 5.4.0

  • Ubuntu 16.04 LTS (x86_64)/clang 7.0.0

  • Ubuntu 14.04 LTS (armhf)/clang 3.8.1

  • Ubuntu 14.04 LTS (x86_64)/GCC 8.0.1

  • Ubuntu 14.04 LTS (x86_64)/GCC 7.3.0

  • Ubuntu 14.04 LTS (x86_64)/GCC 6.4.0

  • Ubuntu 14.04 LTS (x86_64)/GCC 5.5.0

  • Ubuntu 14.04 LTS (x86_64)/clang 6.0.1

  • Ubuntu 14.04 LTS (x86_64)/clang 5.0.2

  • Ubuntu 14.04 LTS (x86_64)/clang 5.0.0

  • Ubuntu 14.04 LTS (x86_64)/clang 4.0.1

  • Ubuntu 14.04 LTS (x86_64)/clang 3.9.1

  • Ubuntu 14.04 LTS (x86_64)/clang 3.8.0

Installation

Installation as single-file, header-only library

libcluon is provided as header-only, single-file library as well - just drop cluon-complete.hpp into your project, #include "cluon-complete.hpp" where you want to use libcluon, and compile your project with a modern C++ compiler (C++14 or newer).

Installation on Ubuntu 20.04 LTS

We are providing pre-compiled binaries for Ubuntu 20.04 LTS (Focal Fossa) via Ubuntu's Launchpad for amd64, i386, armfh, and arm64; simply add the following PPA to your sources list:

sudo add-apt-repository ppa:chrberger/libcluon

Afterwards, update your package database and install libcluon:

sudo apt-get update
sudo apt-get install libcluon

Installation on Ubuntu 18.04 LTS

We are providing pre-compiled binaries for Ubuntu 18.04 LTS (Bionic Beaver) via Ubuntu's Launchpad for amd64, i386, armfh, and arm64; simply add the following PPA to your sources list:

sudo add-apt-repository ppa:chrberger/libcluon

Afterwards, update your package database and install libcluon:

sudo apt-get update
sudo apt-get install libcluon

Installation on Debian

To use libcluon on Debian, you need to add the repository key first:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8EA63C9470BA0E595B75BBA2A92E492AC0B8C7EC

Afterwards, install add-apt-repository and its dependencies:

sudo apt install dirmngr software-properties-common

Then, you can add the libcluon repository:

sudo add-apt-repository ppa:chrberger/libcluon

Now, you can finally install libcluon:

sudo apt update && sudo apt install libcluon

Installation on Alpine 3.13

We are providing pre-compiled binaries for Alpine 3.13 for x86_64, armfh, and aarch64; simply install the pre-compile .apk package as follows:

apk add libcluon --no-cache --repository https://chrberger.github.io/libcluon/alpine/v3.13 --allow-untrusted

Installation on Windows

We are providing pre-compiled binaries including debug symbols for Windows 64 via BinTray here: https://bintray.com/chrberger/libcluon/libcluon-win64-debug#files/

Build from sources on the example of Ubuntu 16.04 LTS

To compile libcluon from sources on an Ubuntu 16.04 LTS (Xenial Xerus) system, you need to have build-essential, cmake, and git installed:

sudo apt-get install build-essential git cmake

Afterwards, simply clone our Git repository:

git clone https://github.com/chrberger/libcluon.git

As an alternative, you can download our latest source release from here: https://github.com/chrberger/libcluon/releases/latest

Change to your working copy and create a build folder:

cd libcluon
mkdir build
cd build

Next, run cmake to create the necessary build files:

cmake ../libcluon

Finally, compile and install the software:

make
make test
make install

Tutorials & API Documentation

Contributing

We are happy to receive your PRs to accelerate libcluon's development; before contributing, please take a look at the Contribution Documents.

License

  • This project is released under the terms of the Mozilla Public License 2.0 - License: MPL-2.0 - FAQ
  • Commercial support is available at [email protected]

libcluon's People

Contributors

bjornborg avatar chrberger avatar lyg1949 avatar olbender avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

libcluon's Issues

Feature request/clarification - C++ generated enum of message types

Hi!

Thank you for open sourcing! Looking over unpacking, I was wondering if there's a way of outputting an enum alongside the generated C++ header for the message?

cluon::OD4Session od4(111,
    [](cluon::data::Envelope &&envelope) noexcept {
      if (envelope.dataType() == 2001) {
        MyTestMessage1 receivedMsg = cluon::extractMessage<MyTestMessage1>(std::move(envelope));

        PrimeChecker pc;
        std::cout << receivedMsg.myValue() << " is" 
          << (pc.isPrime(receivedMsg.myValue()) ? " " : " not ")
          << "a prime." << std::endl;
      }
    });

^Use case would be to swap out 2001 with an enum that's generated. Ideally this enum would also be present as generated proto enum (which I think is represented in the protobuf spec? If not, forgive my ignorance!). When I follow the docs the message id gets added as comments in the .proto file.

Cheers!

// Erik

Unable to compile single header on Windows

I cannot get it to compile using Visual Studio 2019 with C++17 standard enabled.

Compiler messages:

1>C:\dev\raspberry-console\socket\cluon.hpp(9806,76): error C2589: 'constant': illegal token on right side of '::'
1>C:\dev\raspberry-console\socket\cluon.hpp(9806,76): error C2062: type 'unknown-type' unexpected
1>C:\dev\raspberry-console\socket\cluon.hpp(9807,19): error C2181: illegal else without matching if
1>C:\dev\raspberry-console\socket\cluon.hpp(9793): error C2317: 'try' block starting on line '9793' has no catch handlers
1>C:\dev\raspberry-console\socket\cluon.hpp(9811,11): error C2181: illegal else without matching if
1>C:\dev\raspberry-console\socket\cluon.hpp(9812,23): error C2065: 'listOfMetaMessages': undeclared identifier
1>C:\dev\raspberry-console\socket\cluon.hpp(9814,7): error C2059: syntax error: 'catch'
1>C:\dev\raspberry-console\socket\cluon.hpp(9814,31): error C2143: syntax error: missing ';' before '{'
1>C:\dev\raspberry-console\socket\cluon.hpp(9814,31): error C2447: '{': missing function header (old-style formal list?)
1>C:\dev\raspberry-console\socket\cluon.hpp(9816,5): error C2059: syntax error: 'return'
1>C:\dev\raspberry-console\socket\cluon.hpp(9818,1): error C2059: syntax error: '}'
1>C:\dev\raspberry-console\socket\cluon.hpp(9818,1): error C2143: syntax error: missing ';' before '}'
1>C:\dev\raspberry-console\socket\cluon.hpp(9833,17): error C2143: syntax error: missing ';' before '{'
1>C:\dev\raspberry-console\socket\cluon.hpp(9833,17): error C2447: '{': missing function header (old-style formal list?)
1>C:\dev\raspberry-console\socket\cluon.hpp(13507,56): error C2589: 'constant': illegal token on right side of '::'
1>C:\dev\raspberry-console\socket\cluon.hpp(13507,8): error C2059: syntax error: '=='
1>C:\dev\raspberry-console\socket\cluon.hpp(13507,90): error C2143: syntax error: missing ';' before '{'
1>C:\dev\raspberry-console\socket\cluon.hpp(14140,56): error C2589: 'constant': illegal token on right side of '::'
1>C:\dev\raspberry-console\socket\cluon.hpp(14140,8): error C2059: syntax error: '=='
1>C:\dev\raspberry-console\socket\cluon.hpp(14140,90): error C2143: syntax error: missing ';' before '{'
1>C:\dev\raspberry-console\socket\cluon.hpp(14417,73): warning C4003: not enough arguments for function-like macro invocation 'max'
1>C:\dev\raspberry-console\socket\cluon.hpp(14417,73): error C2589: '(': illegal token on right side of '::'
1>C:\dev\raspberry-console\socket\cluon.hpp(14417,73): error C2062: type 'unknown-type' unexpected
1>C:\dev\raspberry-console\socket\cluon.hpp(14417,73): error C2059: syntax error: ')'
1>C:\dev\raspberry-console\socket\cluon.hpp(14418,73): warning C4003: not enough arguments for function-like macro invocation 'min'
1>C:\dev\raspberry-console\socket\cluon.hpp(14418,73): error C2589: '(': illegal token on right side of '::'
1>C:\dev\raspberry-console\socket\cluon.hpp(14418,73): error C2062: type 'unknown-type' unexpected
1>C:\dev\raspberry-console\socket\cluon.hpp(14418,73): error C2059: syntax error: ')'
1>C:\dev\raspberry-console\socket\cluon.hpp(14420,44): error C2589: '(': illegal token on right side of '::'
1>C:\dev\raspberry-console\socket\cluon.hpp(14420,44): error C2062: type 'unknown-type' unexpected
1>C:\dev\raspberry-console\socket\cluon.hpp(14420,44): error C2059: syntax error: ')'
1>C:\dev\raspberry-console\socket\cluon.hpp(14421,44): error C2589: '(': illegal token on right side of '::'
1>C:\dev\raspberry-console\socket\cluon.hpp(14421,44): error C2062: type 'unknown-type' unexpected
1>Generating Code...
1>C:\dev\raspberry-console\socket\cluon.hpp(14421,44): error C2059: syntax error: ')'

Looks like it fails while parsing MessageParserErrorCodes::NO_ERROR for some reason.

Some code context:

9804            if (check4UniqueFieldNames(*ast, tmpPrefix, tmpMessageNames, tmpFieldNames, tmpNumericalMessageIdentifiers, tmpNumericalFieldIdentifiers)) {
9805               transform2MetaMessages(*ast, listOfMetaMessages);
9806                retVal = {listOfMetaMessages, MessageParserErrorCodes::NO_ERROR};
9807            } else {
9808                retVal = {listOfMetaMessages, MessageParserErrorCodes::DUPLICATE_IDENTIFIERS};
9809            }

How can one efficiently transmit substantial volumes of data?

How can one efficiently transmit substantial volumes of data?

`using namespace std;

int main()
{
cout << "Hello CMake." << endl;

cluon::OD4Session od4{ 100 };

if (od4.isRunning()) {
    // Let's wait for 5s before start sending our message.
    using namespace std::chrono_literals;
    std::this_thread::sleep_for(1s);
    int count = 0;
    std::vector<uint8_t> data;
    data.resize(1024 *1024);
    int index = 0;
    for(auto& item : data)
    {
        item = index++ % 255;
    }
    // Let's create our message and set some values.
    MyMessage1 msg;
    msg.myNumber(count)
		.data(std::string(data.begin(), data.end()))
        .myText("Hello World!");
    
    //// Finally, send the message.
    while (true)
    {
        msg.myNumber(count++);
        od4.send(msg);
    }
	
}


return 0;

}
`

Warning from compiler: maybe-uninitialized (Version: 0.0.121)

The following warning, treated as error with -Werror flag), was provided by compiler g++ (version 6.4.0-r5) within Alpine 3.7 as docker image builder:

/opt/sources/src/cluon-complete.hpp: In member function 'virtual size_t peg::CharacterClass::parse(const char*, size_t, peg::SemanticValues&, peg::Context&, peg::any&) const': /opt/sources/src/cluon-complete.hpp:1754:39: error: 'cp' may be used uninitialized in this function [-Werror=maybe-uninitialized] if (range.first <= cp && cp <= range.second) { ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~ cc1plus: all warnings being treated as errors

I added a pair of parentheses after the declaration of cp in the line 1749, and the compiler was satisfied.

Time.hpp use system_clock that can be adjusted at any time by the system

Time deltas in LibCluon are computed using cluon::data::TimeStamp now(), but it uses the Chrono-clock std::chrono::system_clock which is not guaranteed not to be adjusted by the system at any time. This can cause problems in applications where the time delta is used to integrate speeds, just as an example. If the system decides to adjust the time backwards a few seconds, or an hour even as is common for daylight saving, then the delta can be a very large or even negative number that can throw off calculations.

For this reason, Chrono also offers a clock called std::chrono::steady_clock that should be used whenever the time delta should be computed. The issue with this clock on the other hand is that it measures time since an unspecified epoch and not necessarily the Unix epoch.

I therefore suggest that the Time.hpp is documented so that it warns users from using cluon::data::TimeStamp now() in time-delta computations and that the alternative steady_clock is used for that instead.

Tutorials are non functional due to online compiler error

The online compiler seems to be giving an error, see below. As far as I can tell wandbox.org is operational.

ReferenceError: twttr is not defined at https://wandbox.org/build/_shared/chunk-HWTQ5KW5.js:104:29713 at Gf (https://wandbox.org/build/_shared/chunk-2LKANNDY.js:9:6560) at L.unstable_runWithPriority (https://wandbox.org/build/_shared/chunk-2LKANNDY.js:1:4026) at rn (https://wandbox.org/build/_shared/chunk-2LKANNDY.js:5:38448) at Xe (https://wandbox.org/build/_shared/chunk-2LKANNDY.js:9:6029) at yi (https://wandbox.org/build/_shared/chunk-2LKANNDY.js:7:10750) at https://wandbox.org/build/_shared/chunk-2LKANNDY.js:5:38670 at L.unstable_runWithPriority (https://wandbox.org/build/_shared/chunk-2LKANNDY.js:1:4026) at rn (https://wandbox.org/build/_shared/chunk-2LKANNDY.js:5:38448) at Cs (https://wandbox.org/build/_shared/chunk-2LKANNDY.js:5:38616)

Messages specifications for Protobuf, MsgPack, ODVD, ...

This project looks like a great idea.

I was trying to test, but I'm confused a bit.

It took me a minute but I eventually understood that I cannot define my protobuf messages using the actual google proto language. I must use the format that the cluon-msc converter understands.

However, that seems pretty limited to scalar values, no arrays or "repeated" structures.

An example in proto language (very simple):

syntax = "proto2";

message SimpleMessage {
  required int32 msg_id = 1;
  optional string msg_string = 2;
}

message ComplexMessage {
  required int32 complex_msg_id = 1;
  repeated SimpleMessage messages = 2;
}

does not have a corresponding sintax in "odvd":

message SimpleMessage [id = 30000] {
    uint32 msg_id [ id = 1 ];
    string msg_payload [ default = "Hello World!", id = 2 ];
}

message ComplexMessage [id = 30001] {
    uint32 complex_msg_id [ id = 1 ];
    ?
}

If I want something more complex like that, am I expected to extend the classes with definitions of things like you have in your cluon::data namespace? I'm asking because I did not see much info on that other than looking at the code.

Thanks in advance.

No switch for disabling the tests in a CMake build?

Using the CMakeLists.txt from the libcluon folder I cant seem to find a way to disable the tests from being configured. This would make life easier when building from source instead of using the single-file, header-only distribution.

[BUILD] Release 0.0.74 does not build

Description: When building from source, build fails at step "Building CXX object CMakeFiles/TestOD4Session.cpp-Runner.dir/testsuites/TestOD4Session.cpp.o"

Steps I performed:

  • Downloaded 0.0.74 Release
  • Created "build" directory in libcluon root directory
  • cmake ../libcluon
  • make
  • Recipe fails at 84% when building CXX Object CMakeFiles/TestOD4Session.cpp-Runner.dir/testsuites/TestOD4Session.cpp.o

Error Message : Pastebin

Compiler warning: -Wreturn-type (v0.0.140)

Using gcc 9.3.0 on Ubuntu 20.04 (wsl2) and cluon-complete.hpp from the latest release (v0.0.140). The compiler gives me the following warning related to a switch statement without default case in a lambda function:

[build] /build/cluon-complete.cpp: In lambda function:
[build] /build/cluon-complete.cpp:3692:5: warning: control reaches end of non-void function [-Wreturn-type]
[build]  3692 |     };
[build]       |     ^

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.