feat: drop CMake 3.6 and below, modernize CMake

fix: include PYTHON_IS_DEBUG
This commit is contained in:
Henry Schreiner 2020-07-28 00:43:12 -04:00 committed by Henry Schreiner
parent 1491c94c9d
commit 6ec1775fff
16 changed files with 334 additions and 364 deletions

View File

@ -95,7 +95,6 @@ jobs:
- name: Configure C++11 - name: Configure C++11
shell: bash shell: bash
run: > run: >
cmake --version &&
cmake -S . -B build cmake -S . -B build
-DPYBIND11_WERROR=ON -DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON -DDOWNLOAD_CATCH=ON
@ -163,7 +162,6 @@ jobs:
- name: Configure - name: Configure
shell: bash shell: bash
run: > run: >
cmake --version &&
cmake -S . -B build cmake -S . -B build
-DPYBIND11_WERROR=ON -DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON -DDOWNLOAD_CATCH=ON
@ -210,7 +208,6 @@ jobs:
- name: Configure - name: Configure
shell: bash shell: bash
run: > run: >
cmake --version &&
cmake -S . -B build cmake -S . -B build
-DPYBIND11_WERROR=ON -DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON -DDOWNLOAD_CATCH=ON
@ -256,7 +253,6 @@ jobs:
- name: Configure - name: Configure
shell: bash shell: bash
run: > run: >
cmake --version &&
cmake -S . -B build cmake -S . -B build
-DPYBIND11_WERROR=ON -DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON -DDOWNLOAD_CATCH=ON

View File

@ -34,24 +34,10 @@ jobs:
- name: Make build directories - name: Make build directories
run: | run: |
mkdir build2.8
mkdir build3.7 mkdir build3.7
mkdir build3.11
mkdir build3.18 mkdir build3.18
- name: Setup CMake 2.8
uses: jwlawson/actions-setup-cmake@v1.3
with:
cmake-version: 2.8
- name: Configure 2.8
working-directory: build2.8
run: >
cmake --version &&
cmake ..
-DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
- name: Setup CMake 3.7 - name: Setup CMake 3.7
uses: jwlawson/actions-setup-cmake@v1.3 uses: jwlawson/actions-setup-cmake@v1.3
with: with:
@ -60,7 +46,19 @@ jobs:
- name: Configure 3.7 - name: Configure 3.7
working-directory: build3.7 working-directory: build3.7
run: > run: >
cmake --version && cmake ..
-DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
- name: Setup CMake 3.11
uses: jwlawson/actions-setup-cmake@v1.3
with:
cmake-version: 3.11
- name: Configure 3.11
working-directory: build3.11
run: >
cmake .. cmake ..
-DPYBIND11_WERROR=ON -DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON -DDOWNLOAD_CATCH=ON
@ -74,7 +72,6 @@ jobs:
- name: Configure 3.18 - name: Configure 3.18
working-directory: build3.18 working-directory: build3.18
run: > run: >
cmake --version &&
cmake .. cmake ..
-DPYBIND11_WERROR=ON -DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON -DDOWNLOAD_CATCH=ON

View File

