Installation¶
RBE is header-only. Installing it means making the rbe/ headers visible to your compiler and enabling
C++26 reflection.
Requirements¶
| Requirement | Version | Notes |
|---|---|---|
| Compiler | GCC ≥ 16 | The only compiler with C++26 static reflection (P2996) and annotations (P3394) today. Clang and MSVC are not supported yet. |
| Flags | -std=c++26 -freflection -Wno-attributes |
-Wno-attributes silences GCC's warning on annotations it does not recognize as attributes. The CMake target and the Conan package add them for you. |
| CMake | ≥ 3.31 | Only for the CMake and Conan routes. |
| Conan | ≥ 2.0.15 | Only for the Conan route. |
GCC snapshots
CI builds with GCC 16.1. Ubuntu's 16.0.1 snapshot miscompiles reflection code; use a release build of
GCC 16.
Conan¶
Add the requirement to your conanfile.txt (or conanfile.py):
Then install and consume it as a CMake package:
The rbe::rbe target carries the include path and the reflection flags. The recipe rejects any compiler
other than GCC 16 at install time rather than failing later in the build.
Single header through Conan
With -o rbe/*:single_header=True the package ships the whole library as one rbe/rbe.hpp instead of
the header tree. Code written against #include <rbe/rbe.hpp> builds with either.
CMake subproject¶
Clone or vendor the repository and add the library's own src/ directory, which defines the rbe target:
Or fetch it at configure time:
include(FetchContent)
FetchContent_Declare(rbe GIT_REPOSITORY https://github.com/ch0pex/rbe.git GIT_TAG main SOURCE_SUBDIR src)
FetchContent_MakeAvailable(rbe)
target_link_libraries(my_app PRIVATE rbe::rbe)
The top-level CMakeLists.txt of the repository also builds the tests and examples, and needs Conan for
doctest; src/ is the library alone.
Single header¶
Copy single_include/rbe/rbe.hpp into your include path and compile with the flags yourself:
The single header is generated from src/rbe on every commit, so it always matches the header tree. The
granular headers (<rbe/annotations.hpp>, <rbe/frames.hpp>, ...) exist only in the tree; with the single
header everything comes from <rbe/rbe.hpp>.
Verify¶
The smallest program that proves the toolchain works:
#include <rbe/rbe.hpp>
#include <array>
#include <print>
struct [[=rbe::pack_be]] Header {
std::uint16_t length;
std::uint8_t type;
};
auto main() -> int {
std::array<std::byte, rbe::wire_size_of<Header>()> buffer {};
rbe::serialize(buffer, Header {.length = 3, .type = 1});
std::println("{} bytes on the wire, {} in memory", buffer.size(), sizeof(Header)); // 3 bytes on the wire, 4 in memory
}
Next: the Overview walks through the whole library on one protocol.