chore(cmake): carry option-driven defines on pybind11_headers INTERFACE (#6130)
* chore(cmake): carry option-driven defines on pybind11_headers INTERFACE
PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION and
PYBIND11_SIMPLE_GIL_MANAGEMENT were directory-scoped
add_compile_definitions, which only reached the master-project test
build. On the pybind11_headers INTERFACE (like
PYBIND11_INTERNALS_VERSION) they also apply in add_subdirectory mode
and in the exported/installed targets.
Assisted-by: ClaudeCode:claude-fable-5
* test(cmake): verify option-driven defines reach consumer targets
Extend subdirectory_target and installed_target to check that
PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION and
PYBIND11_SIMPLE_GIL_MANAGEMENT propagate through the pybind11_headers
usage requirements. Fails without the parent commit.
Assisted-by: ClaudeCode:claude-fable-5
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6f3f8be..65f794a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -109,13 +109,6 @@
endif()
option(PYBIND11_USE_CROSSCOMPILING "Respect CMAKE_CROSSCOMPILING" OFF)
-if(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
- add_compile_definitions(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
-endif()
-if(PYBIND11_SIMPLE_GIL_MANAGEMENT)
- add_compile_definitions(PYBIND11_SIMPLE_GIL_MANAGEMENT)
-endif()
-
cmake_dependent_option(
USE_PYTHON_INCLUDE_DIR
"Install pybind11 headers in Python include directory instead of default installation prefix"
@@ -307,6 +300,13 @@
target_compile_definitions(
pybind11_headers INTERFACE "PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}")
endif()
+ if(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
+ target_compile_definitions(pybind11_headers
+ INTERFACE PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
+ endif()
+ if(PYBIND11_SIMPLE_GIL_MANAGEMENT)
+ target_compile_definitions(pybind11_headers INTERFACE PYBIND11_SIMPLE_GIL_MANAGEMENT)
+ endif()
else()
# It is invalid to install a target twice, too.
set(PYBIND11_INSTALL OFF)
diff --git a/tests/test_cmake_build/CMakeLists.txt b/tests/test_cmake_build/CMakeLists.txt
index ce63a69..a4d2544 100644
--- a/tests/test_cmake_build/CMakeLists.txt
+++ b/tests/test_cmake_build/CMakeLists.txt
@@ -20,6 +20,15 @@
list(APPEND build_options "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
endif()
+ # Forward option-driven defines so the nested projects can verify they propagate
+ # through the pybind11_headers usage requirements.
+ foreach(opt IN ITEMS PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
+ PYBIND11_SIMPLE_GIL_MANAGEMENT)
+ if(${opt})
+ list(APPEND build_options "-D${opt}=ON")
+ endif()
+ endforeach()
+
if(NOT ARG_INSTALL)
list(APPEND build_options "-Dpybind11_SOURCE_DIR=${pybind11_SOURCE_DIR}")
else()
diff --git a/tests/test_cmake_build/installed_target/CMakeLists.txt b/tests/test_cmake_build/installed_target/CMakeLists.txt
index 6ee0169..a66f8ad 100644
--- a/tests/test_cmake_build/installed_target/CMakeLists.txt
+++ b/tests/test_cmake_build/installed_target/CMakeLists.txt
@@ -8,6 +8,15 @@
add_library(test_installed_target MODULE ../main.cpp)
target_link_libraries(test_installed_target PRIVATE pybind11::module)
+
+# If a pybind11 option is on, main.cpp checks that the matching macro reached this
+# consumer target via the installed pybind11_headers usage requirements.
+foreach(opt IN ITEMS PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
+ PYBIND11_SIMPLE_GIL_MANAGEMENT)
+ if(${opt})
+ target_compile_definitions(test_installed_target PRIVATE "EXPECT_${opt}")
+ endif()
+endforeach()
set_target_properties(test_installed_target PROPERTIES OUTPUT_NAME test_cmake_build)
# Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib
diff --git a/tests/test_cmake_build/main.cpp b/tests/test_cmake_build/main.cpp
index 640449c..adbaace 100644
--- a/tests/test_cmake_build/main.cpp
+++ b/tests/test_cmake_build/main.cpp
@@ -1,4 +1,16 @@
#include <pybind11/pybind11.h>
+
+#ifdef EXPECT_PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
+# ifndef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
+# error "PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION did not propagate"
+# endif
+#endif
+#ifdef EXPECT_PYBIND11_SIMPLE_GIL_MANAGEMENT
+# ifndef PYBIND11_SIMPLE_GIL_MANAGEMENT
+# error "PYBIND11_SIMPLE_GIL_MANAGEMENT did not propagate"
+# endif
+#endif
+
namespace py = pybind11;
PYBIND11_MODULE(test_cmake_build, m, py::mod_gil_not_used()) {
diff --git a/tests/test_cmake_build/subdirectory_target/CMakeLists.txt b/tests/test_cmake_build/subdirectory_target/CMakeLists.txt
index 88d73f6..29b0234 100644
--- a/tests/test_cmake_build/subdirectory_target/CMakeLists.txt
+++ b/tests/test_cmake_build/subdirectory_target/CMakeLists.txt
@@ -15,6 +15,15 @@
target_link_libraries(test_subdirectory_target PRIVATE pybind11::module)
+# If a pybind11 option is on, main.cpp checks that the matching macro reached this
+# consumer target via the pybind11_headers usage requirements.
+foreach(opt IN ITEMS PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
+ PYBIND11_SIMPLE_GIL_MANAGEMENT)
+ if(${opt})
+ target_compile_definitions(test_subdirectory_target PRIVATE "EXPECT_${opt}")
+ endif()
+endforeach()
+
# Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib
pybind11_extension(test_subdirectory_target)