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