mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
Add CMake target for embedding the Python interpreter
All targets provided by pybind11: * pybind11::module - the existing target for creating extension modules * pybind11::embed - new target for embedding the interpreter * pybind11::pybind11 - common "base" target (headers only)
This commit is contained in:
parent
46dbee7d42
commit
7f5c85c861
@ -84,18 +84,25 @@ endif()
|
|||||||
|
|
||||||
if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) # CMake >= 3.0
|
if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) # CMake >= 3.0
|
||||||
# Build an interface library target:
|
# Build an interface library target:
|
||||||
|
add_library(pybind11 INTERFACE)
|
||||||
|
add_library(pybind11::pybind11 ALIAS pybind11) # to match exported target
|
||||||
|
target_include_directories(pybind11 INTERFACE $<BUILD_INTERFACE:${PYBIND11_INCLUDE_DIR}>
|
||||||
|
$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||||
|
target_compile_options(pybind11 INTERFACE $<BUILD_INTERFACE:${PYBIND11_CPP_STANDARD}>)
|
||||||
|
|
||||||
add_library(module INTERFACE)
|
add_library(module INTERFACE)
|
||||||
target_include_directories(module INTERFACE $<BUILD_INTERFACE:${PYBIND11_INCLUDE_DIR}>
|
add_library(pybind11::module ALIAS module)
|
||||||
$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>
|
target_link_libraries(module INTERFACE pybind11::pybind11)
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
|
||||||
if(WIN32 OR CYGWIN)
|
if(WIN32 OR CYGWIN)
|
||||||
target_link_libraries(module INTERFACE $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
|
target_link_libraries(module INTERFACE $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
target_link_libraries(module INTERFACE "-undefined dynamic_lookup")
|
target_link_libraries(module INTERFACE "-undefined dynamic_lookup")
|
||||||
endif()
|
endif()
|
||||||
target_compile_options(module INTERFACE $<BUILD_INTERFACE:${PYBIND11_CPP_STANDARD}>)
|
|
||||||
|
|
||||||
add_library(pybind11::module ALIAS module) # to match exported target
|
add_library(embed INTERFACE)
|
||||||
|
add_library(pybind11::embed ALIAS embed)
|
||||||
|
target_link_libraries(embed INTERFACE pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (PYBIND11_INSTALL)
|
if (PYBIND11_INSTALL)
|
||||||
@ -122,7 +129,7 @@ if (PYBIND11_INSTALL)
|
|||||||
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
||||||
|
|
||||||
if(NOT (CMAKE_VERSION VERSION_LESS 3.0))
|
if(NOT (CMAKE_VERSION VERSION_LESS 3.0))
|
||||||
install(TARGETS module
|
install(TARGETS pybind11 module embed
|
||||||
EXPORT "${PROJECT_NAME}Targets")
|
EXPORT "${PROJECT_NAME}Targets")
|
||||||
install(EXPORT "${PROJECT_NAME}Targets"
|
install(EXPORT "${PROJECT_NAME}Targets"
|
||||||
NAMESPACE "${PROJECT_NAME}::"
|
NAMESPACE "${PROJECT_NAME}::"
|
||||||
|
@ -233,6 +233,9 @@ if(NOT CMAKE_VERSION VERSION_LESS 3.1)
|
|||||||
|
|
||||||
pybind11_add_build_test(subdirectory_function)
|
pybind11_add_build_test(subdirectory_function)
|
||||||
pybind11_add_build_test(subdirectory_target)
|
pybind11_add_build_test(subdirectory_target)
|
||||||
|
if(NOT ${PYTHON_MODULE_EXTENSION} MATCHES "pypy")
|
||||||
|
pybind11_add_build_test(subdirectory_embed)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(PYBIND11_INSTALL)
|
if(PYBIND11_INSTALL)
|
||||||
add_custom_target(mock_install ${CMAKE_COMMAND}
|
add_custom_target(mock_install ${CMAKE_COMMAND}
|
||||||
@ -242,6 +245,9 @@ if(NOT CMAKE_VERSION VERSION_LESS 3.1)
|
|||||||
|
|
||||||
pybind11_add_build_test(installed_function INSTALL)
|
pybind11_add_build_test(installed_function INSTALL)
|
||||||
pybind11_add_build_test(installed_target INSTALL)
|
pybind11_add_build_test(installed_target INSTALL)
|
||||||
|
if(NOT ${PYTHON_MODULE_EXTENSION} MATCHES "pypy")
|
||||||
|
pybind11_add_build_test(installed_embed INSTALL)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
30
tests/test_cmake_build/embed.cpp
Normal file
30
tests/test_cmake_build/embed.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include <pybind11/pybind11.h>
|
||||||
|
#include <pybind11/eval.h>
|
||||||
|
namespace py = pybind11;
|
||||||
|
|
||||||
|
PyObject *make_module() {
|
||||||
|
py::module m("test_cmake_build");
|
||||||
|
|
||||||
|
m.def("add", [](int i, int j) { return i + j; });
|
||||||
|
|
||||||
|
return m.ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc != 2)
|
||||||
|
throw std::runtime_error("Expected test.py file as the first argument");
|
||||||
|
auto test_py_file = argv[1];
|
||||||
|
|
||||||
|
PyImport_AppendInittab("test_cmake_build", &make_module);
|
||||||
|
Py_Initialize();
|
||||||
|
{
|
||||||
|
auto m = py::module::import("test_cmake_build");
|
||||||
|
if (m.attr("add")(1, 2).cast<int>() != 3)
|
||||||
|
throw std::runtime_error("embed.cpp failed");
|
||||||
|
|
||||||
|
auto globals = py::module::import("__main__").attr("__dict__");
|
||||||
|
py::module::import("sys").attr("argv") = py::make_tuple("test.py", "embed.cpp");
|
||||||
|
py::eval_file(test_py_file, globals);
|
||||||
|
}
|
||||||
|
Py_Finalize();
|
||||||
|
}
|
15
tests/test_cmake_build/installed_embed/CMakeLists.txt
Normal file
15
tests/test_cmake_build/installed_embed/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
project(test_installed_embed CXX)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH "")
|
||||||
|
find_package(pybind11 CONFIG REQUIRED)
|
||||||
|
message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
add_executable(test_cmake_build ../embed.cpp)
|
||||||
|
target_link_libraries(test_cmake_build PRIVATE pybind11::embed)
|
||||||
|
|
||||||
|
# Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::embed).
|
||||||
|
# This may be needed to resolve header conflicts, e.g. between Python release and debug headers.
|
||||||
|
set_target_properties(test_cmake_build PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)
|
||||||
|
|
||||||
|
add_custom_target(check $<TARGET_FILE:test_cmake_build> ${PROJECT_SOURCE_DIR}/../test.py)
|
9
tests/test_cmake_build/subdirectory_embed/CMakeLists.txt
Normal file
9
tests/test_cmake_build/subdirectory_embed/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
project(test_subdirectory_embed CXX)
|
||||||
|
|
||||||
|
add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11)
|
||||||
|
|
||||||
|
add_executable(test_cmake_build ../embed.cpp)
|
||||||
|
target_link_libraries(test_cmake_build PRIVATE pybind11::embed)
|
||||||
|
|
||||||
|
add_custom_target(check $<TARGET_FILE:test_cmake_build> ${PROJECT_SOURCE_DIR}/../test.py)
|
@ -21,18 +21,27 @@
|
|||||||
# Exported targets::
|
# Exported targets::
|
||||||
#
|
#
|
||||||
# If pybind11 is found, this module defines the following :prop_tgt:`IMPORTED`
|
# If pybind11 is found, this module defines the following :prop_tgt:`IMPORTED`
|
||||||
# target. Python headers, libraries (as needed by platform), and C++ standard
|
# interface library targets::
|
||||||
|
#
|
||||||
|
# pybind11::module - for extension modules
|
||||||
|
# pybind11::embed - for embedding the Python interpreter
|
||||||
|
#
|
||||||
|
# Python headers, libraries (as needed by platform), and the C++ standard
|
||||||
# are attached to the target. Set PythonLibsNew variables to influence
|
# are attached to the target. Set PythonLibsNew variables to influence
|
||||||
# python detection and PYBIND11_CPP_STANDARD (-std=c++11 or -std=c++14) to
|
# python detection and PYBIND11_CPP_STANDARD (-std=c++11 or -std=c++14) to
|
||||||
# influence standard setting. ::
|
# influence standard setting. ::
|
||||||
#
|
#
|
||||||
# pybind11::module - the main pybind11 interface library for extension modules (i.e., headers)
|
|
||||||
#
|
|
||||||
# find_package(pybind11 CONFIG REQUIRED)
|
# find_package(pybind11 CONFIG REQUIRED)
|
||||||
# message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIR} (found version ${pybind11_VERSION} & Py${PYTHON_VERSION_STRING})")
|
# message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}")
|
||||||
|
#
|
||||||
|
# # Create an extension module
|
||||||
# add_library(mylib MODULE main.cpp)
|
# add_library(mylib MODULE main.cpp)
|
||||||
# target_link_libraries(mylib pybind11::module)
|
# target_link_libraries(mylib pybind11::module)
|
||||||
#
|
#
|
||||||
|
# # Or embed the Python interpreter into an executable
|
||||||
|
# add_executable(myexe main.cpp)
|
||||||
|
# target_link_libraries(myexe pybind11::embed)
|
||||||
|
#
|
||||||
# Suggested usage::
|
# Suggested usage::
|
||||||
#
|
#
|
||||||
# find_package with version info is not recommended except for release versions. ::
|
# find_package with version info is not recommended except for release versions. ::
|
||||||
@ -71,21 +80,21 @@ if(NOT (CMAKE_VERSION VERSION_LESS 3.0))
|
|||||||
# Don't include targets if this file is being picked up by another
|
# Don't include targets if this file is being picked up by another
|
||||||
# project which has already built this as a subproject
|
# project which has already built this as a subproject
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
if(NOT TARGET ${PN}::module)
|
if(NOT TARGET ${PN}::pybind11)
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/${PN}Targets.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/${PN}Targets.cmake")
|
||||||
|
|
||||||
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED)
|
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED)
|
||||||
set_property(TARGET ${PN}::module APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
|
set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
|
||||||
|
set_property(TARGET ${PN}::embed APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
|
||||||
if(WIN32 OR CYGWIN)
|
if(WIN32 OR CYGWIN)
|
||||||
set_property(TARGET ${PN}::module APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
|
set_property(TARGET ${PN}::module APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
select_cxx_standard()
|
select_cxx_standard()
|
||||||
set_property(TARGET ${PN}::module APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${PYBIND11_CPP_STANDARD}")
|
set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${PYBIND11_CPP_STANDARD}")
|
||||||
|
|
||||||
get_property(_iid TARGET ${PN}::module PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
get_property(_iid TARGET ${PN}::pybind11 PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
get_property(_ill TARGET ${PN}::module PROPERTY INTERFACE_LINK_LIBRARIES)
|
get_property(_ill TARGET ${PN}::module PROPERTY INTERFACE_LINK_LIBRARIES)
|
||||||
get_property(_ico TARGET ${PN}::module PROPERTY INTERFACE_COMPILE_OPTIONS)
|
|
||||||
set(${PN}_INCLUDE_DIRS ${_iid})
|
set(${PN}_INCLUDE_DIRS ${_iid})
|
||||||
set(${PN}_LIBRARIES ${_ico} ${_ill})
|
set(${PN}_LIBRARIES ${_ico} ${_ill})
|
||||||
endif()
|
endif()
|
||||||
|
Loading…
Reference in New Issue
Block a user