add CMake exported interface library and Config detection file

This commit is contained in:
Lori A. Burns 2016-12-13 10:55:38 -05:00 committed by Wenzel Jakob
parent 44d7c59c55
commit 5cafc99884
5 changed files with 191 additions and 0 deletions

2
.gitignore vendored
View File

@ -33,3 +33,5 @@ MANIFEST
/cmake/
.cache/
sosize-*.txt
pybind11Config*.cmake
pybind11Targets.cmake

View File

@ -180,6 +180,7 @@ if (PYBIND11_TEST)
endif()
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
# extract project version from source
file(STRINGS "${PYBIND11_INCLUDE_DIR}/pybind11/common.h" pybind11_version_defines
@ -191,10 +192,40 @@ foreach(ver ${pybind11_version_defines})
endforeach()
set(${PROJECT_NAME}_VERSION ${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH})
if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) # CMake >= 3.0
# Build an interface library target:
add_library(pybind11 INTERFACE)
target_include_directories(pybind11 INTERFACE $<BUILD_INTERFACE:${PYBIND11_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
if(APPLE)
target_link_libraries(pybind11 INTERFACE "-undefined dynamic_lookup")
endif()
endif()
if (PYBIND11_INSTALL)
install(FILES ${PYBIND11_HEADERS}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/pybind11)
# GNUInstallDirs "DATADIR" wrong here; CMake search path wants "share".
set(PYBIND11_CMAKECONFIG_INSTALL_DIR "share/cmake/${PROJECT_NAME}" CACHE STRING "install path for pybind11Config.cmake")
configure_package_config_file(tools/${PROJECT_NAME}Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${${PROJECT_NAME}_VERSION}
COMPATIBILITY AnyNewerVersion)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
tools/FindPythonLibsNew.cmake
tools/pybind11Tools.cmake
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
if(NOT (CMAKE_VERSION VERSION_LESS 3.0))
install(TARGETS pybind11
EXPORT "${PROJECT_NAME}Targets")
install(EXPORT "${PROJECT_NAME}Targets"
NAMESPACE "${PROJECT_NAME}::"
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
message(STATUS "Exporting ${PROJECT_NAME}::pybind11 interface library target version ${${PROJECT_NAME}_VERSION}")
endif()
endif()

View File

@ -51,3 +51,67 @@ A working sample project, including a way to invoke CMake from :file:`setup.py`
PyPI integration, can be found in the [cmake_example]_ repository.
.. [cmake_example] https://github.com/pybind/cmake_example
For CMake-based projects that don't include the pybind11
repository internally, an external installation can be detected
through `find_package(pybind11 ... CONFIG ...)`. See the `Config file
<https://github.com/pybind/pybind11/blob/master/tools/pybind11Config.cmake.in>`_
docstring for details of relevant CMake variables.
Once detected, and after setting any variables to guide Python and C++
standard detection, the aforementioned ``pybind11_add_module``
wrapper to ``add_library`` can
be employed as described above (after ``include(pybind11Tools)``). This
procedure is available when using CMake >= 2.8.12. A
working example can be found at [test_installed_module]_ .
.. code-block:: cmake
cmake_minimum_required(VERSION 2.8.12)
project(example)
find_package(pybind11 REQUIRED)
pybind11_add_module(example example.cpp)
.. [test_installed_module] https://github.com/pybind/pybind11/blob/master/tests/test_installed_module/CMakeLists.txt
When using a version of CMake greater than 3.0, pybind11 can
additionally be used as a special *interface library* following the call
to ``find_package``. CMake
variables to guide Python and C++ standard detection should be set
*before* ``find_package``. When ``find_package`` returns, the target
``pybind11::pybind11`` is available with pybind11 headers, Python headers
and libraries as needed, and C++ compile definitions attached. This
target is suitable for linking to an independently constructed (through
``add_library``, not ``pybind11_add_module``) target in the consuming
project. A working example can be found at [test_installed_target]_ .
.. code-block:: cmake
cmake_minimum_required(VERSION 3.0)
project(example)
add_library(example MODULE main.cpp)
find_package(pybind11 REQUIRED)
target_link_libraries(example PRIVATE pybind11::pybind11)
set_target_properties(example PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
SUFFIX "${PYTHON_MODULE_EXTENSION}")
.. warning::
Since pybind11 is a metatemplate library, it is crucial that certain
compiler flags are provided to ensure high quality code generation. In
contrast to the ``pybind11_add_module()`` command, the CMake interface
library only provides the *minimal* set of parameters to ensure that the
code using pybind11 compiles, but it does **not** pass these extra compiler
flags (i.e. this is up to you).
These include Link Time Optimization (``-flto`` on GCC/Clang/ICPC, ``/GL``
and ``/LTCG`` on Visual Studio). Default-hidden symbols on GCC/Clang/ICPC
(``-fvisibility=hidden``) and .OBJ files with many sections on Visual Studio
(``/bigobj``). The :ref:`FAQ <faq:symhidden>` contains an
explanation on why these are needed.
.. [test_installed_target] https://github.com/pybind/pybind11/blob/master/tests/test_installed_target/CMakeLists.txt

View File

@ -162,6 +162,8 @@ culprit is generally the generation of function signatures at compile time
using C++14 template metaprogramming.
.. _`faq:symhidden`:
How can I create smaller binaries?
==================================

View File

@ -0,0 +1,92 @@
# pybind11Config.cmake
# --------------------
#
# PYBIND11 cmake module.
# This module sets the following variables in your project::
#
# pybind11_FOUND - true if pybind11 and all required components found on the system
# pybind11_VERSION - pybind11 version in format Major.Minor.Release
# pybind11_INCLUDE_DIRS - Directories where pybind11 and python headers are located.
# pybind11_INCLUDE_DIR - Directory where pybind11 headers are located.
# pybind11_DEFINITIONS - Definitions necessary to use pybind11, namely USING_pybind11.
# pybind11_LIBRARIES - compile flags and python libraries (as needed) to link against.
# pybind11_LIBRARY - empty.
# CMAKE_MODULE_PATH - appends location of accompanying FindPythonLibsNew.cmake and
# pybind11Tools.cmake modules.
#
#
# Available components: None
#
#
# Exported targets::
#
# If pybind11 is found, this module defines the following :prop_tgt:`IMPORTED`
# target. Python headers, libraries (as needed by platform), and C++ standard
# are attached to the target. Set PythonLibsNew variables to influence
# python detection and PYBIND11_CPP_STANDARD (-std=c++11 or -std=c++14) to
# influence standard setting. ::
#
# pybind11::pybind11 - the main pybind11 interface library (i.e., headers)
#
# find_package(pybind11 CONFIG REQUIRED)
# message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIR} (found version ${pybind11_VERSION} & Py${PYTHON_VERSION_STRING})")
# add_library(mylib MODULE main.cpp)
# target_link_libraries(mylib pybind11::pybind11)
#
# Suggested usage::
#
# find_package with version info is not recommended except for release versions. ::
#
# find_package(pybind11 CONFIG)
# find_package(pybind11 2.0 EXACT CONFIG REQUIRED)
#
#
# The following variables can be set to guide the search for this package::
#
# pybind11_DIR - CMake variable, set to directory containing this Config file
# CMAKE_PREFIX_PATH - CMake variable, set to root directory of this package
# PATH - environment variable, set to bin directory of this package
# CMAKE_DISABLE_FIND_PACKAGE_pybind11 - CMake variable, disables
# find_package(pybind11) when not REQUIRED, perhaps to force internal build
@PACKAGE_INIT@
set(PN pybind11)
# location of pybind11/pybind11.h
set(${PN}_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
set(${PN}_LIBRARY "")
set(${PN}_DEFINITIONS USING_${PN})
check_required_components(${PN})
# make detectable the FindPythonLibsNew.cmake module
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
include(pybind11Tools)
if(NOT (CMAKE_VERSION VERSION_LESS 3.0))
#-----------------------------------------------------------------------------
# Don't include targets if this file is being picked up by another
# project which has already built this as a subproject
#-----------------------------------------------------------------------------
if(NOT TARGET ${PN}::pybind11)
include("${CMAKE_CURRENT_LIST_DIR}/${PN}Targets.cmake")
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED)
set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
if(WIN32 OR CYGWIN)
set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
endif()
select_cxx_standard()
set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${PYBIND11_CPP_STANDARD}")
get_property(_iid TARGET ${PN}::pybind11 PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
get_property(_ill TARGET ${PN}::pybind11 PROPERTY INTERFACE_LINK_LIBRARIES)
get_property(_ico TARGET ${PN}::pybind11 PROPERTY INTERFACE_COMPILE_OPTIONS)
set(${PN}_INCLUDE_DIRS ${_iid})
set(${PN}_LIBRARIES ${_ico} ${_ill})
endif()
endif()