Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ endif()
# Options
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
option(PYBIND11_USE_SYSTEM_HEADERS
"Mark pybind11 headers as system headers in add_subdirectory mode" ON)
option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
option(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
"To enforce that a handle_type_name<> specialization exists" OFF)
Expand Down Expand Up @@ -293,6 +295,8 @@ if(NOT TARGET pybind11_headers)
target_include_directories(
pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
set_property(TARGET pybind11_headers PROPERTY PYBIND11_USE_SYSTEM_HEADERS
"${PYBIND11_USE_SYSTEM_HEADERS}")

target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
cxx_right_angle_brackets)
Expand Down
6 changes: 6 additions & 0 deletions docs/compiling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,12 @@ You can also use the targets (as listed below) with FindPython. If you define
(mostly useful when building pybind11's own tests, or as a way to change search
algorithms from the CMake invocation, with ``-DPYBIND11_FINDPYTHON=ON``.

When adding pybind11 as a subdirectory, its headers are marked as system headers
by default. If a parent project globally adds a prefix containing another
pybind11 installation, add ``set(PYBIND11_USE_SYSTEM_HEADERS OFF)`` before
``add_subdirectory(pybind11)``. ``pybind11_add_module()`` then prioritizes the
subdirectory's headers over the parent include path.

.. warning::

If you use FindPython to multi-target Python versions, use the individual
Expand Down
1 change: 1 addition & 0 deletions tests/test_cmake_build/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ endif()
possibly_uninitialized(PYTHON_MODULE_EXTENSION Python_INTERPRETER_ID)

pybind11_add_build_test(subdirectory_function)
pybind11_add_build_test(subdirectory_system_headers)
pybind11_add_build_test(subdirectory_target)
if("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy"
OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy"
Expand Down
2 changes: 2 additions & 0 deletions tests/test_cmake_build/fake_system/pybind11/pybind11.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#error \
"The globally installed pybind11 headers were selected before the add_subdirectory source tree."
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.15...4.2)

project(test_subdirectory_system_headers CXX)

# Model an older pybind11 copy installed in a global include prefix by a parent project.
include_directories("${CMAKE_CURRENT_LIST_DIR}/../fake_system")

set(PYBIND11_USE_SYSTEM_HEADERS OFF)

# Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
# (makes transition easier while we support both modes).
if(DEFINED PYTHON_EXECUTABLE AND NOT DEFINED Python_EXECUTABLE)
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
endif()

add_subdirectory("${pybind11_SOURCE_DIR}" pybind11)
pybind11_add_module(test_subdirectory_system_headers NO_EXTRAS ../main.cpp)
set_target_properties(test_subdirectory_system_headers PROPERTIES OUTPUT_NAME test_cmake_build)

if(DEFINED Python_EXECUTABLE)
set(_Python_EXECUTABLE "${Python_EXECUTABLE}")
elseif(DEFINED PYTHON_EXECUTABLE)
set(_Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
else()
message(FATAL_ERROR "No Python executable defined (should not be possible at this stage)")
endif()

add_custom_target(
check_subdirectory_system_headers
${CMAKE_COMMAND}
-E
env
PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_system_headers>
${_Python_EXECUTABLE}
${PROJECT_SOURCE_DIR}/../test.py
${PROJECT_NAME}
DEPENDS test_subdirectory_system_headers)
9 changes: 9 additions & 0 deletions tools/pybind11NewTools.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,15 @@ function(pybind11_add_module target_name)

target_link_libraries(${target_name} PRIVATE pybind11::headers)

get_property(
_pybind11_use_system_headers
TARGET pybind11_headers
PROPERTY PYBIND11_USE_SYSTEM_HEADERS)
if(NOT _pybind11_use_system_headers)
set_property(TARGET pybind11_headers PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "")
target_include_directories(${target_name} BEFORE PRIVATE "${pybind11_INCLUDE_DIR}")
endif()

if(lib_type STREQUAL "MODULE")
target_link_libraries(${target_name} PRIVATE pybind11::module)
else()
Expand Down
9 changes: 9 additions & 0 deletions tools/pybind11Tools.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ function(pybind11_add_module target_name)

target_link_libraries(${target_name} PRIVATE pybind11::module)

get_property(
_pybind11_use_system_headers
TARGET pybind11_headers
PROPERTY PYBIND11_USE_SYSTEM_HEADERS)
if(NOT _pybind11_use_system_headers)
set_property(TARGET pybind11_headers PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "")
target_include_directories(${target_name} BEFORE PRIVATE "${pybind11_INCLUDE_DIR}")
endif()

if(ARG_SYSTEM)
message(
STATUS
Expand Down
Loading