@ -5,31 +5,102 @@
# All rights reserved. Use of this source code is governed by a # All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file. # BSD-style license that can be found in the LICENSE file.
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.7)
if (POLICY CMP0048) # VERSION 3.7...3.18, but some versions of VS have a patched CMake 3.11
# cmake warns if loaded from a min-3.0-required parent dir, so silence the warning: # that do not work properly with this syntax, so using the following workaround:
cmake_policy(SET CMP0048 NEW) if(${CMAKE_VERSION} VERSION_LESS 3.18)
endif() cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
# CMake versions < 3.4.0 do not support try_compile/pthread checks without C as active language.
if(CMAKE_VERSION VERSION_LESS 3.4.0)
project(pybind11)
else() else()
project(pybind11 CXX) cmake_policy(VERSION 3.18)
endif() endif()
# Extract project version from source
file(
STRINGS
"${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
pybind11_version_defines
REGEX
"#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH|TYPE) ")
foreach(ver ${pybind11_version_defines})
if (ver MATCHES [=[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH|TYPE) +"?([^ ^"]+)"?$]=])
set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
endif()
endforeach()
project(
pybind11
LANGUAGES
CXX
VERSION
"${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}"
)
# Standard includes
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
# Check if pybind11 is being used directly or via add_subdirectory # Check if pybind11 is being used directly or via add_subdirectory
set(PYBIND11_MASTER_PROJECT OFF) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(PYBIND11_MASTER_PROJECT ON)
set(PYBIND11_MASTER_PROJECT ON) message(STATUS "pybind11 v${pybind11_VERSION} ${PYBIND11_VERSION_TYPE}")
message(STATUS "CMake ${CMAKE_VERSION}")
if(CMAKE_CXX_STANDARD)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
else()
set(PYBIND11_MASTER_PROJECT OFF)
set(pybind11_system SYSTEM)
endif() endif()
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT}) option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT}) option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
option(PYBIND11_CLASSIC_LTO "Use the classic LTO flag algorithm, even on CMake 3.9+" OFF)
cmake_dependent_option(
USE_PYTHON_INCLUDE_DIR
"Install pybind11 headers in Python include directory instead of default installation prefix" OFF
"PYBIND11_INSTALL" OFF
)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools") # NB: when adding a header don't forget to also add it to setup.py
set(PYBIND11_HEADERS
include/pybind11/detail/class.h
include/pybind11/detail/common.h
include/pybind11/detail/descr.h
include/pybind11/detail/init.h
include/pybind11/detail/internals.h
include/pybind11/detail/typeid.h
include/pybind11/attr.h
include/pybind11/buffer_info.h
include/pybind11/cast.h
include/pybind11/chrono.h
include/pybind11/common.h
include/pybind11/complex.h
include/pybind11/options.h
include/pybind11/eigen.h
include/pybind11/embed.h
include/pybind11/eval.h
include/pybind11/functional.h
include/pybind11/numpy.h
include/pybind11/operators.h
include/pybind11/pybind11.h
include/pybind11/pytypes.h
include/pybind11/stl.h
include/pybind11/stl_bind.h
)
# cmake 3.12 added list(TRANSFORM <list> PREPEND
# But we can't use it yet
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/"
PYBIND11_HEADERS "${PYBIND11_HEADERS}")
# Classic mode
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools")
include(pybind11Tools) include(pybind11Tools)
# Cache variables so pybind11_add_module can be used in parent projects # Cache variables so pybind11_add_module can be used in parent projects
@ -40,118 +111,131 @@ set(PYTHON_MODULE_PREFIX ${PYTHON_MODULE_PREFIX} CACHE INTERNAL "")
set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} CACHE INTERNAL "") set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} CACHE INTERNAL "")
set(PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR} CACHE INTERNAL "") set(PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR} CACHE INTERNAL "")
set(PYTHON_VERSION_MINOR ${PYTHON_VERSION_MINOR} CACHE INTERNAL "") set(PYTHON_VERSION_MINOR ${PYTHON_VERSION_MINOR} CACHE INTERNAL "")
set(PYTHON_IS_DEBUG "${PYTHON_IS_DEBUG}" CACHE INTERNAL "")
# NB: when adding a header don't forget to also add it to setup.py
set(PYBIND11_HEADERS
include/pybind11/detail/class.h
include/pybind11/detail/common.h
include/pybind11/detail/descr.h
include/pybind11/detail/init.h
include/pybind11/detail/internals.h
include/pybind11/detail/typeid.h
include/pybind11/attr.h
include/pybind11/buffer_info.h
include/pybind11/cast.h
include/pybind11/chrono.h
include/pybind11/common.h
include/pybind11/complex.h
include/pybind11/options.h
include/pybind11/eigen.h
include/pybind11/embed.h
include/pybind11/eval.h
include/pybind11/functional.h
include/pybind11/numpy.h
include/pybind11/operators.h
include/pybind11/pybind11.h
include/pybind11/pytypes.h
include/pybind11/stl.h
include/pybind11/stl_bind.h
)
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/"
PYBIND11_HEADERS "${PYBIND11_HEADERS}")
if (PYBIND11_TEST) if(PYBIND11_TEST OR (BUILD_TESTING AND PYBIND11_MASTER_PROJECT))
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
# extract project version from source if(USE_PYTHON_INCLUDE_DIR)
file(STRINGS "${PYBIND11_INCLUDE_DIR}/pybind11/detail/common.h" pybind11_version_defines
REGEX "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) ")
foreach(ver ${pybind11_version_defines})
if (ver MATCHES "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$")
set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "")
endif()
endforeach()
set(${PROJECT_NAME}_VERSION ${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH})
message(STATUS "pybind11 v${${PROJECT_NAME}_VERSION}")
option (USE_PYTHON_INCLUDE_DIR "Install pybind11 headers in Python include directory instead of default installation prefix" OFF)
if (USE_PYTHON_INCLUDE_DIR)
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS}) file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
endif() endif()
if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) # CMake >= 3.0 # Note: when creating targets, you cannot use if statements at configure time -
# Build an interface library target: # you need generator expressions, because those will be placed in the target file.
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) # Build an interface library target:
add_library(pybind11::module ALIAS module) add_library(pybind11 INTERFACE)
if(NOT MSVC) add_library(pybind11::pybind11 ALIAS pybind11) # to match exported target
target_compile_options(module INTERFACE -fvisibility=hidden)
endif()
target_link_libraries(module INTERFACE pybind11::pybind11)
if(WIN32 OR CYGWIN)
target_link_libraries(module INTERFACE $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
elseif(APPLE)
target_link_libraries(module INTERFACE "-undefined dynamic_lookup")
endif()
add_library(embed INTERFACE) target_include_directories(pybind11 ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${PYBIND11_INCLUDE_DIR}>
add_library(pybind11::embed ALIAS embed) $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_link_libraries(embed INTERFACE pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>) # Only add Python for build - must be added during the import for config since it has to be re-discovered.
target_include_directories(pybind11 SYSTEM INTERFACE $<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>)
if(CMAKE_VERSION VERSION_LESS 3.13)
target_compile_features(
pybind11
INTERFACE
cxx_auto_type
cxx_constexpr
cxx_defaulted_functions
cxx_lambdas
cxx_nullptr
cxx_range_for
cxx_right_angle_brackets
cxx_strong_enums
cxx_user_literals
cxx_variadic_templates
)
else()
# This was added in CMake 3.8, but we are keeping a consistent breaking
# point for the config file at 3.13. A config generated by CMake 3.13+
# can ony be read in 3.13+ due to the SHELL usage later, so this is safe to do.
target_compile_features(pybind11 INTERFACE cxx_std_11)
endif() endif()
if (PYBIND11_INSTALL) add_library(module INTERFACE)
install(DIRECTORY ${PYBIND11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) add_library(pybind11::module ALIAS module)
# 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 target_link_libraries(module INTERFACE pybind11::pybind11)
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR}) # See https://github.com/Kitware/CMake/blob/master/Modules/CMakePlatformId.h.in for platform IDs
# Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does # Note: CMake 3.15 allows $<PLATFORM_ID:Windows,Cygwin>
# not depend on architecture specific settings or libraries. target_link_libraries(module INTERFACE "$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>")
set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
unset(CMAKE_SIZEOF_VOID_P) if(CMAKE_VERSION VERSION_LESS 3.13)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake target_link_libraries(module INTERFACE "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
VERSION ${${PROJECT_NAME}_VERSION} else()
COMPATIBILITY AnyNewerVersion) # SHELL (3.12+) forces this to remain together, and link_options was added in 3.13+
set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P}) target_link_options(module INTERFACE "$<$<PLATFORM_ID:Darwin>:SHELL:-undefined dynamic_lookup>")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake endif()
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
tools/FindPythonLibsNew.cmake
tools/pybind11Tools.cmake message(STATUS "CXX Compiler version: ${CMAKE_CXX_COMPILER_VERSION}")
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
set(clang_4plus "$<AND:$<CXX_COMPILER_ID:Clang>,$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,3.9>>>")
set(no_register "$<OR:${clang_4plus},$<CXX_COMPILER_ID:AppleClang>>")
target_compile_options(pybind11 INTERFACE "$<${no_register}:-Wno-register;-Wno-deprecated-register>")
add_library(embed INTERFACE)
add_library(pybind11::embed ALIAS embed)
target_link_libraries(embed INTERFACE pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
if(PYBIND11_INSTALL)
install(DIRECTORY ${PYBIND11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# 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})
if(CMAKE_VERSION VERSION_LESS 3.14)
# Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does
# not depend on architecture specific settings or libraries.
set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
unset(CMAKE_SIZEOF_VOID_P)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION
${PROJECT_VERSION}
COMPATIBILITY
AnyNewerVersion
)
set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})
else()
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION
${PROJECT_VERSION}
COMPATIBILITY
AnyNewerVersion
ARCH_INDEPENDENT
)
endif()
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))
if(NOT PYBIND11_EXPORT_NAME) if(NOT PYBIND11_EXPORT_NAME)
set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets") set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets")
endif() endif()
install(TARGETS pybind11 module embed install(TARGETS pybind11 module embed
EXPORT "${PYBIND11_EXPORT_NAME}") EXPORT "${PYBIND11_EXPORT_NAME}")
if(PYBIND11_MASTER_PROJECT)
install(EXPORT "${PYBIND11_EXPORT_NAME}" install(EXPORT "${PYBIND11_EXPORT_NAME}"
NAMESPACE "${PROJECT_NAME}::" NAMESPACE "pybind11::"
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR}) DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
endif()
endif()
endif() endif()

