namespace rgpot::abi

Overview

namespace abi {
 
// namespaces
 
namespace rgpot::abi::detail;
 
// structs
 
struct CxxSoversionEntry;
struct Expectation;
struct ProfileResult;
 
// classes
 
class ProfileLoader;
 
// global variables
 
std::uint32_t kCxxLayoutRevision = 1;
std::uint32_t kCxxSoversion = 4;
std::array<CxxSoversionEntry, 5> kCxxSoversionTable {{     {“linux-x86_64-libstdc++-lp64”, 0x80bc8962b7808d7aull},     {“linux-aarch64-libstdc++-lp64”, 0x191f6a916fe32962ull},     {“macos-aarch64-libc++-lp64”, 0x293e0e103e91a552ull},     {“macos-x86_64-libc++-lp64”, 0x293e0e103e91a552ull},     {“windows-x86_64-msvc-llp64”, 0x395cb18f0d402142ull}, }};
char kCxxPlatformTag[] = “unknown” “-” “unknown” “-” “unknown” “-”   “ilp32”;
std::uint32_t kPotentialBaseVirtuals = 5;
std::uint32_t kPotentialBaseCacheVirtuals = 1;
std::uint32_t kPotentialVirtuals = 2;
std::uint32_t kFeatures = 0;
const char* kProtocolFamily = “rgpot.potentials”;
uint16_t kProtocolMajor = 1;
uint16_t kProtocolMinor = 0;
const char* kSchemaId = “0xbd1f89fa17369103”;
 
// global functions
 
void checked_load(ProfileLoader& loader, const std::string& prefix, const std::string& explicit_path = “”, const Expectation& want = {});
bool cxx_tag_eq(const char* a, const char* b);
const CxxSoversionEntry* find_soversion_entry(const char* tag);
bool soversion_tags_unique();
rgpot_cxx_layout_stamp_t header_stamp();
std::uint64_t recorded_layout_hash();
bool platform_soversion_ok();
rgpot_cxx_layout_stamp_t library_stamp();
bool layout_compatible();
std::string check_capabilities(::Capabilities::Reader caps, const Expectation& want = {});
void fill_compatibility(::Capabilities::Builder caps);
std::string check_server(::Potential::Client& server, kj::WaitScope& wait_scope, const Expectation& want = {});
 
} // namespace abi

Detailed Documentation

Global Variables

std::uint32_t kCxxLayoutRevision = 1

Hand-maintained. Increment when a change the hash cannot see alters the C++ ABI: reordering virtuals without changing their count, changing the meaning of a field, changing a base class of a covered type. Any change to size, alignment or a field offset moves the hash by itself.

std::uint32_t kCxxSoversion = 4

ELF soversion of librgpot (librgpot.so.N, librgpot.N.dylib). Meson and CMake read this constant. The SONAME is not the layout hash. The hash depends on the platform tag and includes the cache feature bit, so builds of one revision do not share a hash. Bump this when a recorded hash in kCxxSoversionTable changes, and replace that table from the CI stamp lines in the same edit. check_cxx_soversion.py fails when the fingerprint of the stamp inputs changes and this number did not increase.

This is not RGPOT_ABI_LAYOUT_REVISION. The C ABI stamp in rgpot.h stayed at major 1, minor 0, layout revision 1: no exported C struct changed layout. The C API is exported from librgpot, so it has no shared library of its own and rides this SONAME. librgpot_mpi stays at soversion 3 (RGPOT_MPI_ABI_VERSION 1, unchanged).

std::array<CxxSoversionEntry, 5> kCxxSoversionTable {{     {“linux-x86_64-libstdc++-lp64”, 0x80bc8962b7808d7aull},     {“linux-aarch64-libstdc++-lp64”, 0x191f6a916fe32962ull},     {“macos-aarch64-libc++-lp64”, 0x293e0e103e91a552ull},     {“macos-x86_64-libc++-lp64”, 0x293e0e103e91a552ull},     {“windows-x86_64-msvc-llp64”, 0x395cb18f0d402142ull}, }}

No-cache header_stamp().hash for each platform ABI CI builds. Rows are copied from RGPOT_CXX_LAYOUT_STAMP lines. An unlisted platform still compiles. How to update the table: docs/orgmode/reference/c_abi.org.

char kCxxPlatformTag[] = “unknown” “-” “unknown” “-” “unknown” “-”   “ilp32”

This translation unit’s platform tag (os-arch-stdlib-datamodel).

std::uint32_t kPotentialBaseVirtuals = 5

Virtual functions declared by PotentialBase, destructor included. The cache hook set_cache adds one when RGPOT_HAS_CACHE is defined. A test counts the virtual declarations in Potential.hpp and fails when this and the header disagree.

std::uint32_t kPotentialVirtuals = 2

Virtual functions Potential<Derived> declares itself (forceImpl and forceBatchImpl).

Global Functions

void checked_load(ProfileLoader& loader, const std::string& prefix, const std::string& explicit_path = “”, const Expectation& want = {})

Load a profile backend and refuse it before dispatch when its Capabilities are incompatible. On refusal the loader is left unloaded and std::runtime_error names the first mismatch.

rgpot_cxx_layout_stamp_t header_stamp()

What the consumer compiled against. Initialise a constexpr variable with it; a call evaluated at run time is not tied to this translation unit (see layout_compatible()).

std::uint64_t recorded_layout_hash()

Recorded no-cache hash for this platform, or 0 when it has no row.

bool platform_soversion_ok()

True when this platform has no row, or the row matches header_stamp.

rgpot_cxx_layout_stamp_t library_stamp()

What the loaded library was built with.

bool layout_compatible()

True when the loaded library was built from the same layouts as these headers: equal revision, equal feature bits, equal hash.

std::string check_capabilities(::Capabilities::Reader caps, const Expectation& want = {})

Empty when caps is acceptable, else the first incompatibility.

void fill_compatibility(::Capabilities::Builder caps)

Fill the compatibility fields of caps with what this build speaks.

std::string check_server(::Potential::Client& server, kj::WaitScope& wait_scope, const Expectation& want = {})

Ask a connected server for its Capabilities and return empty when it is compatible, else the reason. A server built before Potential.getCapabilities existed answers UNIMPLEMENTED; that is reported as a missing call with the upgrade path, never as a successful handshake.