mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 06:35:12 +00:00
feat: new FindPython support (#2370)
* feat: FindPython support * refactor: rename to PYBIND11_FINDPYTHON * docs: Caps fixes * feat: NOPYTHON mode * test: check simple call * docs: add changelog/upgrade guide * feat: Support Python3 and Python2 * refactor: Use targets in tests * fix: support CMake 3.4+ * feat: classic search also finds virtual environments * docs: some updates from @wjakob's review * fix: wrong name for QUIET mode variable, reported by @skoslowski * refactor: cleaner output messaging * fix: support debug Python's in FindPython mode too * fixup! refactor: cleaner output messaging * fix: missing pybind11_FOUND and pybind11_INCLUDE_DIR restored to subdir mode * fix: nicer reporting of Python / PyPy * fix: out-of-order variable fix * docs: minor last-minute cleanup
This commit is contained in:
parent
69821d9e75
commit
1729aae96f
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
@ -31,11 +31,13 @@ jobs:
|
||||
arch: x64
|
||||
max-cxx-std: 17
|
||||
dev: false
|
||||
args: "-DPYBIND11_FINDPYTHON=ON"
|
||||
- runs-on: macos-latest
|
||||
python: 3.7
|
||||
arch: x64
|
||||
max-cxx-std: 17
|
||||
dev: false
|
||||
args: "-DPYBIND11_FINDPYTHON=ON"
|
||||
- runs-on: windows-2016
|
||||
python: 3.7
|
||||
arch: x86
|
||||
@ -46,6 +48,7 @@ jobs:
|
||||
arch: x64
|
||||
max-cxx-std: 17
|
||||
dev: false
|
||||
args: "-DPYBIND11_FINDPYTHON=ON"
|
||||
- runs-on: windows-latest
|
||||
python: 3.7
|
||||
arch: x64
|
||||
@ -89,7 +92,7 @@ jobs:
|
||||
dev: false
|
||||
|
||||
|
||||
name: "🐍 ${{ matrix.python }} • ${{ matrix.runs-on }} • ${{ matrix.arch }}"
|
||||
name: "🐍 ${{ matrix.python }} • ${{ matrix.runs-on }} • ${{ matrix.arch }} ${{ matrix.args }}"
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
continue-on-error: ${{ matrix.dev }}
|
||||
|
||||
@ -106,6 +109,9 @@ jobs:
|
||||
if: runner.os != 'macOS'
|
||||
run: echo "::set-env name=BOOST_ROOT::$BOOST_ROOT_1_72_0"
|
||||
|
||||
- name: Update CMake
|
||||
uses: jwlawson/actions-setup-cmake@v1.3
|
||||
|
||||
- name: Cache wheels
|
||||
if: runner.os == 'macOS'
|
||||
uses: actions/cache@v2
|
||||
@ -120,7 +126,7 @@ jobs:
|
||||
- name: Prepare env
|
||||
run: python -m pip install -r tests/requirements.txt
|
||||
|
||||
- name: Configure C++11
|
||||
- name: Configure C++11 ${{ matrix.args }}
|
||||
shell: bash
|
||||
run: >
|
||||
cmake -S . -B build
|
||||
@ -128,7 +134,7 @@ jobs:
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DDOWNLOAD_EIGEN=ON
|
||||
-DCMAKE_CXX_STANDARD=11
|
||||
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
|
||||
${{ matrix.args }}
|
||||
|
||||
- name: Build C++11
|
||||
run: cmake --build build -j 2
|
||||
@ -140,9 +146,9 @@ jobs:
|
||||
run: cmake --build build --target cpptest -j 2
|
||||
|
||||
- name: Interface test C++11
|
||||
run: cmake --build build --target test_cmake_build
|
||||
run: cmake --build build --target test_cmake_build -v
|
||||
|
||||
- name: Configure C++${{ matrix.max-cxx-std }}
|
||||
- name: Configure C++${{ matrix.max-cxx-std }} ${{ matrix.args }}
|
||||
shell: bash
|
||||
run: >
|
||||
cmake -S . -B build2
|
||||
@ -150,7 +156,7 @@ jobs:
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DDOWNLOAD_EIGEN=ON
|
||||
-DCMAKE_CXX_STANDARD=${{ matrix.max-cxx-std }}
|
||||
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
|
||||
${{ matrix.args }}
|
||||
|
||||
- name: Build C++${{ matrix.max-cxx-std }}
|
||||
run: cmake --build build2 -j 2
|
||||
@ -350,14 +356,14 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install requirements
|
||||
- name: Install system requirements
|
||||
run: apk add doxygen python3-dev
|
||||
|
||||
- name: Ensure pip
|
||||
run: python3 -m ensurepip
|
||||
|
||||
- name: Install python docs requirements
|
||||
run: python3 -m pip install "sphinx<3" sphinx_rtd_theme breathe==4.13.1 pytest setuptools
|
||||
- name: Install docs & setup requirements
|
||||
run: python3 -m pip install -r docs/requirements.txt pytest setuptools
|
||||
|
||||
- name: Build docs
|
||||
run: python3 -m sphinx -W -b html docs docs/.build
|
||||
|
25
.github/workflows/configure.yml
vendored
25
.github/workflows/configure.yml
vendored
@ -14,19 +14,22 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runs-on: [ubuntu-latest, macos-latest]
|
||||
runs-on: [ubuntu-latest, macos-latest, windows-latest]
|
||||
arch: [x64]
|
||||
cmake: [3.7, 3.18]
|
||||
cmake: [3.18]
|
||||
|
||||
include:
|
||||
- runs-on: windows-latest
|
||||
- runs-on: ubuntu-latest
|
||||
arch: x64
|
||||
cmake: 3.18
|
||||
cmake: 3.4
|
||||
|
||||
- runs-on: macos-latest
|
||||
arch: x64
|
||||
cmake: 3.7
|
||||
|
||||
# TODO: 3.8
|
||||
- runs-on: windows-2016
|
||||
arch: x86
|
||||
cmake: 3.11
|
||||
cmake: 3.8
|
||||
|
||||
- runs-on: windows-2016
|
||||
arch: x86
|
||||
@ -63,3 +66,13 @@ jobs:
|
||||
-DPYBIND11_WERROR=ON
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
|
||||
|
||||
- name: Build
|
||||
working-directory: build dir
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: cmake --build . --config Release
|
||||
|
||||
- name: Test
|
||||
working-directory: build dir
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: cmake --build . --config Release --target check
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -32,7 +32,7 @@ MANIFEST
|
||||
.*.swp
|
||||
.DS_Store
|
||||
/dist
|
||||
/build
|
||||
/build*
|
||||
.cache/
|
||||
sosize-*.txt
|
||||
pybind11Config*.cmake
|
||||
|
157
CMakeLists.txt
157
CMakeLists.txt
@ -5,9 +5,9 @@
|
||||
# All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.7...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
@ -41,11 +41,22 @@ include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
|
||||
if(NOT pybind11_FIND_QUIETLY)
|
||||
message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
|
||||
endif()
|
||||
|
||||
# Check if pybind11 is being used directly or via add_subdirectory
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(PYBIND11_MASTER_PROJECT ON)
|
||||
|
||||
if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
|
||||
# Bug in macOS CMake < 3.7 is unable to download catch
|
||||
message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
|
||||
elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)
|
||||
# Only tested with 3.8+ in CI.
|
||||
message(WARNING "CMAKE 3.8+ tested on Windows, previous versions untested")
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake ${CMAKE_VERSION}")
|
||||
|
||||
if(CMAKE_CXX_STANDARD)
|
||||
@ -60,13 +71,16 @@ endif()
|
||||
# Options
|
||||
option(PYBIND11_INSTALL "Install pybind11 header files?" ${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)
|
||||
option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
|
||||
|
||||
cmake_dependent_option(
|
||||
USE_PYTHON_INCLUDE_DIR
|
||||
"Install pybind11 headers in Python include directory instead of default installation prefix"
|
||||
OFF "PYBIND11_INSTALL" OFF)
|
||||
|
||||
cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" OFF
|
||||
"NOT CMAKE_VERSION VERSION_LESS 3.12" OFF)
|
||||
|
||||
# NB: when adding a header don't forget to also add it to setup.py
|
||||
set(PYBIND11_HEADERS
|
||||
include/pybind11/detail/class.h
|
||||
@ -118,101 +132,41 @@ endif()
|
||||
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" PYBIND11_HEADERS
|
||||
"${PYBIND11_HEADERS}")
|
||||
|
||||
# Classic mode
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/tools/pybind11Tools.cmake")
|
||||
|
||||
# Cache variables so pybind11_add_module can be used in parent projects
|
||||
set(PYBIND11_INCLUDE_DIR
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include"
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_INCLUDE_DIRS
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_LIBRARIES
|
||||
${PYTHON_LIBRARIES}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_MODULE_PREFIX
|
||||
${PYTHON_MODULE_PREFIX}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_MODULE_EXTENSION
|
||||
${PYTHON_MODULE_EXTENSION}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_VERSION_MAJOR
|
||||
${PYTHON_VERSION_MAJOR}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_VERSION_MINOR
|
||||
${PYTHON_VERSION_MINOR}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_IS_DEBUG
|
||||
"${PYTHON_IS_DEBUG}"
|
||||
CACHE INTERNAL "")
|
||||
|
||||
if(USE_PYTHON_INCLUDE_DIR)
|
||||
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Note: when creating targets, you cannot use if statements at configure time -
|
||||
# you need generator expressions, because those will be placed in the target file.
|
||||
# You can also place ifs *in* the Config.in, but not here.
|
||||
|
||||
# Build an interface library target:
|
||||
add_library(pybind11 INTERFACE)
|
||||
add_library(pybind11::pybind11 ALIAS pybind11) # to match exported target
|
||||
# This section builds targets, but does *not* touch Python
|
||||
|
||||
# Build the headers-only target (no Python included):
|
||||
add_library(headers INTERFACE)
|
||||
add_library(pybind11::headers ALIAS headers) # to match exported target
|
||||
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
|
||||
|
||||
if(NOT PYBIND11_MASTER_PROJECT AND NOT pybind11_FIND_QUIETLY)
|
||||
message(STATUS "Using pybind11: (version \"${pybind11_VERSION}\" ${pybind11_VERSION_TYPE})")
|
||||
endif()
|
||||
|
||||
# Relative directory setting
|
||||
if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
|
||||
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})
|
||||
elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
|
||||
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Fill in headers target
|
||||
target_include_directories(
|
||||
pybind11 ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${PYBIND11_INCLUDE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
# 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}>)
|
||||
headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${PYBIND11_INCLUDE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
target_compile_features(pybind11 INTERFACE cxx_inheriting_constructors cxx_user_literals
|
||||
cxx_right_angle_brackets)
|
||||
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 only 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()
|
||||
|
||||
add_library(module INTERFACE)
|
||||
add_library(pybind11::module ALIAS module)
|
||||
|
||||
target_link_libraries(module INTERFACE pybind11::pybind11)
|
||||
|
||||
# See https://github.com/Kitware/CMake/blob/master/Modules/CMakePlatformId.h.in for platform IDs
|
||||
# Note: CMake 3.15 allows $<PLATFORM_ID:Windows,Cygwin>
|
||||
target_link_libraries(
|
||||
module
|
||||
INTERFACE
|
||||
"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>")
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
target_link_libraries(module INTERFACE "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
|
||||
else()
|
||||
# SHELL (3.12+) forces this to remain together, and link_options was added in 3.13+
|
||||
# This is safer, because you are ensured the deduplication pass in CMake will not consider
|
||||
# these separate and remove one but not the other.
|
||||
target_link_options(module INTERFACE "$<$<PLATFORM_ID:Darwin>:SHELL:-undefined dynamic_lookup>")
|
||||
endif()
|
||||
|
||||
# Workaround for Python 2.7 and C++17 (C++14 as a warning) incompatibility
|
||||
# This adds the flags -Wno-register and -Wno-deprecated-register if the compiler
|
||||
# is Clang 3.9+ or AppleClang and the compile language is CXX, or /wd5033 for MSVC (all languages,
|
||||
# since MSVC didn't recognize COMPILE_LANGUAGE until CMake 3.11+).
|
||||
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>>")
|
||||
set(cxx_no_register "$<AND:$<COMPILE_LANGUAGE:CXX>,${no_register}>")
|
||||
set(msvc "$<CXX_COMPILER_ID:MSVC>")
|
||||
target_compile_options(
|
||||
pybind11 INTERFACE "$<${cxx_no_register}:-Wno-register;-Wno-deprecated-register>"
|
||||
"$<${msvc}:/wd5033>")
|
||||
|
||||
add_library(embed INTERFACE)
|
||||
add_library(pybind11::embed ALIAS embed)
|
||||
target_link_libraries(embed INTERFACE pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
|
||||
target_compile_features(headers INTERFACE cxx_inheriting_constructors cxx_user_literals
|
||||
cxx_right_angle_brackets)
|
||||
|
||||
if(PYBIND11_INSTALL)
|
||||
install(DIRECTORY ${PYBIND11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
@ -248,14 +202,17 @@ if(PYBIND11_INSTALL)
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
||||
tools/FindPythonLibsNew.cmake tools/pybind11Tools.cmake
|
||||
tools/FindPythonLibsNew.cmake
|
||||
tools/pybind11Common.cmake
|
||||
tools/pybind11Tools.cmake
|
||||
tools/pybind11NewTools.cmake
|
||||
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
||||
|
||||
if(NOT PYBIND11_EXPORT_NAME)
|
||||
set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets")
|
||||
endif()
|
||||
|
||||
install(TARGETS pybind11 module embed EXPORT "${PYBIND11_EXPORT_NAME}")
|
||||
install(TARGETS headers EXPORT "${PYBIND11_EXPORT_NAME}")
|
||||
|
||||
install(
|
||||
EXPORT "${PYBIND11_EXPORT_NAME}"
|
||||
@ -275,10 +232,28 @@ endif()
|
||||
# BUILD_TESTING takes priority, but only if this is the master project
|
||||
if(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
if(_pybind11_nopython)
|
||||
message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
|
||||
else()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
if(PYBIND11_TEST)
|
||||
add_subdirectory(tests)
|
||||
if(_pybind11_nopython)
|
||||
message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
|
||||
else()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Better symmetry with find_package(pybind11 CONFIG) mode.
|
||||
if(NOT PYBIND11_MASTER_PROJECT)
|
||||
set(pybind11_FOUND
|
||||
TRUE
|
||||
CACHE INTERNAL "true if pybind11 and all required components found on the system")
|
||||
set(pybind11_INCLUDE_DIR
|
||||
"${PYBIND11_INCLUDE_DIR}"
|
||||
CACHE INTERNAL "Directory where pybind11 headers are located")
|
||||
endif()
|
||||
|
@ -18,7 +18,7 @@ information, see :doc:`/compiling`.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
project(example)
|
||||
|
||||
find_package(pybind11 REQUIRED) # or `add_subdirectory(pybind11)`
|
||||
|
@ -6,6 +6,39 @@ Changelog
|
||||
Starting with version 1.8.0, pybind11 releases use a `semantic versioning
|
||||
<http://semver.org>`_ policy.
|
||||
|
||||
v2.6.0 (IN PROGRESS)
|
||||
--------------------
|
||||
|
||||
See :ref:`upgrade-guide-2.6` for help upgrading to the new version.
|
||||
|
||||
* Minimum CMake required increased to 3.4.
|
||||
`#2338 <https://github.com/pybind/pybind11/pull/2338>`_ and
|
||||
`#2370 <https://github.com/pybind/pybind11/pull/2370>`_
|
||||
|
||||
* Full integration with CMake’s C++ standard system replaces
|
||||
``PYBIND11_CPP_STANDARD``.
|
||||
|
||||
* Generated config file is now portable to different Python/compiler/CMake
|
||||
versions.
|
||||
|
||||
* Virtual environments prioritized if ``PYTHON_EXECUTABLE`` is not set
|
||||
(``venv``, ``virtualenv``, and ``conda``) (similar to the new FindPython
|
||||
mode).
|
||||
|
||||
* Other CMake features now natively supported, like
|
||||
``CMAKE_INTERPROCEDURAL_OPTIMIZATION``, ``set(CMAKE_CXX_VISIBILITY_PRESET
|
||||
hidden)``.
|
||||
|
||||
* Optional :ref:`find-python-mode` and :ref:`nopython-mode` with CMake.
|
||||
`#2370 <https://github.com/pybind/pybind11/pull/2370>`_
|
||||
|
||||
* Uninstall target added.
|
||||
`#2265 <https://github.com/pybind/pybind11/pull/2265>`_ and
|
||||
`#2346 <https://github.com/pybind/pybind11/pull/2346>`_
|
||||
|
||||
|
||||
|
||||
|
||||
v2.5.0 (Mar 31, 2020)
|
||||
-----------------------------------------------------
|
||||
|
||||
|
@ -33,8 +33,8 @@ extension module can be created with just a few lines of code:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(example)
|
||||
cmake_minimum_required(VERSION 3.4...3.18)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
add_subdirectory(pybind11)
|
||||
pybind11_add_module(example example.cpp)
|
||||
@ -50,6 +50,9 @@ PyPI integration, can be found in the [cmake_example]_ repository.
|
||||
|
||||
.. [cmake_example] https://github.com/pybind/cmake_example
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
CMake 3.4+ is required.
|
||||
|
||||
pybind11_add_module
|
||||
-------------------
|
||||
|
||||
@ -89,7 +92,9 @@ will result in code bloat and is generally not recommended.
|
||||
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
|
||||
the function to prefer this flavor if available. The function falls back to
|
||||
regular LTO if ``-flto=thin`` is not available.
|
||||
regular LTO if ``-flto=thin`` is not available. If
|
||||
``CMAKE_INTERPROCEDURAL_OPTIMIZATION`` is set (either ON or OFF), then that
|
||||
will be respected instead of the built-in flag search.
|
||||
|
||||
.. _ThinLTO: http://clang.llvm.org/docs/ThinLTO.html
|
||||
|
||||
@ -113,9 +118,9 @@ the ``-D<variable>=<value>`` flag. You can also manually set ``CXX_STANDARD``
|
||||
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``
|
||||
or an exact Python installation can be specified with ``PYTHON_EXECUTABLE``.
|
||||
For example:
|
||||
Classic Python support: The target Python version can be selected by setting
|
||||
``PYBIND11_PYTHON_VERSION`` or an exact Python installation can be specified
|
||||
with ``PYTHON_EXECUTABLE``. For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@ -127,6 +132,7 @@ For example:
|
||||
# This often is a good way to get the current Python, works in environments:
|
||||
cmake -DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") ..
|
||||
|
||||
|
||||
find_package vs. add_subdirectory
|
||||
---------------------------------
|
||||
|
||||
@ -136,8 +142,8 @@ See the `Config file`_ docstring for details of relevant CMake variables.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(example)
|
||||
cmake_minimum_required(VERSION 3.4...3.18)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
find_package(pybind11 REQUIRED)
|
||||
pybind11_add_module(example example.cpp)
|
||||
@ -169,52 +175,131 @@ can refer to the same [cmake_example]_ repository for a full sample project
|
||||
|
||||
.. _Config file: https://github.com/pybind/pybind11/blob/master/tools/pybind11Config.cmake.in
|
||||
|
||||
Advanced: interface library target
|
||||
----------------------------------
|
||||
|
||||
When using a version of CMake greater than 3.0, pybind11 can additionally
|
||||
be used as a special *interface library* . The target ``pybind11::module``
|
||||
is available with pybind11 headers, Python headers and libraries as needed,
|
||||
and C++ compile features attached. This target is suitable for linking
|
||||
to an independently constructed (through ``add_library``, not
|
||||
``pybind11_add_module``) target in the consuming project.
|
||||
.. _find-python-mode:
|
||||
|
||||
FindPython mode
|
||||
---------------
|
||||
|
||||
CMake 3.12+ (3.15+ recommended) added a new module called FindPython that had a
|
||||
highly improved search algorithm and modern targets and tools. If you use
|
||||
FindPython, pybind11 will detect this and use the existing targets instead:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(example)
|
||||
cmake_minumum_required(VERSION 3.15...3.18)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
find_package(Python COMPONENTS Interpreter Development REQUIRED)
|
||||
find_package(pybind11 CONFIG REQUIRED)
|
||||
# or add_subdirectory(pybind11)
|
||||
|
||||
pybind11_add_module(example example.cpp)
|
||||
|
||||
You can also use the targets (as listed below) with FindPython. If you define
|
||||
``PYBIND11_FINDPYTHON``, pybind11 will perform the FindPython step for you
|
||||
(mostly useful when building pybind11's own tests, or as a way to change search
|
||||
algorithms from the CMake invocation, with ``-DPYBIND11_FINDPYTHON=ON``.
|
||||
|
||||
.. warning::
|
||||
|
||||
If you use FindPython2 and FindPython3 to dual-target Python, use the
|
||||
individual targets listed below, and avoid targets that directly include
|
||||
Python parts.
|
||||
|
||||
There are `many ways to hint or force a discovery of a specific Python
|
||||
installation <https://cmake.org/cmake/help/latest/module/FindPython.html>`_),
|
||||
setting ``Python_ROOT_DIR`` may be the most common one (though with
|
||||
virtualenv/venv support, and Conda support, this tends to find the correct
|
||||
Python version more often than the old system did).
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
Advanced: interface library targets
|
||||
-----------------------------------
|
||||
|
||||
Pybind11 supports modern CMake usage patterns with a set of interface targets,
|
||||
available in all modes. The targets provided are:
|
||||
|
||||
``pybind11::headers``
|
||||
Just the pybind11 headers and minimum compile requirements
|
||||
|
||||
``pybind11::python2_no_register``
|
||||
Quiets the warning/error when mixing C++14 or higher and Python 2
|
||||
|
||||
``pybind11::pybind11``
|
||||
Python headers + ``pybind11::headers`` + ``pybind11::python2_no_register`` (Python 2 only)
|
||||
|
||||
``pybind11::python_link_helper``
|
||||
Just the "linking" part of pybind11:module
|
||||
|
||||
``pybind11::module``
|
||||
Everything for extension modules - ``pybind11::pybind11`` + ``Python::Module`` (FindPython CMake 3.15+) or ``pybind11::python_link_helper``
|
||||
|
||||
``pybind11::embed``
|
||||
Everything for embedding the Python interpreter - ``pybind11::pybind11`` + ``Python::Embed`` (FindPython) or Python libs
|
||||
|
||||
``pybind11::lto`` / ``pybind11::thin_lto``
|
||||
An alternative to `INTERPROCEDURAL_OPTIMIZATION` for adding link-time optimization.
|
||||
|
||||
``pybind11::windows_extras``
|
||||
``/bigobj`` and ``/mp`` for MSVC.
|
||||
|
||||
Two helper functions are also provided:
|
||||
|
||||
``pybind11_strip(target)``
|
||||
Strips a target (uses ``CMAKE_STRIP`` after the target is built)
|
||||
|
||||
``pybind11_extension(target)``
|
||||
Sets the correct extension (with SOABI) for a target.
|
||||
|
||||
You can use these targets to build complex applications. For example, the
|
||||
``add_python_module`` function is identical to:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
find_package(pybind11 REQUIRED) # or add_subdirectory(pybind11)
|
||||
|
||||
add_library(example MODULE main.cpp)
|
||||
target_link_libraries(example PRIVATE pybind11::module)
|
||||
set_target_properties(example PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
|
||||
SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
||||
|
||||
target_link_libraries(example PRIVATE pybind11::module pybind11::lto pybind11::windows_extras)
|
||||
|
||||
pybind11_extension(example)
|
||||
pybind11_strip(example)
|
||||
|
||||
set_target_properties(example PROPERTIES CXX_VISIBILITY_PRESET "hidden"
|
||||
CUDA_VISIBILITY_PRESET "hidden")
|
||||
|
||||
Instead of setting properties, you can set ``CMAKE_*`` variables to initialize these correctly.
|
||||
|
||||
.. 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).
|
||||
provides a *composable* set of targets to ensure that you retain flexibility.
|
||||
It can be expecially important to provide or set these properties; the
|
||||
:ref:`FAQ <faq:symhidden>` contains an explanation on why these are needed.
|
||||
|
||||
These include Link Time Optimization (``-flto`` on GCC/Clang/ICPC, ``/GL``
|
||||
and ``/LTCG`` on Visual Studio) and .OBJ files with many sections on Visual
|
||||
Studio (``/bigobj``). The :ref:`FAQ <faq:symhidden>` contains an
|
||||
explanation on why these are needed.
|
||||
.. versionadded:: 2.6
|
||||
|
||||
If you want to add these in yourself, you can use:
|
||||
.. _nopython-mode:
|
||||
|
||||
.. code-block:: cmake
|
||||
Advanced: NOPYTHON mode
|
||||
-----------------------
|
||||
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) # CMake 3.9+ required
|
||||
If you want complete control, you can set ``PYBIND11_NOPYTHON`` to completely
|
||||
disable Python integration (this also happens if you run ``FindPython2`` and
|
||||
``FindPython3`` without running ``FindPython``). This gives you complete
|
||||
freedom to integrate into an existing system (like `Scikit-Build's
|
||||
<https://scikit-build.readthedocs.io>`_ ``PythonExtensions``).
|
||||
``pybind11_add_module`` and ``pybind11_extension`` will be unavailable, and the
|
||||
targets will be missing any Python specific behavior.
|
||||
|
||||
or set the corresponding property (without the ``CMAKE_``) on the targets
|
||||
manually.
|
||||
.. versionadded:: 2.6
|
||||
|
||||
Embedding the Python interpreter
|
||||
--------------------------------
|
||||
@ -228,8 +313,8 @@ information about usage in C++, see :doc:`/advanced/embedding`.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(example)
|
||||
cmake_minimum_required(VERSION 3.4...3.18)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
find_package(pybind11 REQUIRED) # or add_subdirectory(pybind11)
|
||||
|
||||
|
@ -1 +1,3 @@
|
||||
breathe == 4.5.0
|
||||
breathe==4.13.1
|
||||
sphinx<3
|
||||
sphinx_rtd_theme
|
||||
|
@ -8,6 +8,53 @@ to a new version. But it goes into more detail. This includes things like
|
||||
deprecated APIs and their replacements, build system changes, general code
|
||||
modernization and other useful information.
|
||||
|
||||
.. _upgrade-guide-2.6:
|
||||
|
||||
v2.6
|
||||
====
|
||||
|
||||
CMake support:
|
||||
--------------
|
||||
|
||||
The minimum required version of CMake is now 3.4. Several details of the CMake
|
||||
support have been deprecated; warnings will be shown if you need to change
|
||||
something. The changes are:
|
||||
|
||||
* ``PYBIND11_CPP_STANDARD=<platform-flag>`` is deprecated, please use
|
||||
``CMAKE_CXX_STANDARD=<number>`` instead, or any other valid CMake CXX or CUDA
|
||||
standard selection method, like ``target_compile_features``.
|
||||
|
||||
* If you do not request a standard, PyBind11 targets will compile with the
|
||||
compiler default, but not less than C++11, instead of forcing C++14 always.
|
||||
If you depend on the old behavior, please use ``set(CMAKE_CXX_STANDARD 14)``
|
||||
instead.
|
||||
|
||||
* Direct ``pybind11::module`` usage should always be accompanied by at least
|
||||
``set(CMAKE_CXX_VISIBILITY_PRESET hidden)`` or similar - it used to try to
|
||||
manually force this compiler flag (but not correctly on all compilers or with
|
||||
CUDA).
|
||||
|
||||
* ``pybind11_add_module``'s ``SYSTEM`` argument is deprecated and does nothing;
|
||||
linking now behaves like other imported libraries consistently in both
|
||||
config and submodule mode, and behaves like a ``SYSTEM`` library by
|
||||
default.
|
||||
|
||||
* If ``PYTHON_EXECUTABLE`` is not set, virtual environments (``venv``,
|
||||
``virtualenv``, and ``conda``) are prioritized over the standard search
|
||||
(similar to the new FindPython mode).
|
||||
|
||||
In addition, the following changes may be of interest:
|
||||
|
||||
* ``CMAKE_INTERPROCEDURAL_OPTIMIZATION`` will be respected by
|
||||
``pybind11_add_module`` if set instead of linking to ``pybind11::lto`` or
|
||||
``pybind11::thin_lto``.
|
||||
|
||||
* Using ``find_package(Python COMPONENTS Interpreter Development)`` before
|
||||
pybind11 will cause pybind11 to use the new Python mechanisms instead of its
|
||||
own custom search, based on a patched version of classic
|
||||
FindPythonInterp/FindPythonLibs. In the future, this may become the default.
|
||||
|
||||
|
||||
|
||||
v2.2
|
||||
====
|
||||
|
@ -5,9 +5,9 @@
|
||||
# All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.7...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
@ -16,6 +16,12 @@ else()
|
||||
cmake_policy(VERSION 3.18)
|
||||
endif()
|
||||
|
||||
# New Python support
|
||||
if(DEFINED Python_EXECUTABLE)
|
||||
set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}")
|
||||
set(PYTHON_VERSION "${Python_VERSION}")
|
||||
endif()
|
||||
|
||||
# There's no harm in including a project in a project
|
||||
project(pybind11_tests CXX)
|
||||
|
||||
@ -137,13 +143,9 @@ if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)
|
||||
|
||||
set(EIGEN3_INCLUDE_DIR ${eigen_SOURCE_DIR})
|
||||
set(EIGEN3_FOUND TRUE)
|
||||
|
||||
else()
|
||||
find_package(Eigen3 3.2.7 QUIET CONFIG)
|
||||
if(EIGEN3_FOUND)
|
||||
if(EIGEN3_VERSION_STRING AND NOT EIGEN3_VERSION_STRING VERSION_LESS 3.3.1)
|
||||
set(PYBIND11_EIGEN_VIA_TARGET TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT EIGEN3_FOUND)
|
||||
# Couldn't load via target, so fall back to allowing module mode finding, which will pick up
|
||||
@ -153,6 +155,12 @@ if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)
|
||||
endif()
|
||||
|
||||
if(EIGEN3_FOUND)
|
||||
if(NOT TARGET Eigen3::Eigen)
|
||||
add_library(Eigen3::Eigen IMPORTED INTERFACE)
|
||||
set_property(TARGET Eigen3::Eigen PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${EIGEN3_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
# Eigen 3.3.1+ cmake sets EIGEN3_VERSION_STRING (and hard codes the version when installed
|
||||
# rather than looking it up in the cmake script); older versions, and the
|
||||
# tools/FindEigen3.cmake, set EIGEN3_VERSION instead.
|
||||
@ -169,6 +177,20 @@ endif()
|
||||
# Optional dependency for some tests (boost::variant is only supported with version >= 1.56)
|
||||
find_package(Boost 1.56)
|
||||
|
||||
if(Boost_FOUND)
|
||||
if(NOT TARGET Boost::headers)
|
||||
if(TARGET Boost::boost)
|
||||
# Classic FindBoost
|
||||
add_library(Boost::headers ALIAS Boost::boost)
|
||||
else()
|
||||
# Very old FindBoost, or newer Boost than CMake in older CMakes
|
||||
add_library(Boost::headers IMPORTED INTERFACE)
|
||||
set_property(TARGET Boost::headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
||||
${Boost_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Compile with compiler warnings turned on
|
||||
function(pybind11_enable_warnings target_name)
|
||||
if(MSVC)
|
||||
@ -233,16 +255,12 @@ foreach(target ${test_targets})
|
||||
endif()
|
||||
|
||||
if(EIGEN3_FOUND)
|
||||
if(PYBIND11_EIGEN_VIA_TARGET)
|
||||
target_link_libraries(${target} PRIVATE Eigen3::Eigen)
|
||||
else()
|
||||
target_include_directories(${target} SYSTEM PRIVATE ${EIGEN3_INCLUDE_DIR})
|
||||
endif()
|
||||
target_link_libraries(${target} PRIVATE Eigen3::Eigen)
|
||||
target_compile_definitions(${target} PRIVATE -DPYBIND11_TEST_EIGEN)
|
||||
endif()
|
||||
|
||||
if(Boost_FOUND)
|
||||
target_include_directories(${target} SYSTEM PRIVATE ${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(${target} PRIVATE Boost::headers)
|
||||
target_compile_definitions(${target} PRIVATE -DPYBIND11_TEST_BOOST)
|
||||
endif()
|
||||
|
||||
|
@ -1,12 +1,24 @@
|
||||
# Built-in in CMake 3.5+
|
||||
include(CMakeParseArguments)
|
||||
|
||||
add_custom_target(test_cmake_build)
|
||||
|
||||
function(pybind11_add_build_test name)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 ARG "INSTALL" "" "")
|
||||
cmake_parse_arguments(ARG "INSTALL" "" "" ${ARGN})
|
||||
|
||||
set(build_options
|
||||
"-DCMAKE_PREFIX_PATH=${pybind11_BINARY_DIR}/mock_install"
|
||||
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
|
||||
"-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}")
|
||||
set(build_options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
|
||||
|
||||
if(PYBIND11_FINDPYTHON)
|
||||
list(APPEND build_options "-DPYBIND11_FINDPYTHON=${PYBIND11_FINDPYTHON}")
|
||||
|
||||
if(DEFINED Python_ROOT_DIR)
|
||||
list(APPEND build_options "-DPython_ROOT_DIR=${Python_ROOT_DIR}")
|
||||
endif()
|
||||
|
||||
list(APPEND build_options "-DPython_EXECUTABLE=${Python_EXECUTABLE}")
|
||||
else()
|
||||
list(APPEND build_options "-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}")
|
||||
endif()
|
||||
|
||||
if(DEFINED CMAKE_CXX_STANDARD)
|
||||
list(APPEND build_options "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
|
||||
@ -45,7 +57,9 @@ endfunction()
|
||||
|
||||
pybind11_add_build_test(subdirectory_function)
|
||||
pybind11_add_build_test(subdirectory_target)
|
||||
if(NOT ${PYTHON_MODULE_EXTENSION} MATCHES "pypy")
|
||||
if("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy")
|
||||
message(STATUS "Skipping embed test on PyPy")
|
||||
else()
|
||||
pybind11_add_build_test(subdirectory_embed)
|
||||
endif()
|
||||
|
||||
@ -56,7 +70,8 @@ if(PYBIND11_INSTALL)
|
||||
|
||||
pybind11_add_build_test(installed_function INSTALL)
|
||||
pybind11_add_build_test(installed_target INSTALL)
|
||||
if(NOT ${PYTHON_MODULE_EXTENSION} MATCHES "pypy")
|
||||
if(NOT ("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy"
|
||||
))
|
||||
pybind11_add_build_test(installed_embed INSTALL)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.7...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
|
@ -1,6 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
project(test_installed_module CXX)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.7...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
@ -18,12 +19,20 @@ message(
|
||||
pybind11_add_module(test_installed_function SHARED NO_EXTRAS ../main.cpp)
|
||||
set_target_properties(test_installed_function 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_installed_function
|
||||
${CMAKE_COMMAND}
|
||||
-E
|
||||
env
|
||||
PYTHONPATH=$<TARGET_FILE_DIR:test_installed_function>
|
||||
${PYTHON_EXECUTABLE}
|
||||
${_Python_EXECUTABLE}
|
||||
${PROJECT_SOURCE_DIR}/../test.py
|
||||
${PROJECT_NAME})
|
||||
|
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.7...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
@ -19,20 +19,27 @@ add_library(test_installed_target MODULE ../main.cpp)
|
||||
target_link_libraries(test_installed_target PRIVATE pybind11::module)
|
||||
set_target_properties(test_installed_target PROPERTIES OUTPUT_NAME test_cmake_build)
|
||||
|
||||
# make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib
|
||||
set_target_properties(test_installed_target PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
|
||||
SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
||||
# Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib
|
||||
pybind11_extension(test_installed_target)
|
||||
|
||||
# Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::module).
|
||||
# This may be needed to resolve header conflicts, e.g. between Python release and debug headers.
|
||||
set_target_properties(test_installed_target PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)
|
||||
|
||||
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_installed_target
|
||||
${CMAKE_COMMAND}
|
||||
-E
|
||||
env
|
||||
PYTHONPATH=$<TARGET_FILE_DIR:test_installed_target>
|
||||
${PYTHON_EXECUTABLE}
|
||||
${_Python_EXECUTABLE}
|
||||
${PROJECT_SOURCE_DIR}/../test.py
|
||||
${PROJECT_NAME})
|
||||
|
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.7...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
|
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.7...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
@ -12,15 +12,23 @@ endif()
|
||||
project(test_subdirectory_function CXX)
|
||||
|
||||
add_subdirectory("${PYBIND11_PROJECT_DIR}" pybind11)
|
||||
pybind11_add_module(test_subdirectory_function THIN_LTO ../main.cpp)
|
||||
pybind11_add_module(test_subdirectory_function ../main.cpp)
|
||||
set_target_properties(test_subdirectory_function 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_function
|
||||
${CMAKE_COMMAND}
|
||||
-E
|
||||
env
|
||||
PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_function>
|
||||
${PYTHON_EXECUTABLE}
|
||||
${_Python_EXECUTABLE}
|
||||
${PROJECT_SOURCE_DIR}/../test.py
|
||||
${PROJECT_NAME})
|
||||
|
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.7...3.18)` syntax does not work with
|
||||
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.18)
|
||||
@ -18,9 +18,16 @@ set_target_properties(test_subdirectory_target PROPERTIES OUTPUT_NAME test_cmake
|
||||
|
||||
target_link_libraries(test_subdirectory_target PRIVATE pybind11::module)
|
||||
|
||||
# make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib
|
||||
set_target_properties(test_subdirectory_target PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
|
||||
SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
||||
# Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib
|
||||
pybind11_extension(test_subdirectory_target)
|
||||
|
||||
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_target
|
||||
@ -28,6 +35,6 @@ add_custom_target(
|
||||
-E
|
||||
env
|
||||
PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_target>
|
||||
${PYTHON_EXECUTABLE}
|
||||
${_Python_EXECUTABLE}
|
||||
${PROJECT_SOURCE_DIR}/../test.py
|
||||
${PROJECT_NAME})
|
||||
|
@ -1,10 +1,11 @@
|
||||
if(${PYTHON_MODULE_EXTENSION} MATCHES "pypy")
|
||||
if("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy")
|
||||
add_custom_target(cpptest) # Dummy target on PyPy. Embedding is not supported.
|
||||
set(_suppress_unused_variable_warning "${DOWNLOAD_CATCH}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(Catch 2.13.0)
|
||||
|
||||
if(CATCH_FOUND)
|
||||
message(STATUS "Building interpreter tests using Catch v${CATCH_VERSION}")
|
||||
else()
|
||||
@ -13,14 +14,12 @@ else()
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
add_executable(test_embed catch.cpp test_interpreter.cpp)
|
||||
target_include_directories(test_embed SYSTEM PRIVATE "${CATCH_INCLUDE_DIR}")
|
||||
pybind11_enable_warnings(test_embed)
|
||||
|
||||
target_link_libraries(test_embed PRIVATE pybind11::embed)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(test_embed PUBLIC Threads::Threads)
|
||||
target_link_libraries(test_embed PRIVATE pybind11::embed Catch2::Catch2 Threads::Threads)
|
||||
|
||||
add_custom_target(
|
||||
cpptest
|
||||
|
@ -64,4 +64,7 @@ if(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(Catch2::Catch2 IMPORTED INTERFACE)
|
||||
set_property(TARGET Catch2::Catch2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CATCH_INCLUDE_DIR}")
|
||||
|
||||
set(CATCH_FOUND TRUE)
|
||||
|
@ -55,15 +55,46 @@ if(PYTHONLIBS_FOUND AND PYTHON_MODULE_EXTENSION)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(PythonLibsNew_FIND_QUIETLY)
|
||||
set(_pythonlibs_quiet QUIET)
|
||||
endif()
|
||||
|
||||
if(PythonLibsNew_FIND_REQUIRED)
|
||||
set(_pythonlibs_required REQUIRED)
|
||||
endif()
|
||||
|
||||
# Check to see if the `python` command is present and from a virtual
|
||||
# environment, conda, or GHA activation - if it is, try to use that.
|
||||
|
||||
if(NOT DEFINED PYTHON_EXECUTABLE)
|
||||
if(DEFINED ENV{VIRTUAL_ENV})
|
||||
find_program(
|
||||
PYTHON_EXECUTABLE python
|
||||
PATHS "$ENV{VIRTUAL_ENV}" "$ENV{VIRTUAL_ENV}/bin"
|
||||
NO_DEFAULT_PATH)
|
||||
elseif(DEFINED ENV{CONDA_PREFIX})
|
||||
find_program(
|
||||
PYTHON_EXECUTABLE python
|
||||
PATHS "$ENV{CONDA_PREFIX}" "$ENV{CONDA_PREFIX}/bin"
|
||||
NO_DEFAULT_PATH)
|
||||
elseif(DEFINED ENV{pythonLocation})
|
||||
find_program(
|
||||
PYTHON_EXECUTABLE python
|
||||
PATHS "$ENV{pythonLocation}" "$ENV{pythonLocation}/bin"
|
||||
NO_DEFAULT_PATH)
|
||||
endif()
|
||||
if(NOT PYTHON_EXECUTABLE)
|
||||
unset(PYTHON_EXECUTABLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Use the Python interpreter to find the libs.
|
||||
if(NOT PythonLibsNew_FIND_VERSION)
|
||||
set(PythonLibsNew_FIND_VERSION "")
|
||||
endif()
|
||||
if(PythonLibsNew_FIND_REQUIRED)
|
||||
find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} REQUIRED)
|
||||
else()
|
||||
find_package(PythonInterp ${PythonLibsNew_FIND_VERSION})
|
||||
endif()
|
||||
|
||||
find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} ${_pythonlibs_required}
|
||||
${_pythonlibs_quiet})
|
||||
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
set(PYTHONLIBS_FOUND FALSE)
|
||||
@ -71,7 +102,7 @@ if(NOT PYTHONINTERP_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# According to http://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter
|
||||
# According to https://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter
|
||||
# testing whether sys has the gettotalrefcount function is a reliable, cross-platform
|
||||
# way to detect a CPython debug interpreter.
|
||||
#
|
||||
|
296
tools/pybind11Common.cmake
Normal file
296
tools/pybind11Common.cmake
Normal file
@ -0,0 +1,296 @@
|
||||
#[======================================================[.rst
|
||||
|
||||
Adds the following targets::
|
||||
|
||||
pybind11::pybind11 - link to headers and pybind11
|
||||
pybind11::module - Adds module links
|
||||
pybind11::embed - Adds embed links
|
||||
pybind11::lto - Link time optimizations (manual selection)
|
||||
pybind11::thin_lto - Link time optimizations (manual selection)
|
||||
pybind11::python_link_helper - Adds link to Python libraries
|
||||
pybind11::python2_no_register - Avoid warning/error with Python 2 + C++14/7
|
||||
pybind11::windows_extras - MSVC bigobj and mp for building multithreaded
|
||||
|
||||
Adds the following functions::
|
||||
|
||||
pybind11_strip(target) - strip target after building on linux/macOS
|
||||
|
||||
|
||||
#]======================================================]
|
||||
|
||||
# CMake 3.10 has an include_guard command, but we can't use that yet
|
||||
if(TARGET pybind11::lto)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# If we are in subdirectory mode, all IMPORTED targets must be GLOBAL. If we
|
||||
# are in CONFIG mode, they should be "normal" targets instead.
|
||||
# In CMake 3.11+ you can promote a target to global after you create it,
|
||||
# which might be simpler than this check.
|
||||
get_property(
|
||||
is_config
|
||||
TARGET pybind11::headers
|
||||
PROPERTY IMPORTED)
|
||||
if(NOT is_config)
|
||||
set(optional_global GLOBAL)
|
||||
endif()
|
||||
|
||||
# --------------------- Shared targets ----------------------------
|
||||
|
||||
# Build an interface library target:
|
||||
add_library(pybind11::pybind11 IMPORTED INTERFACE ${optional_global})
|
||||
set_property(
|
||||
TARGET pybind11::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::headers)
|
||||
|
||||
# Build a module target:
|
||||
add_library(pybind11::module IMPORTED INTERFACE ${optional_global})
|
||||
set_property(
|
||||
TARGET pybind11::module
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
|
||||
|
||||
# Build an embed library target:
|
||||
add_library(pybind11::embed IMPORTED INTERFACE ${optional_global})
|
||||
set_property(
|
||||
TARGET pybind11::embed
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
|
||||
|
||||
# ----------------------- no register ----------------------
|
||||
|
||||
# Workaround for Python 2.7 and C++17 (C++14 as a warning) incompatibility
|
||||
# This adds the flags -Wno-register and -Wno-deprecated-register if the compiler
|
||||
# is Clang 3.9+ or AppleClang and the compile language is CXX, or /wd5033 for MSVC (all languages,
|
||||
# since MSVC didn't recognize COMPILE_LANGUAGE until CMake 3.11+).
|
||||
|
||||
add_library(pybind11::python2_no_register INTERFACE IMPORTED ${optional_global})
|
||||
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>>")
|
||||
|
||||
if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
|
||||
set(cxx_no_register "${no_register}")
|
||||
else()
|
||||
set(cxx_no_register "$<AND:$<COMPILE_LANGUAGE:CXX>,${no_register}>")
|
||||
endif()
|
||||
|
||||
set(msvc "$<CXX_COMPILER_ID:MSVC>")
|
||||
|
||||
set_property(
|
||||
TARGET pybind11::python2_no_register
|
||||
PROPERTY INTERFACE_COMPILE_OPTIONS
|
||||
"$<${cxx_no_register}:-Wno-register;-Wno-deprecated-register>" "$<${msvc}:/wd5033>")
|
||||
|
||||
# --------------------------- link helper ---------------------------
|
||||
|
||||
add_library(pybind11::python_link_helper IMPORTED INTERFACE ${optional_global})
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
# In CMake 3.11+, you can set INTERFACE properties via the normal methods, and
|
||||
# this would be simpler.
|
||||
set_property(
|
||||
TARGET pybind11::python_link_helper
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
|
||||
else()
|
||||
# link_options was added in 3.13+
|
||||
# This is safer, because you are ensured the deduplication pass in CMake will not consider
|
||||
# these separate and remove one but not the other.
|
||||
set_property(
|
||||
TARGET pybind11::python_link_helper
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_OPTIONS "$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup>")
|
||||
endif()
|
||||
|
||||
# ------------------------ Windows extras -------------------------
|
||||
|
||||
add_library(pybind11::windows_extras IMPORTED INTERFACE ${optional_global})
|
||||
|
||||
if(MSVC)
|
||||
# /MP enables multithreaded builds (relevant when there are many files), /bigobj is
|
||||
# needed for bigger binding projects due to the limit to 64k addressable sections
|
||||
set_property(
|
||||
TARGET pybind11::windows_extras
|
||||
APPEND
|
||||
PROPERTY INTERFACE_COMPILE_OPTIONS /bigobj)
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.11)
|
||||
set_property(
|
||||
TARGET pybind11::windows_extras
|
||||
APPEND
|
||||
PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:/MP>)
|
||||
else()
|
||||
# Only set these options for C++ files. This is important so that, for
|
||||
# instance, projects that include other types of source files like CUDA
|
||||
# .cu files don't get these options propagated to nvcc since that would
|
||||
# cause the build to fail.
|
||||
set_property(
|
||||
TARGET pybind11::windows_extras
|
||||
APPEND
|
||||
PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:$<$<COMPILE_LANGUAGE:CXX>:/MP>>)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ----------------------- Legacy option --------------------------
|
||||
|
||||
# Warn or error if old variable name used
|
||||
if(PYBIND11_CPP_STANDARD)
|
||||
string(REGEX MATCH [[..$]] VAL "${PYBIND11_CPP_STANDARD}")
|
||||
if(CMAKE_CXX_STANDARD)
|
||||
if(NOT CMAKE_CXX_STANDARD STREQUAL VAL)
|
||||
message(WARNING "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} does not match "
|
||||
"PYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}, "
|
||||
"please remove PYBIND11_CPP_STANDARD from your cache")
|
||||
endif()
|
||||
else()
|
||||
set(supported_standards 11 14 17 20)
|
||||
if("${VAL}" IN_LIST supported_standards)
|
||||
message(WARNING "USE -DCMAKE_CXX_STANDARD=${VAL} instead of PYBIND11_PYTHON_VERSION")
|
||||
set(CMAKE_CXX_STANDARD
|
||||
${VAL}
|
||||
CACHE STRING "From PYBIND11_CPP_STANDARD")
|
||||
else()
|
||||
message(FATAL_ERROR "PYBIND11_CPP_STANDARD should be replaced with CMAKE_CXX_STANDARD "
|
||||
"(last two chars: ${VAL} not understood as a valid CXX std)")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --------------------- Python specifics -------------------------
|
||||
|
||||
# Check to see which Python mode we are in, new, old, or no python
|
||||
if(PYBIND11_NOPYTHON)
|
||||
set(_pybind11_nopython ON)
|
||||
elseif(
|
||||
PYBIND11_FINDPYTHON
|
||||
OR Python_FOUND
|
||||
OR Python2_FOUND
|
||||
OR Python3_FOUND)
|
||||
# New mode
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/pybind11NewTools.cmake")
|
||||
|
||||
else()
|
||||
|
||||
# Classic mode
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
|
||||
|
||||
endif()
|
||||
|
||||
# --------------------- LTO -------------------------------
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
# 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 of flags: the compilation result will be
|
||||
# cached base on the result variable. If the flags work, sets them in
|
||||
# cxxflags_out/linkerflags_out internal cache variables (in addition to
|
||||
# ${result}).
|
||||
function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out
|
||||
linkerflags_out)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})
|
||||
check_cxx_compiler_flag("${cxxflags}" ${result})
|
||||
if(${result})
|
||||
set(${cxxflags_out}
|
||||
"${cxxflags}"
|
||||
PARENT_SCOPE)
|
||||
set(${linkerflags_out}
|
||||
"${linkerflags}"
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(_pybind11_generate_lto target prefer_thin_lto)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
set(cxx_append "")
|
||||
set(linker_append "")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
|
||||
# Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it
|
||||
set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(cxx_append ";-fno-fat-lto-objects")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto)
|
||||
_pybind11_return_if_cxx_and_linker_flags_work(
|
||||
HAS_FLTO_THIN "-flto=thin${cxx_append}" "-flto=thin${linker_append}"
|
||||
PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
||||
endif()
|
||||
|
||||
if(NOT HAS_FLTO_THIN)
|
||||
_pybind11_return_if_cxx_and_linker_flags_work(
|
||||
HAS_FLTO "-flto${cxx_append}" "-flto${linker_append}" PYBIND11_LTO_CXX_FLAGS
|
||||
PYBIND11_LTO_LINKER_FLAGS)
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||
# Intel equivalent to LTO is called IPO
|
||||
_pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO "-ipo" "-ipo"
|
||||
PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
||||
elseif(MSVC)
|
||||
# cmake only interprets libraries as linker flags when they start with a - (otherwise it
|
||||
# converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags
|
||||
# with - instead of /, even if it is a bit non-standard:
|
||||
_pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG "/GL" "-LTCG"
|
||||
PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
||||
endif()
|
||||
|
||||
# Enable LTO flags if found, except for Debug builds
|
||||
if(PYBIND11_LTO_CXX_FLAGS)
|
||||
set(not_debug "$<NOT:$<CONFIG:Debug>>")
|
||||
set(cxx_lang "$<COMPILE_LANGUAGE:CXX>")
|
||||
if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
|
||||
set(genex "${not_debug}")
|
||||
else()
|
||||
set(genex "$<AND:${not_debug},${cxx_lang}>")
|
||||
endif()
|
||||
set_property(
|
||||
TARGET ${target}
|
||||
APPEND
|
||||
PROPERTY INTERFACE_COMPILE_OPTIONS "$<${genex}:${PYBIND11_LTO_CXX_FLAGS}>")
|
||||
if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
|
||||
message(STATUS "${target} enabled")
|
||||
endif()
|
||||
else()
|
||||
if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
|
||||
message(STATUS "${target} disabled (not supported by the compiler and/or linker)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(PYBIND11_LTO_LINKER_FLAGS)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.11)
|
||||
set_property(
|
||||
TARGET ${target}
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
|
||||
else()
|
||||
set_property(
|
||||
TARGET ${target}
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_OPTIONS "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
add_library(pybind11::lto IMPORTED INTERFACE ${optional_global})
|
||||
_pybind11_generate_lto(pybind11::lto FALSE)
|
||||
|
||||
add_library(pybind11::thin_lto IMPORTED INTERFACE ${optional_global})
|
||||
_pybind11_generate_lto(pybind11::thin_lto TRUE)
|
||||
|
||||
# ---------------------- pybind11_strip -----------------------------
|
||||
|
||||
function(pybind11_strip target_name)
|
||||
# Strip unnecessary sections of the binary on Linux/Mac OS
|
||||
if(CMAKE_STRIP)
|
||||
if(APPLE)
|
||||
set(x_opt -x)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${target_name}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} ${x_opt} $<TARGET_FILE:${target_name}>)
|
||||
endif()
|
||||
endfunction()
|
@ -8,6 +8,7 @@ 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_VERSION_TYPE - pybind11 version type (dev, 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.
|
||||
@ -28,21 +29,61 @@ interface library targets::
|
||||
|
||||
Python headers, libraries (as needed by platform), and the C++ standard
|
||||
are attached to the target.
|
||||
|
||||
Advanced targets are also supplied - these are primary for users building
|
||||
complex applications, and they are available in all modes::
|
||||
|
||||
pybind11::headers - Just the pybind11 headers and minimum compile requirements
|
||||
pybind11::pybind11 - Python headers too
|
||||
pybind11::python_link_helper - Just the "linking" part of pybind11:module, for CMake < 3.15
|
||||
pybind11::python2_no_register - Quiets the warning/error when mixing C++14+ and Python 2, also included in pybind11::module
|
||||
pybind11::thin_lto - An alternative to INTERPROCEDURAL_OPTIMIZATION
|
||||
pybind11::lto - An alternative to INTERPROCEDURAL_OPTIMIZATION (also avoids thin LTO on clang)
|
||||
pybind11::windows_extras - Adds bigobj and mp for MSVC
|
||||
|
||||
Modes::
|
||||
|
||||
There are two modes provided; classic, which is built on the old Python
|
||||
discovery packages in CMake, or the new FindPython mode, which uses FindPython
|
||||
from 3.12+ forward (3.15+ _highly_ recommended).
|
||||
|
||||
New FindPython mode::
|
||||
|
||||
To activate this mode, either call ``find_package(Python COMPONENTS Interpreter Development)``
|
||||
before finding this package, or set the ``PYBIND11_FINDPYTHON`` variable to ON. In this mode,
|
||||
you can either use the basic targets, or use the FindPython tools::
|
||||
|
||||
find_package(Python COMPONENTS Interpreter Development)
|
||||
find_package(pybind11 CONFIG)
|
||||
|
||||
# pybind11 method:
|
||||
pybind11_add_module(MyModule1 src1.cpp)
|
||||
|
||||
# Python method:
|
||||
Python_add_library(MyModule2 src2.cpp)
|
||||
target_link_libraries(MyModule2 pybind11::headers)
|
||||
set_target_properties(MyModule2 PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION ON
|
||||
CXX__VISIBILITY_PRESET ON
|
||||
VISIBLITY_INLINES_HIDDEN ON)
|
||||
|
||||
If you build targets yourself, you may be interested in stripping the output
|
||||
for reduced size; this is the one other feature that the helper function gives you.
|
||||
|
||||
Classic mode::
|
||||
|
||||
Set PythonLibsNew variables to influence python detection and
|
||||
CMAKE_CXX_STANDARD to influence standard setting. ::
|
||||
|
||||
find_package(pybind11 CONFIG REQUIRED)
|
||||
message(STATUS "Found pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}: ${pybind11_INCLUDE_DIRS}")
|
||||
|
||||
# Create an extension module
|
||||
add_library(mylib MODULE main.cpp)
|
||||
target_link_libraries(mylib pybind11::module)
|
||||
target_link_libraries(mylib PUBLIC pybind11::module)
|
||||
|
||||
# Or embed the Python interpreter into an executable
|
||||
add_executable(myexe main.cpp)
|
||||
target_link_libraries(myexe pybind11::embed)
|
||||
target_link_libraries(myexe PUBLIC pybind11::embed)
|
||||
|
||||
Suggested usage::
|
||||
|
||||
@ -59,8 +100,17 @@ The following variables can be set to guide the search for 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
|
||||
#]=============================================================================]
|
||||
|
||||
Helper functions::
|
||||
|
||||
pybind11_add_module(...) - Add a library and setup all helpers
|
||||
pybind11_strip(target) - Strip a target after building it (linux/macOS)
|
||||
pybind11_extension(target) - Injects the Python extension name
|
||||
|
||||
See ``pybind11Tools.cmake`` or ``pybind11NewTools.cmake`` for details on
|
||||
``pybind11_add_module``.
|
||||
|
||||
#]=============================================================================]
|
||||
@PACKAGE_INIT@
|
||||
|
||||
# Location of pybind11/pybind11.h
|
||||
@ -72,50 +122,19 @@ set(pybind11_VERSION_TYPE "@pybind11_VERSION_TYPE@")
|
||||
|
||||
check_required_components(pybind11)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# 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 pybind11::pybind11)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED)
|
||||
list(REMOVE_AT CMAKE_MODULE_PATH -1)
|
||||
|
||||
set_property(
|
||||
TARGET pybind11::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
|
||||
set_property(
|
||||
TARGET pybind11::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
|
||||
|
||||
set_property(
|
||||
TARGET pybind11::embed
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
|
||||
set_property(
|
||||
TARGET pybind11::module
|
||||
APPEND
|
||||
PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES
|
||||
"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>"
|
||||
)
|
||||
|
||||
get_property(
|
||||
_iid
|
||||
TARGET pybind11::pybind11
|
||||
PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_property(
|
||||
_ill
|
||||
TARGET pybind11::module
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES)
|
||||
set(pybind11_INCLUDE_DIRS ${_iid})
|
||||
set(pybind11_LIBRARIES ${_ico} ${_ill})
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
|
||||
if(TARGET pybind11::python_link_helper)
|
||||
# This has already been setup elsewhere, such as with a previous call or
|
||||
# add_subdirectory
|
||||
return()
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake")
|
||||
|
||||
if(NOT pybind11_FIND_QUIETLY)
|
||||
message(
|
||||
STATUS
|
||||
"Found pybind11: ${pybind11_INCLUDE_DIR} (found version \"${pybind11_VERSION}\" ${pybind11_VERSION_TYPE})"
|
||||
)
|
||||
endif()
|
||||
|
203
tools/pybind11NewTools.cmake
Normal file
203
tools/pybind11NewTools.cmake
Normal file
@ -0,0 +1,203 @@
|
||||
# tools/pybind11NewTools.cmake -- Build system for the pybind11 modules
|
||||
#
|
||||
# Copyright (c) 2020 Wenzel Jakob <wenzel@inf.ethz.ch> and Henry Schreiner
|
||||
#
|
||||
# All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
get_property(
|
||||
is_config
|
||||
TARGET pybind11::headers
|
||||
PROPERTY IMPORTED)
|
||||
|
||||
if(pybind11_FIND_QUIETLY)
|
||||
set(_pybind11_quiet QUIET)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.12)
|
||||
message(FATAL_ERROR "You cannot use the new FindPython module with CMake < 3.12")
|
||||
endif()
|
||||
|
||||
if(NOT Python_FOUND
|
||||
AND NOT Python3_FOUND
|
||||
AND NOT Python2_FOUND)
|
||||
if(NOT DEFINED Python_FIND_IMPLEMENTATIONS)
|
||||
set(Python_FIND_IMPLEMENTATIONS CPython PyPy)
|
||||
endif()
|
||||
|
||||
# GitHub Actions like activation
|
||||
if(NOT DEFINED Python_ROOT_DIR AND DEFINED ENV{pythonLocation})
|
||||
set(Python_ROOT_DIR "$ENV{pythonLocation}")
|
||||
endif()
|
||||
|
||||
find_package(Python REQUIRED COMPONENTS Interpreter Development ${_pybind11_quiet})
|
||||
|
||||
# If we are in submodule mode, export the Python targets to global targets.
|
||||
# If this behavior is not desired, FindPython _before_ pybind11.
|
||||
if(NOT is_config)
|
||||
set_property(TARGET Python::Python PROPERTY IMPORTED_GLOBAL TRUE)
|
||||
set_property(TARGET Python::Interpreter PROPERTY IMPORTED_GLOBAL TRUE)
|
||||
if(TARGET Python::Module)
|
||||
set_property(TARGET Python::Module PROPERTY IMPORTED_GLOBAL TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Python_FOUND)
|
||||
set(_Python
|
||||
Python
|
||||
CACHE INTERNAL "" FORCE)
|
||||
elseif(Python3_FOUND AND NOT Python2_FOUND)
|
||||
set(_Python
|
||||
Python3
|
||||
CACHE INTERNAL "" FORCE)
|
||||
elseif(Python2_FOUND AND NOT Python3_FOUND)
|
||||
set(_Python
|
||||
Python2
|
||||
CACHE INTERNAL "" FORCE)
|
||||
else()
|
||||
message(AUTHOR_WARNING "Python2 and Python3 both present, pybind11 in "
|
||||
"PYBIND11_NOPYTHON mode (manually activate to silence warning)")
|
||||
set(_pybind11_nopython ON)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(PYBIND11_MASTER_PROJECT)
|
||||
if(${_Python}_INTERPRETER_ID MATCHES "PyPy")
|
||||
message(STATUS "PyPy ${${_Python}_PyPy_VERSION} (Py ${${_Python}_VERSION})")
|
||||
else()
|
||||
message(STATUS "${_Python} ${${_Python}_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Debug check - see https://stackoverflow.com/questions/646518/python-how-to-detect-debug-Interpreter
|
||||
execute_process(COMMAND ${_Python}::Python -c "import sys; print(hasattr(sys, 'gettotalrefcount'))"
|
||||
OUTPUT_VARIABLE PYTHON_IS_DEBUG)
|
||||
|
||||
# Python debug libraries expose slightly different objects before 3.8
|
||||
# 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
|
||||
if(PYTHON_IS_DEBUG)
|
||||
set_property(
|
||||
TARGET pybind::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
|
||||
endif()
|
||||
|
||||
# Check on every access - since Python2 and Python3 could have been used - do nothing in that case.
|
||||
|
||||
if(DEFINED ${_Python}_INCLUDE_DIRS)
|
||||
set_property(
|
||||
TARGET pybind11::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>)
|
||||
endif()
|
||||
|
||||
if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
|
||||
set_property(
|
||||
TARGET pybind11::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)
|
||||
endif()
|
||||
|
||||
# In CMake 3.18+, you can find these separately, so include an if
|
||||
if(TARGET ${_Python}::${_Python})
|
||||
set_property(
|
||||
TARGET pybind11::embed
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::${_Python})
|
||||
endif()
|
||||
|
||||
# CMake 3.15+ has this
|
||||
if(TARGET ${_Python}::Module)
|
||||
set_property(
|
||||
TARGET pybind11::module
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)
|
||||
else()
|
||||
set_property(
|
||||
TARGET pybind11::module
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)
|
||||
endif()
|
||||
|
||||
function(pybind11_add_module target_name)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 ARG "STATIC;SHARED;MODULE;THIN_LTO;NO_EXTRAS" "" "")
|
||||
|
||||
if(ARG_ADD_LIBRARY_STATIC)
|
||||
set(type STATIC)
|
||||
elseif(ARG_ADD_LIBRARY_SHARED)
|
||||
set(type SHARED)
|
||||
else()
|
||||
set(type MODULE)
|
||||
endif()
|
||||
|
||||
if("${_Python}" STREQUAL "Python")
|
||||
python_add_library(${target_name} ${type} WITH_SOABI ${ARG_UNPARSED_ARGUMENTS})
|
||||
elseif("${_Python}" STREQUAL "Python3")
|
||||
python3_add_library(${target_name} ${type} WITH_SOABI ${ARG_UNPARSED_ARGUMENTS})
|
||||
elseif("${_Python}" STREQUAL "Python2")
|
||||
python2_add_library(${target_name} ${type} WITH_SOABI ${ARG_UNPARSED_ARGUMENTS})
|
||||
else()
|
||||
message(FATAL_ERROR "Cannot detect FindPython version: ${_Python}")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::headers)
|
||||
|
||||
if(type STREQUAL "MODULE")
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::module)
|
||||
else()
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::embed)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
|
||||
endif()
|
||||
|
||||
if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::python2_no_register)
|
||||
endif()
|
||||
|
||||
set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden"
|
||||
CUDA_VISIBILITY_PRESET "hidden")
|
||||
|
||||
if(ARG_NO_EXTRAS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
||||
if(ARG_THIN_LTO)
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
|
||||
else()
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::lto)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
|
||||
# Strip unnecessary sections of the binary on Linux/Mac OS
|
||||
pybind11_strip(${target_name})
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(pybind11_extension name)
|
||||
set_property(TARGET ${name} PROPERTY PREFIX "")
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set_property(TARGET ${name} PROPERTY SUFFIX ".pyd")
|
||||
endif()
|
||||
|
||||
if(${_Python}_SOABI)
|
||||
get_property(
|
||||
suffix
|
||||
TARGET ${name}
|
||||
PROPERTY SUFFIX)
|
||||
if(NOT suffix)
|
||||
set(suffix "${CMAKE_SHARED_MODULE_SUFFIX}")
|
||||
endif()
|
||||
set_property(TARGET ${name} PROPERTY SUFFIX ".${${_Python}_SOABI}${suffix}")
|
||||
endif()
|
||||
endfunction()
|
@ -5,6 +5,13 @@
|
||||
# All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
# Built-in in CMake 3.5+
|
||||
include(CMakeParseArguments)
|
||||
|
||||
if(pybind11_FIND_QUIETLY)
|
||||
set(_pybind11_quiet QUIET)
|
||||
endif()
|
||||
|
||||
# Add a CMake parameter for choosing a desired Python version
|
||||
if(NOT PYBIND11_PYTHON_VERSION)
|
||||
set(PYBIND11_PYTHON_VERSION
|
||||
@ -18,112 +25,91 @@ set(Python_ADDITIONAL_VERSIONS
|
||||
CACHE INTERNAL "")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED)
|
||||
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED ${_pybind11_quiet})
|
||||
list(REMOVE_AT CMAKE_MODULE_PATH -1)
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
# Cache variables so pybind11_add_module can be used in parent projects
|
||||
set(PYTHON_INCLUDE_DIRS
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_LIBRARIES
|
||||
${PYTHON_LIBRARIES}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_MODULE_PREFIX
|
||||
${PYTHON_MODULE_PREFIX}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_MODULE_EXTENSION
|
||||
${PYTHON_MODULE_EXTENSION}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_VERSION_MAJOR
|
||||
${PYTHON_VERSION_MAJOR}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_VERSION_MINOR
|
||||
${PYTHON_VERSION_MINOR}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_VERSION
|
||||
${PYTHON_VERSION}
|
||||
CACHE INTERNAL "")
|
||||
set(PYTHON_IS_DEBUG
|
||||
"${PYTHON_IS_DEBUG}"
|
||||
CACHE INTERNAL "")
|
||||
|
||||
# Warn or error if old variable name used
|
||||
if(PYBIND11_CPP_STANDARD)
|
||||
string(REGEX MATCH [[..$]] VAL "${PYBIND11_CPP_STANDARD}")
|
||||
if(CMAKE_CXX_STANDARD)
|
||||
if(NOT CMAKE_CXX_STANDARD STREQUAL VAL)
|
||||
message(WARNING "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} does not match "
|
||||
"PYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}, "
|
||||
"please remove PYBIND11_CPP_STANDARD from your cache")
|
||||
if(PYBIND11_MASTER_PROJECT)
|
||||
if(PYTHON_MODULE_EXTENSION MATCHES "pypy")
|
||||
if(NOT DEFINED PYPY_VERSION)
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c
|
||||
[=[import sys; print(".".join(map(str, sys.pypy_version_info[:3])))]=]
|
||||
OUTPUT_VARIABLE pypy_version)
|
||||
set(PYPY_VERSION
|
||||
${pypy_version}
|
||||
CACHE INTERNAL "")
|
||||
endif()
|
||||
message(STATUS "PYPY ${PYPY_VERSION} (Py ${PYTHON_VERSION})")
|
||||
else()
|
||||
set(supported_standards 11 14 17 20)
|
||||
if("${VAL}" IN_LIST supported_standards)
|
||||
message(WARNING "USE -DCMAKE_CXX_STANDARD=${VAL} instead of PYBIND11_PYTHON_VERSION")
|
||||
set(CMAKE_CXX_STANDARD
|
||||
${VAL}
|
||||
CACHE STRING "From PYBIND11_CPP_STANDARD")
|
||||
else()
|
||||
message(FATAL_ERROR "PYBIND11_CPP_STANDARD should be replaced with CMAKE_CXX_STANDARD "
|
||||
"(last two chars: ${VAL} not understood as a valid CXX std)")
|
||||
endif()
|
||||
message(STATUS "PYTHON ${PYTHON_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# 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
|
||||
# of flags: the compilation result will be cached base on the result variable. If the flags work,
|
||||
# sets them in cxxflags_out/linkerflags_out internal cache variables (in addition to ${result}).
|
||||
function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out
|
||||
linkerflags_out)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})
|
||||
check_cxx_compiler_flag("${cxxflags}" ${result})
|
||||
if(${result})
|
||||
set(${cxxflags_out}
|
||||
"${cxxflags}"
|
||||
CACHE INTERNAL "" FORCE)
|
||||
set(${linkerflags_out}
|
||||
"${linkerflags}"
|
||||
CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
endfunction()
|
||||
# Only add Python for build - must be added during the import for config since it has to be re-discovered.
|
||||
set_property(
|
||||
TARGET pybind11::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>)
|
||||
|
||||
# Internal: find the appropriate link time optimization flags for this compiler
|
||||
function(_pybind11_add_lto_flags target_name prefer_thin_lto)
|
||||
if(NOT DEFINED PYBIND11_LTO_CXX_FLAGS)
|
||||
set(PYBIND11_LTO_CXX_FLAGS
|
||||
""
|
||||
CACHE INTERNAL "")
|
||||
set(PYBIND11_LTO_LINKER_FLAGS
|
||||
""
|
||||
CACHE INTERNAL "")
|
||||
# Python debug libraries expose slightly different objects before 3.8
|
||||
# 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
|
||||
if(PYTHON_IS_DEBUG)
|
||||
set_property(
|
||||
TARGET pybind::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
set(cxx_append "")
|
||||
set(linker_append "")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
|
||||
# Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it
|
||||
set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(cxx_append ";-fno-fat-lto-objects")
|
||||
endif()
|
||||
set_property(
|
||||
TARGET pybind11::module
|
||||
APPEND
|
||||
PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES pybind11::python_link_helper
|
||||
"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>")
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto)
|
||||
_pybind11_return_if_cxx_and_linker_flags_work(
|
||||
HAS_FLTO_THIN "-flto=thin${cxx_append}" "-flto=thin${linker_append}"
|
||||
PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
||||
endif()
|
||||
if(PYTHON_VERSION VERSION_LESS 3)
|
||||
set_property(
|
||||
TARGET pybind11::pybind11
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)
|
||||
endif()
|
||||
|
||||
if(NOT HAS_FLTO_THIN)
|
||||
_pybind11_return_if_cxx_and_linker_flags_work(
|
||||
HAS_FLTO "-flto${cxx_append}" "-flto${linker_append}" PYBIND11_LTO_CXX_FLAGS
|
||||
PYBIND11_LTO_LINKER_FLAGS)
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||
# Intel equivalent to LTO is called IPO
|
||||
_pybind11_return_if_cxx_and_linker_flags_work(
|
||||
HAS_INTEL_IPO "-ipo" "-ipo" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
||||
elseif(MSVC)
|
||||
# cmake only interprets libraries as linker flags when they start with a - (otherwise it
|
||||
# converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags
|
||||
# with - instead of /, even if it is a bit non-standard:
|
||||
_pybind11_return_if_cxx_and_linker_flags_work(
|
||||
HAS_MSVC_GL_LTCG "/GL" "-LTCG" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
|
||||
endif()
|
||||
set_property(
|
||||
TARGET pybind11::embed
|
||||
APPEND
|
||||
PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
|
||||
|
||||
if(PYBIND11_LTO_CXX_FLAGS)
|
||||
message(STATUS "LTO enabled")
|
||||
else()
|
||||
message(STATUS "LTO disabled (not supported by the compiler and/or linker)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Enable LTO flags if found, except for Debug builds
|
||||
if(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()
|
||||
if(PYBIND11_LTO_LINKER_FLAGS)
|
||||
target_link_libraries(${target_name} PRIVATE "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
|
||||
endif()
|
||||
function(pybind11_extension name)
|
||||
# The prefix and extension are provided by FindPythonLibsNew.cmake
|
||||
set_target_properties(${name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
|
||||
SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
||||
endfunction()
|
||||
|
||||
# Build a Python extension module:
|
||||
@ -132,7 +118,7 @@ endfunction()
|
||||
#
|
||||
function(pybind11_add_module target_name)
|
||||
set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS SYSTEM THIN_LTO)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 ARG "${options}" "" "")
|
||||
cmake_parse_arguments(ARG "${options}" "" "" ${ARGN})
|
||||
|
||||
if(ARG_MODULE AND ARG_SHARED)
|
||||
message(FATAL_ERROR "Can't be both MODULE and SHARED")
|
||||
@ -159,74 +145,34 @@ function(pybind11_add_module target_name)
|
||||
)
|
||||
endif()
|
||||
|
||||
# Python debug libraries expose slightly different objects before 3.8
|
||||
# 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
|
||||
if(PYTHON_IS_DEBUG)
|
||||
target_compile_definitions(${target_name} PRIVATE Py_DEBUG)
|
||||
endif()
|
||||
|
||||
# The prefix and extension are provided by FindPythonLibsNew.cmake
|
||||
set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
|
||||
set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
||||
pybind11_extension(${target_name})
|
||||
|
||||
# -fvisibility=hidden is required to allow multiple modules compiled against
|
||||
# different pybind versions to work properly, and for some features (e.g.
|
||||
# py::module_local). We force it on everything inside the `pybind11`
|
||||
# namespace; also turning it on for a pybind module compilation here avoids
|
||||
# potential warnings or issues from having mixed hidden/non-hidden types.
|
||||
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 CXX_VISIBILITY_PRESET "hidden"
|
||||
CUDA_VISIBILITY_PRESET "hidden")
|
||||
|
||||
if(ARG_NO_EXTRAS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
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
|
||||
LANGUAGES CXX)
|
||||
if(supported)
|
||||
set_property(TARGET ${target_name} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
||||
if(ARG_THIN_LTO)
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
|
||||
else()
|
||||
message(WARNING "IPO is not supported: ${output}")
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::lto)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
|
||||
# Strip unnecessary sections of the binary on Linux/Mac OS
|
||||
if(CMAKE_STRIP)
|
||||
if(APPLE)
|
||||
add_custom_command(
|
||||
TARGET ${target_name}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} -x $<TARGET_FILE:${target_name}>)
|
||||
else()
|
||||
add_custom_command(
|
||||
TARGET ${target_name}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target_name}>)
|
||||
endif()
|
||||
endif()
|
||||
pybind11_strip(${target_name})
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
# /MP enables multithreaded builds (relevant when there are many files), /bigobj is
|
||||
# needed for bigger binding projects due to the limit to 64k addressable sections
|
||||
target_compile_options(${target_name} PRIVATE /bigobj)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.11)
|
||||
target_compile_options(${target_name} PRIVATE $<$<NOT:$<CONFIG:Debug>>:/MP>)
|
||||
else()
|
||||
# Only set these options for C++ files. This is important so that, for
|
||||
# instance, projects that include other types of source files like CUDA
|
||||
# .cu files don't get these options propagated to nvcc since that would
|
||||
# cause the build to fail.
|
||||
target_compile_options(${target_name}
|
||||
PRIVATE $<$<NOT:$<CONFIG:Debug>>:$<$<COMPILE_LANGUAGE:CXX>:/MP>>)
|
||||
endif()
|
||||
target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
Loading…
Reference in New Issue
Block a user