Skip to content

Commit

Permalink
pybind11 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
wjakob committed Jan 7, 2025
1 parent cdf3671 commit 15286b2
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 96 deletions.
102 changes: 102 additions & 0 deletions src/nb_abi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
src/nb_abi.h: this file computes tags that are used to isolate extensions
from each other in the case of platform or nanobind-related ABI
incompatibilities. The file is included by ``nb_internals.cpp`` and should
not be used directly.
The implementation of this file (specifically, the NB_PLATFORM_ABI_TAG) is
designed to be compatible with @rwgk's
https://github.com/pybind/pybind11/blob/master/include/pybind11/conduit/pybind11_platform_abi_id.h
Use of this source code is governed by a BSD-style license that can be found
in the LICENSE file.
*/

/// Tracks the version of nanobind's internal data structures
#ifndef NB_INTERNALS_VERSION
# define NB_INTERNALS_VERSION 16
#endif

#if defined(__MINGW32__)
# define NB_COMPILER_TYPE "mingw"
#elif defined(__CYGWIN__)
# define NB_COMPILER_TYPE "gcc_cygwin"
#elif defined(_MSC_VER)
# define NB_COMPILER_TYPE "msvc"
#elif defined(__clang__) || defined(__GNUC__)
# define NB_COMPILER_TYPE "system" // Assumed compatible with system compiler.
#else
# error "Unknown compiler type. Please revise this code."
#endif

// Catch other conditions that imply ABI incompatibility
// - MSVC builds with different CRT versions
// - An anticipated MSVC ABI break ("vNext")
// - Builds using libc++ with unstable ABIs
// - Builds using libstdc++ with the legacy (pre-C++11) ABI, etc.
#if defined(_MSC_VER)
# if defined(_MT) && defined(_DLL) // Corresponding to CL command line options /MD or /MDd.
# if (_MSC_VER) / 100 == 19
# define NB_BUILD_ABI "_md_mscver19"
# else
# error "Unknown MSVC major version. Please revise this code."
# endif
# elif defined(_MT) // Corresponding to CL command line options /MT or /MTd.
# define NB_BUILD_ABI "_mt_mscver" NB_TOSTRING(_MSC_VER)
# else
# if (_MSC_VER) / 100 == 19
# define NB_BUILD_ABI "_none_mscver19"
# else
# error "Unknown MSVC major version. Please revise this code."
# endif
# endif
#elif defined(_LIBCPP_ABI_VERSION) // https://libcxx.llvm.org/DesignDocs/ABIVersioning.html
# define NB_BUILD_ABI "_libcpp_abi" NB_TOSTRING(_LIBCPP_ABI_VERSION)
#elif defined(_GLIBCXX_USE_CXX11_ABI)
# if defined(__NVCOMPILER) && !defined(__GXX_ABI_VERSION)
# error "Unknown platform or compiler (_GLIBCXX_USE_CXX11_ABI). Please revise this code."
# endif
# if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION < 1002 || __GXX_ABI_VERSION >= 2000
# error "Unknown platform or compiler (__GXX_ABI_VERSION). Please revise this code."
# endif
# define NB_BUILD_ABI "_libstdcpp_gxx_abi_1xxx_use_cxx11_abi_" NB_TOSTRING(_GLIBCXX_USE_CXX11_ABI)
#else
# error "Unknown platform or compiler. Please revise this code."
#endif

// On MSVC, debug and release builds are not ABI-compatible!
#if defined(_MSC_VER) && defined(_DEBUG)
# define NB_BUILD_TYPE "_debug"
#else
# define NB_BUILD_TYPE ""
#endif

// Tag to determine if inter-library C++ function can be safely dispatched
#define NB_PLATFORM_ABI_TAG \
NB_COMPILER_TYPE NB_BUILD_ABI NB_BUILD_TYPE

// Can have limited and non-limited-API extensions in the same process.
// Nanobind data structures will differ, so these can't talk to each other
#if defined(Py_LIMITED_API)
# define NB_STABLE_ABI "_stable"
#else
# define NB_STABLE_ABI ""
#endif

// As above, but for free-threaded extensions
#if defined(NB_FREE_THREADED)
# define NB_FREE_THREADED_ABI "_ft"
#else
# define NB_FREE_THREADED_ABI ""
#endif

#if NB_VERSION_DEV > 0
#define NB_VERSION_DEV_STR "_dev" NB_TOSTRING(NB_VERSION_DEV)
#else
#define NB_VERSION_DEV_STR ""
#endif

