Skip to content

Commit

Permalink
Fix naming of ABI3 extension libraries on Windows
Browse files Browse the repository at this point in the history
This commit fixes the naming conventions of ABI3 builds on Windows. It
also adopts a recent CMake/FindPython interface whenever available.
  • Loading branch information
wjakob committed May 31, 2023
1 parent 0952f99 commit 4513c49
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 39 deletions.
12 changes: 4 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,11 @@ endif()
# ---------------------------------------------------------------------------

if (NOT TARGET Python::Module OR NOT TARGET Python::Interpreter)
set(Python_FIND_FRAMEWORK LAST) # Prefer Brew/Conda to Apple framework python
set(Python_FIND_FRAMEWORK LAST) # Prefer Brew/Conda to Apple framework python

if (WIN32 AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.26 AND Python_INTERPRETER_ID STREQUAL "Python")
# Windows stable ABI builds for CPython require Development.SABIModule provided by CMake>=3.26
find_package(Python 3.8 COMPONENTS Interpreter Development.Module Development.SABIModule REQUIRED)
else()
# The following suffices in all other cases
find_package(Python 3.8 COMPONENTS Interpreter Development REQUIRED)
endif()
find_package(Python 3.8
REQUIRED COMPONENTS Interpreter Development.Module
OPTIONAL_COMPONENTS Development.SABIModule)
endif()

# ---------------------------------------------------------------------------
Expand Down
76 changes: 45 additions & 31 deletions cmake/nanobind-config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,48 @@ if (NOT TARGET Python::Module)
message(FATAL_ERROR "You must invoke 'find_package(Python COMPONENTS Interpreter Development REQUIRED)' prior to including nanobind.")
endif()

# Determine the Python extension suffix and stash in the CMake cache
execute_process(
COMMAND "${Python_EXECUTABLE}" "-c"
"import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"
RESULT_VARIABLE NB_SUFFIX_RET
OUTPUT_VARIABLE NB_SUFFIX
OUTPUT_STRIP_TRAILING_WHITESPACE)

if (NB_SUFFIX_RET AND NOT NB_SUFFIX_RET EQUAL 0)
message(FATAL_ERROR "nanobind: Python sysconfig query to "
"find 'EXT_SUFFIX' property failed!")
# Determine the right suffix for ordinary and stable ABI extensions.
# Python_SOSABI is guaranteed to be available in CMake 3.26+, and it may
# also be available as part of backported FindPython in scikit-build-core
if (DEFINED Python_SOSABI)
if (WIN32)
set(NB_SUFFIX_EXT ".pyd")
else()
set(NB_SUFFIX_EXT "${CMAKE_SHARED_MODULE_SUFFIX}")
endif()

set(NB_SUFFIX ".${Python_SOABI}${NB_SUFFIX_EXT}")

if (Python_SOSABI STREQUAL "")
set(NB_SUFFIX_S "${NB_SUFFIX_EXT}")
else()
set(NB_SUFFIX_S ".${Python_SOSABI}${NB_SUFFIX_EXT}")
endif()
else()
# Query Python directly to get the right suffix
execute_process(
COMMAND "${Python_EXECUTABLE}" "-c"
"import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"
RESULT_VARIABLE NB_SUFFIX_RET
OUTPUT_VARIABLE NB_SUFFIX
OUTPUT_STRIP_TRAILING_WHITESPACE)

if (NB_SUFFIX_RET AND NOT NB_SUFFIX_RET EQUAL 0)
message(FATAL_ERROR "nanobind: Python sysconfig query to "
"find 'EXT_SUFFIX' property failed!")
endif()

get_filename_component(NB_SUFFIX_EXT "${NB_SUFFIX}" LAST_EXT)
if (WIN32)
set(NB_SUFFIX_S "${NB_SUFFIX_EXT}")
else()
set(NB_SUFFIX_S ".abi3${NB_SUFFIX_EXT}")
endif()
endif()

set(NB_SUFFIX ${NB_SUFFIX} CACHE INTERNAL "")
# Stash these for later use
set(NB_SUFFIX ${NB_SUFFIX} CACHE INTERNAL "")
set(NB_SUFFIX_S ${NB_SUFFIX_S} CACHE INTERNAL "")

get_filename_component(NB_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(NB_DIR "${NB_DIR}" PATH)
Expand Down Expand Up @@ -194,8 +222,7 @@ function(nanobind_extension name)
endfunction()

function(nanobind_extension_abi3 name)
get_filename_component(ext "${NB_SUFFIX}" LAST_EXT)
set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX ".abi3${ext}")
set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${NB_SUFFIX_S}")
endfunction()

function (nanobind_lto name)
Expand Down Expand Up @@ -238,23 +265,10 @@ function(nanobind_add_module name)
set(ARG_NB_STATIC TRUE)
endif()

# Stable ABI interface requires Python >= 3.12
if (ARG_STABLE_ABI AND (Python_VERSION_MAJOR EQUAL 3) AND (Python_VERSION_MINOR LESS 12))
set(ARG_STABLE_ABI OFF)
endif()

# Stable API interface requires CPython (PyPy isn't supported)
if (ARG_STABLE_ABI AND NOT (Python_INTERPRETER_ID STREQUAL "Python"))
set(ARG_STABLE_ABI OFF)
endif()

# On Windows, use of the stable ABI requires a very recent CMake version
if (ARG_STABLE_API AND WIN32 AND NOT TARGET Python::SABIModule)
if (CMAKE_VERSION VERSION_LESS 3.26)
message(WARNING "To build stable ABI packages on Windows, you must use CMake version 3.26 or newer!")
else()
message(WARNING "To build stable ABI packages on Windows, you must invoke 'find_package(Python COMPONENTS Interpreter Development.Module Development.SABIModule REQUIRED)' prior to including nanobind.")
endif()
# Stable ABI builds require CPython >= 3.12 and Python::SABIModule
if ((Python_VERSION VERSION_LESS 3.12) OR
(NOT Python_INTERPRETER_ID STREQUAL "Python") OR
(NOT TARGET Python::SABIModule))
set(ARG_STABLE_ABI OFF)
endif()

Expand Down
6 changes: 6 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ case, both modules must use the same nanobind ABI version, or they will be
isolated from each other. Releases that don't explicitly mention an ABI version
below inherit that of the preceding release.

Version 1.3.1 (TBA)
-------------------

* CMake build system improvements for stable ABI wheel generation.
(PR `#222 <https://github.com/wjakob/nanobind/pull/222>`__).

Version 1.3.0 (May 31, 2023)
----------------------------

Expand Down

0 comments on commit 4513c49

Please sign in to comment.