View File

@ -33,7 +33,7 @@ extension module can be created with just a few lines of code:
.. code-block:: cmake .. code-block:: cmake
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.7)
project(example) project(example)
add_subdirectory(pybind11) add_subdirectory(pybind11)
@ -59,7 +59,7 @@ function with the following signature:
.. code-block:: cmake .. code-block:: cmake
pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL] pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
[NO_EXTRAS] [SYSTEM] [THIN_LTO] source1 [source2 ...]) [NO_EXTRAS] [THIN_LTO] source1 [source2 ...])
This function behaves very much like CMake's builtin ``add_library`` (in fact, This function behaves very much like CMake's builtin ``add_library`` (in fact,
it's a wrapper function around that command). It will add a library target it's a wrapper function around that command). It will add a library target
@ -86,10 +86,6 @@ latter optimizations are never applied in ``Debug`` mode. If ``NO_EXTRAS`` is
given, they will always be disabled, even in ``Release`` mode. However, this given, they will always be disabled, even in ``Release`` mode. However, this
will result in code bloat and is generally not recommended. will result in code bloat and is generally not recommended.
By default, pybind11 and Python headers will be included with ``-I``. In order
to include pybind11 as system library, e.g. to avoid warnings in downstream
code with warn-levels outside of pybind11's scope, set the option ``SYSTEM``.
As stated above, LTO is enabled by default. Some newer compilers also support As stated above, LTO is enabled by default. Some newer compilers also support
different flavors of LTO such as `ThinLTO`_. Setting ``THIN_LTO`` will cause different flavors of LTO such as `ThinLTO`_. Setting ``THIN_LTO`` will cause
the function to prefer this flavor if available. The function falls back to the function to prefer this flavor if available. The function falls back to
@ -100,25 +96,22 @@ regular LTO if ``-flto=thin`` is not available.
Configuration variables Configuration variables
----------------------- -----------------------
By default, pybind11 will compile modules with the C++14 standard, if available By default, pybind11 will compile modules with the compiler default or the
on the target compiler, falling back to C++11 if C++14 support is not minimum standard required by PyBind11, whichever is higher. You can set the
available. Note, however, that this default is subject to change: future standard explicitly with
pybind11 releases are expected to migrate to newer C++ standards as they become `CMAKE_CXX_STANDARD <https://cmake.org/cmake/help/latest/variable/CMAKE_CXX_STANDARD.html>`_:
available. To override this, the standard flag can be given explicitly in
`CMAKE_CXX_STANDARD <https://cmake.org/cmake/help/v3.17/variable/CMAKE_CXX_STANDARD.html>`_:
.. code-block:: cmake .. code-block:: cmake
# Use just one of these: # Use just one of these:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17) # Experimental C++17 support set(CMAKE_CXX_STANDARD 17)
add_subdirectory(pybind11) # or find_package(pybind11)
Note that this and all other configuration variables must be set **before** the The variables can also be set when calling CMake from the command line using
call to ``add_subdirectory`` or ``find_package``. The variables can also be set the ``-D<variable>=<value>`` flag. You can also manually set ``CXX_STANDARD``
when calling CMake from the command line using the ``-D<variable>=<value>`` flag. on a target or use ``target_compile_features`` on your targets - anything that
CMake supports.
The target Python version can be selected by setting ``PYBIND11_PYTHON_VERSION`` The target Python version can be selected by setting ``PYBIND11_PYTHON_VERSION``
or an exact Python installation can be specified with ``PYTHON_EXECUTABLE``. or an exact Python installation can be specified with ``PYTHON_EXECUTABLE``.
@ -128,7 +121,7 @@ For example:
cmake -DPYBIND11_PYTHON_VERSION=3.6 .. cmake -DPYBIND11_PYTHON_VERSION=3.6 ..
# or # or
cmake -DPYTHON_EXECUTABLE=path/to/python .. cmake -DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") ..
find_package vs. add_subdirectory find_package vs. add_subdirectory
--------------------------------- ---------------------------------
@ -139,7 +132,7 @@ See the `Config file`_ docstring for details of relevant CMake variables.
.. code-block:: cmake .. code-block:: cmake
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.7)
project(example) project(example)
find_package(pybind11 REQUIRED) find_package(pybind11 REQUIRED)
@ -171,13 +164,13 @@ Advanced: interface library target
When using a version of CMake greater than 3.0, pybind11 can additionally When using a version of CMake greater than 3.0, pybind11 can additionally
be used as a special *interface library* . The target ``pybind11::module`` be used as a special *interface library* . The target ``pybind11::module``
is available with pybind11 headers, Python headers and libraries as needed, is available with pybind11 headers, Python headers and libraries as needed,
and C++ compile definitions attached. This target is suitable for linking and C++ compile features attached. This target is suitable for linking
to an independently constructed (through ``add_library``, not to an independently constructed (through ``add_library``, not
``pybind11_add_module``) target in the consuming project. ``pybind11_add_module``) target in the consuming project.
.. code-block:: cmake .. code-block:: cmake
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.7)
project(example) project(example)
find_package(pybind11 REQUIRED) # or add_subdirectory(pybind11) find_package(pybind11 REQUIRED) # or add_subdirectory(pybind11)
@ -201,6 +194,17 @@ to an independently constructed (through ``add_library``, not
Studio (``/bigobj``). The :ref:`FAQ <faq:symhidden>` contains an Studio (``/bigobj``). The :ref:`FAQ <faq:symhidden>` contains an
explanation on why these are needed. explanation on why these are needed.
If you want to add these in yourself, you can use:
.. code-block:: cmake
cmake_minimum_required(3.9)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
or set teh corisponding property (without the ``CMAKE_``) on the targets
manually.
Embedding the Python interpreter Embedding the Python interpreter
-------------------------------- --------------------------------
@ -213,7 +217,7 @@ information about usage in C++, see :doc:`/advanced/embedding`.
.. code-block:: cmake .. code-block:: cmake
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.7)
project(example) project(example)
find_package(pybind11 REQUIRED) # or add_subdirectory(pybind11) find_package(pybind11 REQUIRED) # or add_subdirectory(pybind11)

