Skip to content

Commit 130c995

Browse files
authored
fix: support basic dual includes (#2804)
1 parent eb83fee commit 130c995

File tree

5 files changed

+32
-20
lines changed

5 files changed

+32
-20
lines changed

CMakeLists.txt

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,13 @@ if(NOT pybind11_FIND_QUIETLY)
4545
message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
4646
endif()
4747

48+
# Avoid infinite recursion if tests include this as a subdirectory
49+
if(DEFINED PYBIND11_MASTER_PROJECT)
50+
set(PYBIND11_TEST OFF)
51+
endif()
52+
4853
# Check if pybind11 is being used directly or via add_subdirectory
49-
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
54+
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR AND NOT DEFINED PYBIND11_MASTER_PROJECT)
5055
### Warn if not an out-of-source builds
5156
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
5257
set(lines
@@ -161,12 +166,24 @@ endif()
161166
# You can also place ifs *in* the Config.in, but not here.
162167

163168
# This section builds targets, but does *not* touch Python
164-
165-
# Build the headers-only target (no Python included):
166-
# (long name used here to keep this from clashing in subdirectory mode)
167-
add_library(pybind11_headers INTERFACE)
168-
add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target
169-
add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember
169+
# Non-IMPORT targets cannot be defined twice
170+
if(NOT TARGET pybind11_headers)
171+
# Build the headers-only target (no Python included):
172+
# (long name used here to keep this from clashing in subdirectory mode)
173+
add_library(pybind11_headers INTERFACE)
174+
add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target
175+
add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember
176+
177+
target_include_directories(
178+
pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
179+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
180+
181+
target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
182+
cxx_right_angle_brackets)
183+
else()
184+
# It is invalid to install a target twice, too.
185+
set(PYBIND11_INSTALL OFF)
186+
endif()
170187

171188
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
172189

@@ -177,14 +194,6 @@ elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
177194
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
178195
endif()
179196

180-
# Fill in headers target
181-
target_include_directories(
182-
pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
183-
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
184-
185-
target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
186-
cxx_right_angle_brackets)
187-
188197
if(PYBIND11_INSTALL)
189198
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
190199
set(PYBIND11_CMAKECONFIG_INSTALL_DIR

tests/test_cmake_build/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function(pybind11_add_build_test name)
2525
endif()
2626

2727
if(NOT ARG_INSTALL)
28-
list(APPEND build_options "-DPYBIND11_PROJECT_DIR=${pybind11_SOURCE_DIR}")
28+
list(APPEND build_options "-Dpybind11_SOURCE_DIR=${pybind11_SOURCE_DIR}")
2929
else()
3030
list(APPEND build_options "-DCMAKE_PREFIX_PATH=${pybind11_BINARY_DIR}/mock_install")
3131
endif()
@@ -79,3 +79,6 @@ if(PYBIND11_INSTALL)
7979
endif()
8080

8181
add_dependencies(check test_cmake_build)
82+
83+
add_subdirectory(subdirectory_target EXCLUDE_FROM_ALL)
84+
add_subdirectory(subdirectory_embed EXCLUDE_FROM_ALL)

tests/test_cmake_build/subdirectory_embed/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ set(PYBIND11_INSTALL
1616
CACHE BOOL "")
1717
set(PYBIND11_EXPORT_NAME test_export)
1818

19-
add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11)
19+
add_subdirectory("${pybind11_SOURCE_DIR}" pybind11)
2020

2121
# Test basic target functionality
2222
add_executable(test_subdirectory_embed ../embed.cpp)
2323
target_link_libraries(test_subdirectory_embed PRIVATE pybind11::embed)
2424
set_target_properties(test_subdirectory_embed PROPERTIES OUTPUT_NAME test_cmake_build)
2525

2626
add_custom_target(check_subdirectory_embed $<TARGET_FILE:test_subdirectory_embed>
27-
${PROJECT_SOURCE_DIR}/../test.py)
27+
"${PROJECT_SOURCE_DIR}/../test.py")
2828

2929
# Test custom export group -- PYBIND11_EXPORT_NAME
3030
add_library(test_embed_lib ../embed.cpp)

tests/test_cmake_build/subdirectory_function/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ endif()
1111

1212
project(test_subdirectory_function CXX)
1313

14-
add_subdirectory("${PYBIND11_PROJECT_DIR}" pybind11)
14+
add_subdirectory("${pybind11_SOURCE_DIR}" pybind11)
1515
pybind11_add_module(test_subdirectory_function ../main.cpp)
1616
set_target_properties(test_subdirectory_function PROPERTIES OUTPUT_NAME test_cmake_build)
1717

tests/test_cmake_build/subdirectory_target/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ endif()
1111

1212
project(test_subdirectory_target CXX)
1313

14-
add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11)
14+
add_subdirectory("${pybind11_SOURCE_DIR}" pybind11)
1515

1616
add_library(test_subdirectory_target MODULE ../main.cpp)
1717
set_target_properties(test_subdirectory_target PROPERTIES OUTPUT_NAME test_cmake_build)

0 commit comments

Comments
 (0)