1# tools/pybind11Tools.cmake -- Build system for the pybind11 modules 2# 3# Copyright (c) 2020 Wenzel Jakob <wenzel.jakob@epfl.ch> 4# 5# All rights reserved. Use of this source code is governed by a 6# BSD-style license that can be found in the LICENSE file. 7 8# Built-in in CMake 3.5+ 9include(CMakeParseArguments) 10 11if(pybind11_FIND_QUIETLY) 12 set(_pybind11_quiet QUIET) 13else() 14 set(_pybind11_quiet "") 15endif() 16 17# If this is the first run, PYTHON_VERSION can stand in for PYBIND11_PYTHON_VERSION 18if(NOT DEFINED PYBIND11_PYTHON_VERSION AND DEFINED PYTHON_VERSION) 19 message(WARNING "Set PYBIND11_PYTHON_VERSION to search for a specific version, not " 20 "PYTHON_VERSION (which is an output). Assuming that is what you " 21 "meant to do and continuing anyway.") 22 set(PYBIND11_PYTHON_VERSION 23 "${PYTHON_VERSION}" 24 CACHE STRING "Python version to use for compiling modules") 25 unset(PYTHON_VERSION) 26 unset(PYTHON_VERSION CACHE) 27elseif(DEFINED PYBIND11_PYTHON_VERSION) 28 # If this is set as a normal variable, promote it 29 set(PYBIND11_PYTHON_VERSION 30 "${PYBIND11_PYTHON_VERSION}" 31 CACHE STRING "Python version to use for compiling modules") 32else() 33 # Make an empty cache variable. 34 set(PYBIND11_PYTHON_VERSION 35 "" 36 CACHE STRING "Python version to use for compiling modules") 37endif() 38 39# A user can set versions manually too 40set(Python_ADDITIONAL_VERSIONS 41 "3.10;3.9;3.8;3.7;3.6;3.5;3.4" 42 CACHE INTERNAL "") 43 44list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") 45find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED ${_pybind11_quiet}) 46list(REMOVE_AT CMAKE_MODULE_PATH -1) 47 48# Cache variables so pybind11_add_module can be used in parent projects 49set(PYTHON_INCLUDE_DIRS 50 ${PYTHON_INCLUDE_DIRS} 51 CACHE INTERNAL "") 52set(PYTHON_LIBRARIES 53 ${PYTHON_LIBRARIES} 54 CACHE INTERNAL "") 55set(PYTHON_MODULE_PREFIX 56 ${PYTHON_MODULE_PREFIX} 57 CACHE INTERNAL "") 58set(PYTHON_MODULE_EXTENSION 59 ${PYTHON_MODULE_EXTENSION} 60 CACHE INTERNAL "") 61set(PYTHON_VERSION_MAJOR 62 ${PYTHON_VERSION_MAJOR} 63 CACHE INTERNAL "") 64set(PYTHON_VERSION_MINOR 65 ${PYTHON_VERSION_MINOR} 66 CACHE INTERNAL "") 67set(PYTHON_VERSION 68 ${PYTHON_VERSION} 69 CACHE INTERNAL "") 70set(PYTHON_IS_DEBUG 71 "${PYTHON_IS_DEBUG}" 72 CACHE INTERNAL "") 73 74if(PYBIND11_MASTER_PROJECT) 75 if(PYTHON_MODULE_EXTENSION MATCHES "pypy") 76 if(NOT DEFINED PYPY_VERSION) 77 execute_process( 78 COMMAND ${PYTHON_EXECUTABLE} -c 79 [=[import sys; sys.stdout.write(".".join(map(str, sys.pypy_version_info[:3])))]=] 80 OUTPUT_VARIABLE pypy_version) 81 set(PYPY_VERSION 82 ${pypy_version} 83 CACHE INTERNAL "") 84 endif() 85 message(STATUS "PYPY ${PYPY_VERSION} (Py ${PYTHON_VERSION})") 86 else() 87 message(STATUS "PYTHON ${PYTHON_VERSION}") 88 endif() 89endif() 90 91# Only add Python for build - must be added during the import for config since 92# it has to be re-discovered. 93# 94# This needs to be an target to it is included after the local pybind11 95# directory, just in case there are multiple versions of pybind11, we want the 96# one we expect. 97add_library(pybind11::python_headers INTERFACE IMPORTED) 98set_property(TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES 99 "$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>") 100set_property( 101 TARGET pybind11::pybind11 102 APPEND 103 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers) 104 105set(pybind11_INCLUDE_DIRS 106 "${pybind11_INCLUDE_DIR}" "${PYTHON_INCLUDE_DIRS}" 107 CACHE INTERNAL "Directories where pybind11 and possibly Python headers are located") 108 109# Python debug libraries expose slightly different objects before 3.8 110# https://docs.python.org/3.6/c-api/intro.html#debugging-builds 111# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib 112if(PYTHON_IS_DEBUG) 113 set_property( 114 TARGET pybind11::pybind11 115 APPEND 116 PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG) 117endif() 118 119set_property( 120 TARGET pybind11::module 121 APPEND 122 PROPERTY 123 INTERFACE_LINK_LIBRARIES pybind11::python_link_helper 124 "$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>") 125 126if(PYTHON_VERSION VERSION_LESS 3) 127 set_property( 128 TARGET pybind11::pybind11 129 APPEND 130 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register) 131endif() 132 133set_property( 134 TARGET pybind11::embed 135 APPEND 136 PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>) 137 138function(pybind11_extension name) 139 # The prefix and extension are provided by FindPythonLibsNew.cmake 140 set_target_properties(${name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" 141 SUFFIX "${PYTHON_MODULE_EXTENSION}") 142endfunction() 143 144# Build a Python extension module: 145# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL] 146# [NO_EXTRAS] [THIN_LTO] [OPT_SIZE] source1 [source2 ...]) 147# 148function(pybind11_add_module target_name) 149 set(options "MODULE;SHARED;EXCLUDE_FROM_ALL;NO_EXTRAS;SYSTEM;THIN_LTO;OPT_SIZE") 150 cmake_parse_arguments(ARG "${options}" "" "" ${ARGN}) 151 152 if(ARG_MODULE AND ARG_SHARED) 153 message(FATAL_ERROR "Can't be both MODULE and SHARED") 154 elseif(ARG_SHARED) 155 set(lib_type SHARED) 156 else() 157 set(lib_type MODULE) 158 endif() 159 160 if(ARG_EXCLUDE_FROM_ALL) 161 set(exclude_from_all EXCLUDE_FROM_ALL) 162 else() 163 set(exclude_from_all "") 164 endif() 165 166 add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS}) 167 168 target_link_libraries(${target_name} PRIVATE pybind11::module) 169 170 if(ARG_SYSTEM) 171 message( 172 STATUS 173 "Warning: this does not have an effect - use NO_SYSTEM_FROM_IMPORTED if using imported targets" 174 ) 175 endif() 176 177 pybind11_extension(${target_name}) 178 179 # -fvisibility=hidden is required to allow multiple modules compiled against 180 # different pybind versions to work properly, and for some features (e.g. 181 # py::module_local). We force it on everything inside the `pybind11` 182 # namespace; also turning it on for a pybind module compilation here avoids 183 # potential warnings or issues from having mixed hidden/non-hidden types. 184 if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET) 185 set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden") 186 endif() 187 188 if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET) 189 set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden") 190 endif() 191 192 if(ARG_NO_EXTRAS) 193 return() 194 endif() 195 196 if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION) 197 if(ARG_THIN_LTO) 198 target_link_libraries(${target_name} PRIVATE pybind11::thin_lto) 199 else() 200 target_link_libraries(${target_name} PRIVATE pybind11::lto) 201 endif() 202 endif() 203 204 if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo) 205 pybind11_strip(${target_name}) 206 endif() 207 208 if(MSVC) 209 target_link_libraries(${target_name} PRIVATE pybind11::windows_extras) 210 endif() 211 212 if(ARG_OPT_SIZE) 213 target_link_libraries(${target_name} PRIVATE pybind11::opt_size) 214 endif() 215endfunction() 216 217# Provide general way to call common Python commands in "common" file. 218set(_Python 219 PYTHON 220 CACHE INTERNAL "" FORCE) 221