View File

@ -9,6 +9,11 @@
#pragma once #pragma once
#define PYBIND11_VERSION_MAJOR 2
#define PYBIND11_VERSION_MINOR 6
#define PYBIND11_VERSION_PATCH 0
#define PYBIND11_VERSION_TYPE "dev"
#define PYBIND11_NAMESPACE_BEGIN(name) namespace name { #define PYBIND11_NAMESPACE_BEGIN(name) namespace name {
#define PYBIND11_NAMESPACE_END(name) } #define PYBIND11_NAMESPACE_END(name) }
@ -96,10 +101,6 @@
# define PYBIND11_MAYBE_UNUSED __attribute__ ((__unused__)) # define PYBIND11_MAYBE_UNUSED __attribute__ ((__unused__))
#endif #endif
#define PYBIND11_VERSION_MAJOR 2
#define PYBIND11_VERSION_MINOR 5
#define PYBIND11_VERSION_PATCH dev1
/* Don't let Python.h #define (v)snprintf as macro because they are implemented /* Don't let Python.h #define (v)snprintf as macro because they are implemented
properly in Visual Studio since 2015. */ properly in Visual Studio since 2015. */
#if defined(_MSC_VER) && _MSC_VER >= 1900 #if defined(_MSC_VER) && _MSC_VER >= 1900

View File

