|
18 | 18 |
|
19 | 19 | /// Tracks the ABI of nanobind
|
20 | 20 | #ifndef NB_INTERNALS_VERSION
|
21 |
| -# define NB_INTERNALS_VERSION 15 |
| 21 | +# define NB_INTERNALS_VERSION 16 |
22 | 22 | #endif
|
23 | 23 |
|
24 | 24 | /// On MSVC, debug and release builds are not ABI-compatible!
|
|
49 | 49 |
|
50 | 50 | /// Also standard libs
|
51 | 51 | #if defined(_LIBCPP_VERSION)
|
52 |
| -# define NB_STDLIB "_libcpp" |
53 |
| -#elif defined(__GLIBCXX__) || defined(__GLIBCPP__) |
54 |
| -# define NB_STDLIB "_libstdcpp" |
| 52 | +# define NB_STDLIB "_libc++" |
| 53 | +#elif defined(__GLIBCXX__) |
| 54 | +# define NB_STDLIB "_libstdc++" |
55 | 55 | #else
|
56 | 56 | # define NB_STDLIB ""
|
57 | 57 | #endif
|
58 | 58 |
|
59 |
| -/// On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility. |
60 |
| -/// Also keep potentially ABI-incompatible visual studio builds apart. |
61 |
| -#if defined(__GXX_ABI_VERSION) |
62 |
| -# define NB_BUILD_ABI "_cxxabi" NB_TOSTRING(__GXX_ABI_VERSION) |
63 |
| -#elif defined(_MSC_VER) |
64 |
| -# define NB_BUILD_ABI "_mscver" NB_TOSTRING(_MSC_VER) |
| 59 | +// Catch other conditions that imply ABI incompatibility |
| 60 | +// - MSVC builds with different CRT versions |
| 61 | +// - An anticipated MSVC ABI break ("vNext") |
| 62 | +// - Builds using libc++ with unstable ABIs |
| 63 | +// - Builds using libstdc++ with the legacy (pre-C++11) ABI |
| 64 | +#if defined(_MSC_VER) |
| 65 | +# if defined(_MT) && defined(_DLL) // catches /MD or /MDd |
| 66 | +# define NB_BUILD_LIB "_md" |
| 67 | +# elif defined(_MT) |
| 68 | +# define NB_BUILD_LIB "_mt" // catches /MT or /MTd |
| 69 | +# else |
| 70 | +# define NB_BUILD_LIB "" |
| 71 | +# endif |
| 72 | +# if (_MSC_VER) / 100 == 19 |
| 73 | +# define NB_BUILD_ABI NB_BUILD_LIB "_19" |
| 74 | +# else |
| 75 | +# define NB_BUILD_ABI NB_BUILD_LIB "_unknown" |
| 76 | +# endif |
| 77 | +#elif defined(_LIBCPP_ABI_VERSION) |
| 78 | +# define NB_BUILD_ABI "_abi" NB_TOSTRING(_LIBCPP_ABI_VERSION) |
| 79 | +#elif defined(__GLIBCXX__) |
| 80 | +# if _GLIBCXX_USE_CXX11_ABI |
| 81 | +# define NB_BUILD_ABI "" |
| 82 | +# else |
| 83 | +# define NB_BUILD_ABI "_legacy" |
| 84 | +# endif |
65 | 85 | #else
|
66 | 86 | # define NB_BUILD_ABI ""
|
67 | 87 | #endif
|
68 | 88 |
|
69 |
| -// Can have limited and non-limited-API extensions in the same process, and they might be incompatible |
| 89 | +// Can have limited and non-limited-API extensions in the same process. |
| 90 | +// Nanobind data structures will differ, so these can't talk to each other |
70 | 91 | #if defined(Py_LIMITED_API)
|
71 | 92 | # define NB_STABLE_ABI "_stable"
|
72 | 93 | #else
|
73 | 94 | # define NB_STABLE_ABI ""
|
74 | 95 | #endif
|
75 | 96 |
|
| 97 | +// As above, but for free-threaded extensions |
76 | 98 | #if defined(NB_FREE_THREADED)
|
77 | 99 | # define NB_FREE_THREADED_ABI "_ft"
|
78 | 100 | #else
|
|
85 | 107 | #define NB_VERSION_DEV_STR ""
|
86 | 108 | #endif
|
87 | 109 |
|
88 |
| -#define NB_INTERNALS_ID \ |
| 110 | +#define NB_ABI_TAG \ |
89 | 111 | "v" NB_TOSTRING(NB_INTERNALS_VERSION) \
|
90 | 112 | NB_VERSION_DEV_STR NB_COMPILER_TYPE NB_STDLIB NB_BUILD_ABI \
|
91 | 113 | NB_BUILD_TYPE NB_STABLE_ABI NB_FREE_THREADED_ABI
|
@@ -241,6 +263,8 @@ static bool is_alive_value = false;
|
241 | 263 | static bool *is_alive_ptr = &is_alive_value;
|
242 | 264 | bool is_alive() noexcept { return *is_alive_ptr; }
|
243 | 265 |
|
| 266 | +const char *abi_tag() { return NB_ABI_TAG; } |
| 267 | + |
244 | 268 | static void internals_cleanup() {
|
245 | 269 | nb_internals *p = internals;
|
246 | 270 | if (!p)
|
@@ -382,7 +406,7 @@ NB_NOINLINE void init(const char *name) {
|
382 | 406 | check(dict, "nanobind::detail::init(): could not access internals dictionary!");
|
383 | 407 |
|
384 | 408 | PyObject *key = PyUnicode_FromFormat("__nb_internals_%s_%s__",
|
385 |
| - NB_INTERNALS_ID, name ? name : ""); |
| 409 | + abi_tag(), name ? name : ""); |
386 | 410 | check(key, "nanobind::detail::init(): could not create dictionary key!");
|
387 | 411 |
|
388 | 412 | PyObject *capsule = dict_get_item_ref_or_fail(dict, key);
|
|
0 commit comments