xref: /openbmc/sdbusplus/README.md (revision 9cde21ff)
1# sdbusplus
2
3sdbusplus contains two parts:
4
51. A C++ library (libsdbusplus) for interacting with D-Bus, built on top of
6   the sd-bus library from systemd.
72. A tool (sdbus++) to generate C++ bindings to simplify the development of
8   D-Bus-based applications.
9
10## Dependencies
11
12The sdbusplus library requires sd-bus, which is contained in libsystemd.
13
14The sdbus++ application requires Python 3 and the Python libraries mako
15and inflection.
16
17## Building
18
19The sdbusplus library is built using meson.
20
21```sh
22meson build
23cd build
24ninja
25ninja test
26ninja install
27```
28
29Optionally, building the tests and examples can be disabled by passing
30`-Dtests=disabled` and `-Dexamples=disabled` respectively to `meson.
31
32The sdbus++ application is installed as a standard Python package
33using `setuptools`.
34
35```sh
36cd tools
37./setup.py install
38```
39
40## C++ library
41
42The sdbusplus library builds on top of the
43[sd-bus](http://0pointer.net/blog/the-new-sd-bus-api-of-systemd.html)
44library to create a modern C++ API for D-Bus. The library attempts to be
45as lightweight as possible, usually compiling to exactly the sd-bus API
46calls that would have been necessary, while also providing compile-time
47type-safety and memory leak protection afforded by modern C++ practices.
48
49Consider the following code:
50
51```cpp
52auto b = bus::new_default_system();
53auto m = b.new_method_call("org.freedesktop.login1",
54                           "/org/freedesktop/login1",
55                           "org.freedesktop.login1.Manager",
56                           "ListUsers");
57auto reply = b.call(m);
58
59std::vector<std::tuple<uint32_t, std::string, message::object_path>> users;
60reply.read(users);
61    // or
62auto users = reply.unpack<
63    std::vector<std::tuple<uint32_t, std::string, message::object_path>>>();
64```
65
66In a few, relatively succinct, C++ lines this snippet will create a D-Bus
67connection to the system bus, and call the systemd login manager to get a
68list of active users. The message and bus objects are automatically freed
69when they leave scope and the message format strings are generated at compile
70time based on the types being read. Compare this to the corresponding server
71code within [logind](https://github.com/systemd/systemd/blob/d60c527009133a1ed3d69c14b8c837c790e78d10/src/login/logind-dbus.c#L496).
72
73In general, the library attempts to mimic the naming conventions of the sd-bus
74library: ex. `sd_bus_call` becomes `sdbusplus::bus::call`,
75`sd_bus_get_unique_name` becomes `sdbusplus::bus::get_unique_name`,
76`sd_bus_message_get_signature` becomes `sdbusplus::message::get_signature`,
77etc. This allows a relatively straight-forward translation back to the sd-bus
78functions for looking up the manpage details.
79
80## Binding generation tool
81
82sdbusplus also contains a bindings generator tool: `sdbus++`. The purpose of
83a bindings generator is to reduce the boilerplate associated with creating
84D-Bus server or client applications. When creating a server application,
85rather than creating sd-bus vtables and writing C-style functions to handle
86each vtable callback, you can create a small YAML file to define your D-Bus
87interface and the `sdbus++` tool will create a C++ class that implements your
88D-Bus interface. This class has a set of virtual functions for each method
89and property, which you can overload to create your own customized behavior
90for the interface.
91
92There are currently two types of YAML files: [interface](docs/interface.md) and
93[error](docs/error.md). Interfaces are used to create server and client D-Bus
94interfaces. Errors are used to define C++ exceptions which can be thrown and
95will automatically turn into D-Bus error responses.
96
97[[D-Bus client bindings are not yet implemented.  See openbmc/openbmc#851.]]
98
99### Generating bindings
100
101## How to use tools/sdbus++
102
103The path of your file will be the interface name. For example, for an interface
104`org.freedesktop.Example`, you would create the files
105`org/freedesktop/Example.interface.yaml` and
106`org/freedesktop/Example.errors.yaml]` for interfaces and errors respectively.
107These can then be used to generate the server and error bindings:
108
109```sh
110sdbus++ interface server-header org.freedesktop.Example > \
111    org/freedesktop/Example/server.hpp
112sdbus++ interface server-cpp org.freedesktop.Example > \
113    org/freedesktop/Example/server.cpp
114sdbus++ error exception-header org.freedesktop.Example > \
115    org/freedesktop/Example/error.hpp \
116sdbus++ error exception-cpp org.freedesktop.Example > \
117    org/freedesktop/Example/error.cpp
118```
119
120Markdown-based documentation can also be generated from the interface and
121exception files:
122
123```sh
124sdbus++ interface markdown org.freedesktop.Example > \
125    org/freedesktop/Example.md
126sdbus++ error markdown org.freedesktop.Example >> \
127    org/freedesktop/Example.md
128```
129
130See the `example/meson.build` for more details.
131
132## Installing sdbusplus on custom distributions
133
134Installation of sdbusplus bindings on a custom distribution requires a few
135packages to be installed prior. Although these packages are the same for several
136distributions the names of these packages do differ. Below are the packages
137needed for Ubuntu and Fedora.
138
139### Installation on Ubuntu
140
141```sh
142sudo apt install git meson libtool pkg-config g++ libsystemd-dev \
143    python3 python3-pip python3-yaml python3-mako python3-inflection
144```
145
146### Installation on Fedora
147
148```sh
149sudo dnf install git meson libtool gcc-c++ pkgconfig systemd-devel \
150    python3 python3-pip python3-yaml python3-mako
151```
152
153Install the inflection package using the pip utility (on Fedora)
154
155```sh
156pip3 install inflection
157```
158