@ -5,16 +5,26 @@
# All rights reserved. Use of this source code is governed by a # All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file. # BSD-style license that can be found in the LICENSE file.
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.7)
# VERSION 3.7...3.18, but some versions of VS have a patched CMake 3.11
# that do not work properly with this syntax, so using the following workaround:
if(${CMAKE_VERSION} VERSION_LESS 3.18)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
cmake_policy(VERSION 3.18)
endif()
# There's no harm in including a project in a project
project(pybind11_tests CXX)
option(PYBIND11_WERROR "Report all warnings as errors" OFF) option(PYBIND11_WERROR "Report all warnings as errors" OFF)
option(DOWNLOAD_EIGEN "Download EIGEN (requires CMake 3.11+)" OFF)
set(PYBIND11_TEST_OVERRIDE "" CACHE STRING "Tests from ;-separated list of *.cpp files will be built instead of all tests") set(PYBIND11_TEST_OVERRIDE "" CACHE STRING "Tests from ;-separated list of *.cpp files will be built instead of all tests")
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
# We're being loaded directly, i.e. not via add_subdirectory, so make this # We're being loaded directly, i.e. not via add_subdirectory, so make this
# work as its own project and load the pybind11Config to get the tools we need # work as its own project and load the pybind11Config to get the tools we need
project(pybind11_tests CXX)
find_package(pybind11 REQUIRED CONFIG) find_package(pybind11 REQUIRED CONFIG)
endif() endif()
@ -97,8 +107,6 @@ set(PYBIND11_CROSS_MODULE_GIL_TESTS
test_gil_scoped.py test_gil_scoped.py
) )
option(DOWNLOAD_EIGEN "Download EIGEN (requires CMake 3.11+)" OFF)
# Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but # Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but
# keep it in PYBIND11_PYTEST_FILES, so that we get the "eigen is not installed" # keep it in PYBIND11_PYTEST_FILES, so that we get the "eigen is not installed"
# skip message). # skip message).
@ -130,14 +138,13 @@ if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)
set(EIGEN3_INCLUDE_DIR ${eigen_SOURCE_DIR}) set(EIGEN3_INCLUDE_DIR ${eigen_SOURCE_DIR})
set(EIGEN3_FOUND TRUE) set(EIGEN3_FOUND TRUE)
else() else()
if (NOT CMAKE_VERSION VERSION_LESS 3.0) find_package(Eigen3 3.2.7 QUIET CONFIG)
find_package(Eigen3 3.2.7 QUIET CONFIG) if (EIGEN3_FOUND)
if (EIGEN3_FOUND) if (EIGEN3_VERSION_STRING AND NOT EIGEN3_VERSION_STRING VERSION_LESS 3.3.1)
if (EIGEN3_VERSION_STRING AND NOT EIGEN3_VERSION_STRING VERSION_LESS 3.3.1) set(PYBIND11_EIGEN_VIA_TARGET TRUE)
set(PYBIND11_EIGEN_VIA_TARGET TRUE)
endif()
endif() endif()
endif() endif()
if (NOT EIGEN3_FOUND) if (NOT EIGEN3_FOUND)
# Couldn't load via target, so fall back to allowing module mode finding, which will pick up # Couldn't load via target, so fall back to allowing module mode finding, which will pick up
# tools/FindEigen3.cmake # tools/FindEigen3.cmake
@ -178,6 +185,7 @@ function(pybind11_enable_warnings target_name)
endif() endif()
endif() endif()
# Needs to be readded since the ordering requires these to be after the ones above
if(CMAKE_CXX_STANDARD AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND PYTHON_VERSION VERSION_LESS 3.0) if(CMAKE_CXX_STANDARD AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND PYTHON_VERSION VERSION_LESS 3.0)
if(CMAKE_CXX_STANDARD LESS 17) if(CMAKE_CXX_STANDARD LESS 17)
target_compile_options(${target_name} PUBLIC -Wno-deprecated-register) target_compile_options(${target_name} PUBLIC -Wno-deprecated-register)
@ -259,15 +267,9 @@ if(NOT PYBIND11_PYTEST_FOUND)
set(PYBIND11_PYTEST_FOUND TRUE CACHE INTERNAL "") set(PYBIND11_PYTEST_FOUND TRUE CACHE INTERNAL "")
endif() endif()
if(CMAKE_VERSION VERSION_LESS 3.2)
set(PYBIND11_USES_TERMINAL "")
else()
set(PYBIND11_USES_TERMINAL "USES_TERMINAL")
endif()
# A single command to compile and run the tests # A single command to compile and run the tests
add_custom_target(pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PYBIND11_PYTEST_FILES} add_custom_target(pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PYBIND11_PYTEST_FILES}
DEPENDS ${test_targets} WORKING_DIRECTORY ${testdir} ${PYBIND11_USES_TERMINAL}) DEPENDS ${test_targets} WORKING_DIRECTORY ${testdir} USES_TERMINAL)
if(PYBIND11_TEST_OVERRIDE) if(PYBIND11_TEST_OVERRIDE)
add_custom_command(TARGET pytest POST_BUILD add_custom_command(TARGET pytest POST_BUILD
@ -279,14 +281,19 @@ add_custom_target(check DEPENDS pytest)
# The remaining tests only apply when being built as part of the pybind11 project, but not if the # The remaining tests only apply when being built as part of the pybind11 project, but not if the
# tests are being built independently. # tests are being built independently.
if (NOT PROJECT_NAME STREQUAL "pybind11") if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
return() return()
endif() endif()
# Add a post-build comment to show the primary test suite .so size and, if a previous size, compare it: # Add a post-build comment to show the primary test suite .so size and, if a previous size, compare it:
add_custom_command(TARGET pybind11_tests POST_BUILD add_custom_command(
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/libsize.py TARGET
$<TARGET_FILE:pybind11_tests> ${CMAKE_CURRENT_BINARY_DIR}/sosize-$<TARGET_FILE_NAME:pybind11_tests>.txt) pybind11_tests
POST_BUILD COMMAND
${PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tools/libsize.py
$<TARGET_FILE:pybind11_tests>
${CMAKE_CURRENT_BINARY_DIR}/sosize-$<TARGET_FILE_NAME:pybind11_tests>.txt)
# Test embedding the interpreter. Provides the `cpptest` target. # Test embedding the interpreter. Provides the `cpptest` target.
add_subdirectory(test_embed) add_subdirectory(test_embed)

View File

@ -1,26 +1,22 @@
add_custom_target(test_cmake_build) add_custom_target(test_cmake_build)
if(CMAKE_VERSION VERSION_LESS 3.1)
# 3.0 needed for interface library for subdirectory_target/installed_target
# 3.1 needed for cmake -E env for testing
return()
endif()
include(CMakeParseArguments)
function(pybind11_add_build_test name) function(pybind11_add_build_test name)
cmake_parse_arguments(ARG "INSTALL" "" "" ${ARGN}) cmake_parse_arguments(ARG "INSTALL" "" "" ${ARGN})
set(build_options "-DCMAKE_PREFIX_PATH=${PROJECT_BINARY_DIR}/mock_install" set(build_options "-DCMAKE_PREFIX_PATH=${pybind11_BINARY_DIR}/mock_install"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}" "-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}")
"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
"-DPYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}") if(CMAKE_CXX_STANDARD)
list(APPEND build_options "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
endif()
if(NOT ARG_INSTALL) if(NOT ARG_INSTALL)
list(APPEND build_options "-DPYBIND11_PROJECT_DIR=${PROJECT_SOURCE_DIR}") list(APPEND build_options "-DPYBIND11_PROJECT_DIR=${pybind11_SOURCE_DIR}")
endif() endif()
add_custom_target(test_${name} ${CMAKE_CTEST_COMMAND} add_custom_target(test_${name} ${CMAKE_CTEST_COMMAND}
--quiet --output-log ${name}.log
--build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/${name}" --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/${name}"
"${CMAKE_CURRENT_BINARY_DIR}/${name}" "${CMAKE_CURRENT_BINARY_DIR}/${name}"
--build-config Release --build-config Release
@ -45,8 +41,8 @@ endif()
if(PYBIND11_INSTALL) if(PYBIND11_INSTALL)
add_custom_target(mock_install ${CMAKE_COMMAND} add_custom_target(mock_install ${CMAKE_COMMAND}
"-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/mock_install" "-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install"
-P "${PROJECT_BINARY_DIR}/cmake_install.cmake" -P "${pybind11_BINARY_DIR}/cmake_install.cmake"
) )
pybind11_add_build_test(installed_function INSTALL) pybind11_add_build_test(installed_function INSTALL)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.7)
project(test_installed_embed CXX) project(test_installed_embed CXX)
set(CMAKE_MODULE_PATH "") set(CMAKE_MODULE_PATH "")
@ -14,11 +14,3 @@ target_link_libraries(test_cmake_build PRIVATE pybind11::embed)
set_target_properties(test_cmake_build PROPERTIES NO_SYSTEM_FROM_IMPORTED ON) 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) add_custom_target(check $<TARGET_FILE:test_cmake_build> ${PROJECT_SOURCE_DIR}/../test.py)
if(CMAKE_CXX_STANDARD AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND PYTHON_VERSION VERSION_LESS 3.0)
if(CMAKE_CXX_STANDARD LESS 17)
target_compile_options(test_cmake_build PUBLIC -Wno-deprecated-register)
else()
target_compile_options(test_cmake_build PUBLIC -Wno-register)
endif()
endif()

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.7)
project(test_installed_module CXX) project(test_installed_module CXX)
set(CMAKE_MODULE_PATH "") set(CMAKE_MODULE_PATH "")

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.7)
project(test_installed_target CXX) project(test_installed_target CXX)
set(CMAKE_MODULE_PATH "") set(CMAKE_MODULE_PATH "")
@ -20,11 +20,3 @@ set_target_properties(test_cmake_build PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)
add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$<TARGET_FILE_DIR:test_cmake_build> add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$<TARGET_FILE_DIR:test_cmake_build>
${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME})
if(CMAKE_CXX_STANDARD AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND PYTHON_VERSION VERSION_LESS 3.0)
if(CMAKE_CXX_STANDARD LESS 17)
target_compile_options(test_cmake_build PUBLIC -Wno-deprecated-register)
else()
target_compile_options(test_cmake_build PUBLIC -Wno-register)
endif()
endif()

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.7)
project(test_subdirectory_embed CXX) project(test_subdirectory_embed CXX)
set(PYBIND11_INSTALL ON CACHE BOOL "") set(PYBIND11_INSTALL ON CACHE BOOL "")
@ -23,13 +23,3 @@ install(TARGETS test_embed_lib
RUNTIME DESTINATION lib) RUNTIME DESTINATION lib)
install(EXPORT test_export install(EXPORT test_export
DESTINATION lib/cmake/test_export/test_export-Targets.cmake) DESTINATION lib/cmake/test_export/test_export-Targets.cmake)
if(CMAKE_CXX_STANDARD AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND PYTHON_VERSION VERSION_LESS 3.0)
if(CMAKE_CXX_STANDARD LESS 17)
target_compile_options(test_embed_lib PUBLIC -Wno-deprecated-register)
target_compile_options(test_cmake_build PUBLIC -Wno-deprecated-register)
else()
target_compile_options(test_embed_lib PUBLIC -Wno-register)
target_compile_options(test_cmake_build PUBLIC -Wno-register)
endif()
endif()

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.7)
project(test_subdirectory_module CXX) project(test_subdirectory_module CXX)
add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11) add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.7)
project(test_subdirectory_target CXX) project(test_subdirectory_target CXX)
add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11) add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11)
@ -13,11 +13,3 @@ set_target_properties(test_cmake_build PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX
add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$<TARGET_FILE_DIR:test_cmake_build> add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$<TARGET_FILE_DIR:test_cmake_build>
${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME})
if(CMAKE_CXX_STANDARD AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND PYTHON_VERSION VERSION_LESS 3.0)
if(CMAKE_CXX_STANDARD LESS 17)
target_compile_options(test_cmake_build PUBLIC -Wno-deprecated-register)
else()
target_compile_options(test_cmake_build PUBLIC -Wno-register)
endif()
endif()

