include/pops/runtime/dynamic/abi_key.hpp Source FileΒΆ

adc_cpp: include/pops/runtime/dynamic/abi_key.hpp Source File
adc_cpp 0.3.0
Model-free C++23 core for coupled hyperbolic-elliptic systems on adaptive (AMR) meshes, with MPI and GPU (Kokkos) backends
abi_key.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <pops/runtime/export.hpp> // POPS_EXPORT (default visibility across the hidden _pops module)
4
5#include <string>
6
40
41#ifndef POPS_HEADER_SIG
42#define POPS_HEADER_SIG "unknown"
43#endif
44
45// Indirection to stringify the value of a macro (not its name). Defined BEFORE the tokens that use
46// it (expansion happens at use, but keeping it readable does no harm).
47#define POPS_ABI_STR_(x) #x
48#define POPS_ABI_STR(x) POPS_ABI_STR_(x)
49
50// Kokkos token: evaluated PER UNIT (_pops module on one side, generated .so loader on the other).
51#ifdef POPS_HAS_KOKKOS
52#define POPS_ABI_KOKKOS "1"
53#else
54#define POPS_ABI_KOKKOS "0"
55#endif
56
57// stdlib token: identity + version of the linked standard library. _LIBCPP_VERSION /
58// __GLIBCXX__ are only defined after including a stdlib header (<string> above).
59#if defined(_LIBCPP_VERSION)
60#define POPS_ABI_STDLIB "libc++_" POPS_ABI_STR(_LIBCPP_VERSION)
61#elif defined(__GLIBCXX__)
62#define POPS_ABI_STDLIB "libstdc++_" POPS_ABI_STR(__GLIBCXX__)
63#else
64#define POPS_ABI_STDLIB "unknown"
65#endif
66
67// Compiler token: __VERSION__ (GCC/Clang/AppleClang) is already a string LITERAL; MSVC does NOT
68// define it -> stringify _MSC_FULL_VER. Keeps the key comparable cross-compiler (native Windows
69// port, ADC-99/100). POSIX unchanged (POPS_ABI_COMPILER == __VERSION__).
70#if defined(__VERSION__)
71#define POPS_ABI_COMPILER __VERSION__
72#elif defined(_MSC_FULL_VER)
73#define POPS_ABI_COMPILER "MSVC_" POPS_ABI_STR(_MSC_FULL_VER)
74#else
75#define POPS_ABI_COMPILER "unknown"
76#endif
77
78// ABI key of the current TRANSLATION UNIT, as a pure literal concatenated by the preprocessor:
79// "compiler=<__VERSION__>;std=<__cplusplus>;headers=<POPS_HEADER_SIG>;kokkos=<0|1>;stdlib=<...>".
80// All tokens are string literals (__VERSION__ and POPS_HEADER_SIG already are), so the key is frozen
81// in the .rodata of EACH TU at preprocessing -- NO function call.
82//
83// WHY a literal and not an inline function (real CI bug, ELF/Linux): a .so loader is loaded
84// RTLD_GLOBAL and an `inline` function (weak linkage, default visibility) that would build the key
85// would be INTERPOSED by the dynamic linker onto the copy in the already-loaded module -- the
86// loader would then return the key OF THE MODULE and the guard would compare the module key against
87// itself (tautology: ABI never rejected). Whether interposition happened depended on the compiler's
88// inlining threshold (the short function was inlined -> correct local key; lengthened by
89// kokkos=/stdlib=, gcc -O2 stopped inlining it -> interposition -> guard neutralized, caught by
90// test_amr_native_loader). A literal crosses no symbol: no interposition.
91// NB: the parsers (dsl._pops_cxx_std_from_module / module_header_signature) scan by token prefix
92// ("std=", "headers=") -> insensitive to ADDING tokens at the tail.
93#define POPS_ABI_KEY_LITERAL \
94 "compiler=" POPS_ABI_COMPILER ";std=" POPS_ABI_STR(__cplusplus) ";headers=" POPS_HEADER_SIG \
95 ";kokkos=" POPS_ABI_KOKKOS \
96 ";stdlib=" POPS_ABI_STDLIB
97
98namespace pops {
99namespace detail {
100
104inline std::string abi_key_string() {
106}
107
108} // namespace detail
109
113POPS_EXPORT std::string abi_key();
114
115} // namespace pops
#define POPS_ABI_KEY_LITERAL
Definition abi_key.hpp:93
POPS_EXPORT: force DEFAULT VISIBILITY on an out-of-line symbol, even when the unit is compiled with -...
#define POPS_EXPORT
Definition export.hpp:25
std::string abi_key_string()
ABI key of the current TU (cf.
Definition abi_key.hpp:104
Definition amr_hierarchy.hpp:29
POPS_EXPORT std::string abi_key()
ABI key of the module (TU system.cpp).