mirror of
https://github.com/pybind/pybind11.git
synced 2026-04-20 14:59:27 +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:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user