View File

@ -20,18 +20,12 @@ add_executable(test_embed
target_include_directories(test_embed PRIVATE "${CATCH_INCLUDE_DIR}") target_include_directories(test_embed PRIVATE "${CATCH_INCLUDE_DIR}")
pybind11_enable_warnings(test_embed) pybind11_enable_warnings(test_embed)
if(NOT CMAKE_VERSION VERSION_LESS 3.0) target_link_libraries(test_embed PRIVATE pybind11::embed)
target_link_libraries(test_embed PRIVATE pybind11::embed)
else()
target_include_directories(test_embed PRIVATE "${PYBIND11_INCLUDE_DIR}" "${PYTHON_INCLUDE_DIRS}")
target_compile_options(test_embed PRIVATE "${PYBIND11_CPP_STANDARD}")
target_link_libraries(test_embed PRIVATE "${PYTHON_LIBRARIES}")
endif()
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
target_link_libraries(test_embed PUBLIC ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(test_embed PUBLIC Threads::Threads)
add_custom_target(cpptest COMMAND $<TARGET_FILE:test_embed> add_custom_target(cpptest COMMAND "$<TARGET_FILE:test_embed>"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
pybind11_add_module(external_module THIN_LTO external_module.cpp) pybind11_add_module(external_module THIN_LTO external_module.cpp)
@ -43,13 +37,3 @@ endforeach()
add_dependencies(cpptest external_module) add_dependencies(cpptest external_module)
add_dependencies(check cpptest) add_dependencies(check cpptest)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND PYTHON_VERSION VERSION_LESS 3.0)
if(CMAKE_CXX_STANDARD LESS 17)
target_compile_options(test_embed PUBLIC -Wno-deprecated-register)
target_compile_options(external_module PUBLIC -Wno-deprecated-register)
else()
target_compile_options(test_embed PUBLIC -Wno-register)
target_compile_options(external_module PUBLIC -Wno-register)
endif()
endif()

View File

@ -75,7 +75,6 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
include(pybind11Tools) include(pybind11Tools)
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
@ -85,20 +84,14 @@ if(NOT TARGET ${PN}::pybind11)
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED) find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED)
set_property(TARGET ${PN}::pybind11 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}::pybind11 APPEND PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
set_property(TARGET ${PN}::embed APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES}) 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()
if(CMAKE_VERSION VERSION_LESS 3.3)
set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${PYBIND11_CPP_STANDARD}")
else()
set_property(TARGET ${PN}::pybind11 APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CXX>:${PYBIND11_CPP_STANDARD}>)
endif()
get_property(_iid TARGET ${PN}::pybind11 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)
set(${PN}_INCLUDE_DIRS ${_iid}) set(${PN}_INCLUDE_DIRS ${_iid})
set(${PN}_LIBRARIES ${_ico} ${_ill}) set(${PN}_LIBRARIES ${_ico} ${_ill})
endif() endif()
endif()