#define NB_ABI_TAG \
"v" NB_TOSTRING(NB_INTERNALS_VERSION) \
NB_VERSION_DEV_STR NB_PLATFORM_ABI_TAG NB_STABLE_ABI \
NB_FREE_THREADED_ABI
97 changes: 1 addition & 96 deletions src/nb_internals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,108 +10,13 @@
#include <nanobind/nanobind.h>
#include <structmember.h>
#include "nb_internals.h"
#include "nb_abi.h"
#include <thread>

#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif

/// Tracks the ABI of nanobind
#ifndef NB_INTERNALS_VERSION
# define NB_INTERNALS_VERSION 16
#endif

/// On MSVC, debug and release builds are not ABI-compatible!
#if defined(_MSC_VER) && defined(_DEBUG)
# define NB_BUILD_TYPE "_debug"
#else
# define NB_BUILD_TYPE ""
#endif

/// Let's assume that different compilers are ABI-incompatible.
#if defined(_MSC_VER)
# define NB_COMPILER_TYPE "_msvc"
#elif defined(__INTEL_COMPILER)
# define NB_COMPILER_TYPE "_icc"
#elif defined(__clang__)
# define NB_COMPILER_TYPE "_clang"
#elif defined(__PGI)
# define NB_COMPILER_TYPE "_pgi"
#elif defined(__MINGW32__)
# define NB_COMPILER_TYPE "_mingw"
#elif defined(__CYGWIN__)
# define NB_COMPILER_TYPE "_gcc_cygwin"
#elif defined(__GNUC__)
# define NB_COMPILER_TYPE "_gcc"
#else
# define NB_COMPILER_TYPE "_unknown"
#endif

/// Also standard libs
#if defined(_LIBCPP_VERSION)
# define NB_STDLIB "_libc++"
#elif defined(__GLIBCXX__)
# define NB_STDLIB "_libstdc++"
#else
# define NB_STDLIB ""
#endif

// Catch other conditions that imply ABI incompatibility
// - MSVC builds with different CRT versions
// - An anticipated MSVC ABI break ("vNext")
// - Builds using libc++ with unstable ABIs
// - Builds using libstdc++ with the legacy (pre-C++11) ABI
#if defined(_MSC_VER)
# if defined(_MT) && defined(_DLL) // catches /MD or /MDd
# define NB_BUILD_LIB "_md"
# elif defined(_MT)
# define NB_BUILD_LIB "_mt" // catches /MT or /MTd
# else
# define NB_BUILD_LIB ""
# endif
# if (_MSC_VER) / 100 == 19
# define NB_BUILD_ABI NB_BUILD_LIB "_19"
# else
# define NB_BUILD_ABI NB_BUILD_LIB "_unknown"
# endif
#elif defined(_LIBCPP_ABI_VERSION)
# define NB_BUILD_ABI "_abi" NB_TOSTRING(_LIBCPP_ABI_VERSION)
#elif defined(__GLIBCXX__)
# if _GLIBCXX_USE_CXX11_ABI
# define NB_BUILD_ABI ""
# else
# define NB_BUILD_ABI "_legacy"
# endif
#else
# define NB_BUILD_ABI ""
#endif

// Can have limited and non-limited-API extensions in the same process.
// Nanobind data structures will differ, so these can't talk to each other
#if defined(Py_LIMITED_API)
# define NB_STABLE_ABI "_stable"
#else
# define NB_STABLE_ABI ""
#endif

// As above, but for free-threaded extensions
#if defined(NB_FREE_THREADED)
# define NB_FREE_THREADED_ABI "_ft"
#else
# define NB_FREE_THREADED_ABI ""
#endif

#if NB_VERSION_DEV > 0
#define NB_VERSION_DEV_STR "_dev" NB_TOSTRING(NB_VERSION_DEV)
#else
#define NB_VERSION_DEV_STR ""
#endif

#define NB_ABI_TAG \
"v" NB_TOSTRING(NB_INTERNALS_VERSION) \
NB_VERSION_DEV_STR NB_COMPILER_TYPE NB_STDLIB NB_BUILD_ABI \
NB_BUILD_TYPE NB_STABLE_ABI NB_FREE_THREADED_ABI

NAMESPACE_BEGIN(NB_NAMESPACE)
NAMESPACE_BEGIN(detail)

Expand Down

0 comments on commit 15286b2

Please sign in to comment.