View File

@ -5,56 +5,41 @@
# All rights reserved. Use of this source code is governed by a # All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file. # BSD-style license that can be found in the LICENSE file.
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 3.7)
# VERSION 3.7...3.18, but some versions of VS have a patched CMake 3.11
# that do not work properly with this syntax, so using the following workaround:
if(${CMAKE_VERSION} VERSION_LESS 3.18)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
cmake_policy(VERSION 3.18)
endif()
# Add a CMake parameter for choosing a desired Python version # Add a CMake parameter for choosing a desired Python version
if(NOT PYBIND11_PYTHON_VERSION) if(NOT PYBIND11_PYTHON_VERSION)
set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules") set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules")
endif() endif()
set(Python_ADDITIONAL_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4) # A user can set versions manually too
set(Python_ADDITIONAL_VERSIONS "3.9;3.8;3.7;3.6;3.5;3.4" CACHE INTERNAL "")
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED) find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(CMakeParseArguments) include(CMakeParseArguments)
# Use the language standards abstraction if CMake supports it with the current compiler # Use the language standards abstraction if CMake supports it with the current compiler
if(NOT CMAKE_VERSION VERSION_LESS 3.1) if(PYBIND11_CPP_STANDARD)
if(NOT CMAKE_CXX_STANDARD) message(WARNING "USE -DCMAKE_CXX_STANDARD=11 instead of PYBIND11_PYTHON_VERSION")
if(CMAKE_CXX14_STANDARD_COMPILE_OPTION) if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14) string(REGEX MATCH
elseif(CMAKE_CXX11_STANDARD_COMPILE_OPTION) [=[..^]=]
set(CMAKE_CXX_STANDARD 11) VAL
"${PYBIND11_CPP_STANDARD}")
set(CMAKE_CXX_STANDARD ${VAL})
endif() endif()
endif()
if(CMAKE_CXX_STANDARD)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
endif() endif()
# Fall back to heuristics
if(NOT PYBIND11_CPP_STANDARD AND NOT CMAKE_CXX_STANDARD)
if(MSVC)
set(PYBIND11_CPP_STANDARD /std:c++14)
else()
check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
if(HAS_CPP14_FLAG)
set(PYBIND11_CPP_STANDARD -std=c++14)
else()
check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
if(HAS_CPP11_FLAG)
set(PYBIND11_CPP_STANDARD -std=c++11)
endif()
endif()
endif()
if(NOT PYBIND11_CPP_STANDARD)
message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
endif()
set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
"C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to C++14 mode." FORCE)
endif()
# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and # Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and
# linkerflags are lists of flags to use. The result variable is a unique variable name for each set # linkerflags are lists of flags to use. The result variable is a unique variable name for each set
@ -117,16 +102,18 @@ function(_pybind11_add_lto_flags target_name prefer_thin_lto)
# Enable LTO flags if found, except for Debug builds # Enable LTO flags if found, except for Debug builds
if (PYBIND11_LTO_CXX_FLAGS) if (PYBIND11_LTO_CXX_FLAGS)
target_compile_options(${target_name} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:${PYBIND11_LTO_CXX_FLAGS}>") set(not_debug "$<NOT:$<CONFIG:Debug>>")
set(cxx_lang "$<COMPILE_LANGUAGE:CXX>")
target_compile_options(${target_name} PRIVATE "$<$<AND:${not_debug},${cxx_lang}>:${PYBIND11_LTO_CXX_FLAGS}>")
endif() endif()
if (PYBIND11_LTO_LINKER_FLAGS) if (PYBIND11_LTO_LINKER_FLAGS)
target_link_libraries(${target_name} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:${PYBIND11_LTO_LINKER_FLAGS}>") target_link_libraries(${target_name} PRIVATE "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
endif() endif()
endfunction() endfunction()
# Build a Python extension module: # Build a Python extension module:
# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL] # pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
# [NO_EXTRAS] [SYSTEM] [THIN_LTO] source1 [source2 ...]) # [NO_EXTRAS] [THIN_LTO] source1 [source2 ...])
# #
function(pybind11_add_module target_name) function(pybind11_add_module target_name)
set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS SYSTEM THIN_LTO) set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS SYSTEM THIN_LTO)
@ -148,29 +135,13 @@ function(pybind11_add_module target_name)
add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS}) add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS})
target_link_libraries(${target_name} PRIVATE pybind11::module)
if(ARG_SYSTEM) if(ARG_SYSTEM)
set(inc_isystem SYSTEM) message(STATUS "Warning: this does not have an effect - use NO_SYSTEM_FROM_IMPORTED if using imported targets")
else()
set(inc_isystem "")
endif() endif()
set(PYBIND11_INCLUDE_DIR_SELECTED "") # Python debug libraries expose slightly different objects before 3.8
if(PYBIND11_INCLUDE_DIR)
# from project CMakeLists.txt
set(PYBIND11_INCLUDE_DIR_SELECTED ${PYBIND11_INCLUDE_DIR})
elseif(pybind11_INCLUDE_DIR)
# from pybind11Config
set(PYBIND11_INCLUDE_DIR_SELECTED ${pybind11_INCLUDE_DIR})
else()
message(FATAL "No pybind11_INCLUDE_DIR available. Use "
"find_package(pybind11) before calling pybind11_add_module.")
endif()
target_include_directories(${target_name} ${inc_isystem}
PRIVATE ${PYBIND11_INCLUDE_DIR_SELECTED}
PRIVATE ${PYTHON_INCLUDE_DIRS})
# Python debug libraries expose slightly different objects
# https://docs.python.org/3.6/c-api/intro.html#debugging-builds # https://docs.python.org/3.6/c-api/intro.html#debugging-builds
# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib # https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
if(PYTHON_IS_DEBUG) if(PYTHON_IS_DEBUG)
@ -189,54 +160,25 @@ function(pybind11_add_module target_name)
set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden") set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden") set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden")
if(WIN32 OR CYGWIN)
# Link against the Python shared library on Windows
target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES})
elseif(APPLE)
# It's quite common to have multiple copies of the same Python version
# installed on one's system. E.g.: one copy from the OS and another copy
# that's statically linked into an application like Blender or Maya.
# If we link our plugin library against the OS Python here and import it
# into Blender or Maya later on, this will cause segfaults when multiple
# conflicting Python instances are active at the same time (even when they
# are of the same version).
# Windows is not affected by this issue since it handles DLL imports
# differently. The solution for Linux and Mac OS is simple: we just don't
# link against the Python library. The resulting shared library will have
# missing symbols, but that's perfectly fine -- they will be resolved at
# import time.
target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup")
if(ARG_SHARED)
# Suppress CMake >= 3.0 warning for shared libraries
set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON)
endif()
endif()
# Make sure C++11/14 are enabled
if(PYBIND11_CPP_STANDARD)
if(CMAKE_VERSION VERSION_LESS 3.3)
target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD})
else()
target_compile_options(${target_name} PUBLIC $<$<COMPILE_LANGUAGE:CXX>:${PYBIND11_CPP_STANDARD}>)
endif()
endif()
# Python 2 doesn't really support C++17, Clang warns/errors over it
if(CMAKE_CXX_STANDARD
AND CMAKE_CXX_COMPILER_ID MATCHES "Clang"
AND PYTHON_VERSION VERSION_LESS 3.0
AND NOT CMAKE_CXX_STANDARD LESS 17)
target_compile_options(${target_name} PUBLIC -Wno-register)
endif()
if(ARG_NO_EXTRAS) if(ARG_NO_EXTRAS)
return() return()
endif() endif()
_pybind11_add_lto_flags(${target_name} ${ARG_THIN_LTO}) if(CMAKE_VERSION VERSION_LESS 3.9 OR PYBIND11_CLASSIC_LTO)
_pybind11_add_lto_flags(${target_name} ${ARG_THIN_LTO})
else()
include(CheckIPOSupported)
check_ipo_supported(RESULT supported OUTPUT error)
if(supported)
set_property(
TARGET
${target_name}
PROPERTY
INTERPROCEDURAL_OPTIMIZATION TRUE
)
endif()
endif()
if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo) if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
# Strip unnecessary sections of the binary on Linux/Mac OS # Strip unnecessary sections of the binary on Linux/Mac OS