blob: ded4dad9c9ad37d0fdf4121713e22bc8084ab76f [file] [log] [blame]
Dean Moldovana0c1ccf2016-08-12 13:50:00 +02001# CMakeLists.txt -- Build system for the pybind11 modules
Wenzel Jakob38bd7112015-07-05 20:05:44 +02002#
3# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.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
Henry Schreiner1729aae2020-08-19 12:26:26 -04008cmake_minimum_required(VERSION 3.4)
Wenzel Jakob38bd7112015-07-05 20:05:44 +02009
Henry Schreiner1729aae2020-08-19 12:26:26 -040010# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
Henry Schreinerdf115972020-07-31 22:45:19 -040011# some versions of VS that have a patched CMake 3.11. This forces us to emulate
12# the behavior using the following workaround:
Henry Schreiner6ec17752020-07-28 00:43:12 -040013if(${CMAKE_VERSION} VERSION_LESS 3.18)
Henry Schreiner94db5c52020-07-30 16:20:10 -040014 cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
Florian Apolloner29b99a12017-08-30 14:17:54 +020015else()
Henry Schreiner94db5c52020-07-30 16:20:10 -040016 cmake_policy(VERSION 3.18)
Florian Apolloner29b99a12017-08-30 14:17:54 +020017endif()
Wenzel Jakob38bd7112015-07-05 20:05:44 +020018
Henry Schreiner6ec17752020-07-28 00:43:12 -040019# Extract project version from source
Henry Schreiner94db5c52020-07-30 16:20:10 -040020file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
21 pybind11_version_defines REGEX "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) ")
Henry Schreiner6ec17752020-07-28 00:43:12 -040022
23foreach(ver ${pybind11_version_defines})
Henry Schreiner94db5c52020-07-30 16:20:10 -040024 if(ver MATCHES [[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])
25 set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
26 endif()
Henry Schreiner6ec17752020-07-28 00:43:12 -040027endforeach()
28
Henry Schreinerfd61f502020-09-16 17:13:41 -040029if(PYBIND11_VERSION_PATCH MATCHES [[\.([a-zA-Z0-9]+)$]])
Henry Schreinerdf115972020-07-31 22:45:19 -040030 set(pybind11_VERSION_TYPE "${CMAKE_MATCH_1}")
Henry Schreiner1651c322020-07-30 16:04:26 -040031endif()
Henry Schreinerfd61f502020-09-16 17:13:41 -040032string(REGEX MATCH "^[0-9]+" PYBIND11_VERSION_PATCH "${PYBIND11_VERSION_PATCH}")
Henry Schreiner1651c322020-07-30 16:04:26 -040033
Henry Schreiner6ec17752020-07-28 00:43:12 -040034project(
Henry Schreiner94db5c52020-07-30 16:20:10 -040035 pybind11
36 LANGUAGES CXX
37 VERSION "${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}")
Henry Schreiner6ec17752020-07-28 00:43:12 -040038
39# Standard includes
40include(GNUInstallDirs)
41include(CMakePackageConfigHelpers)
42include(CMakeDependentOption)
43
Henry Schreiner1729aae2020-08-19 12:26:26 -040044if(NOT pybind11_FIND_QUIETLY)
45 message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
46endif()
Henry Schreiner1651c322020-07-30 16:04:26 -040047
Henry Schreiner130c9952021-01-19 18:49:03 -050048# Avoid infinite recursion if tests include this as a subdirectory
49if(DEFINED PYBIND11_MASTER_PROJECT)
50 set(PYBIND11_TEST OFF)
51endif()
52
Dean Moldovan8c6b0b82016-05-23 00:12:37 +020053# Check if pybind11 is being used directly or via add_subdirectory
Henry Schreiner130c9952021-01-19 18:49:03 -050054if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR AND NOT DEFINED PYBIND11_MASTER_PROJECT)
Henry Schreiner04fdc442020-08-19 13:11:57 -040055 ### Warn if not an out-of-source builds
56 if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
57 set(lines
58 "You are building in-place. If that is not what you intended to "
59 "do, you can clean the source directory with:\n"
60 "rm -r CMakeCache.txt CMakeFiles/ cmake_uninstall.cmake pybind11Config.cmake "
61 "pybind11ConfigVersion.cmake tests/CMakeFiles/\n")
62 message(AUTHOR_WARNING ${lines})
63 endif()
64
Henry Schreiner94db5c52020-07-30 16:20:10 -040065 set(PYBIND11_MASTER_PROJECT ON)
Henry Schreiner1729aae2020-08-19 12:26:26 -040066
67 if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
68 # Bug in macOS CMake < 3.7 is unable to download catch
69 message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
70 elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)
71 # Only tested with 3.8+ in CI.
72 message(WARNING "CMAKE 3.8+ tested on Windows, previous versions untested")
73 endif()
74
Henry Schreiner94db5c52020-07-30 16:20:10 -040075 message(STATUS "CMake ${CMAKE_VERSION}")
Henry Schreiner6ec17752020-07-28 00:43:12 -040076
Henry Schreiner94db5c52020-07-30 16:20:10 -040077 if(CMAKE_CXX_STANDARD)
78 set(CMAKE_CXX_EXTENSIONS OFF)
79 set(CMAKE_CXX_STANDARD_REQUIRED ON)
80 endif()
Henry Schreinereb83fee2021-01-19 18:48:22 -050081
82 set(pybind11_system "")
Henry Schreiner6ec17752020-07-28 00:43:12 -040083else()
Henry Schreiner94db5c52020-07-30 16:20:10 -040084 set(PYBIND11_MASTER_PROJECT OFF)
85 set(pybind11_system SYSTEM)
Wenzel Jakob67a63922016-05-29 12:35:16 +020086endif()
Dean Moldovan8c6b0b82016-05-23 00:12:37 +020087
Henry Schreinerdf115972020-07-31 22:45:19 -040088# Options
Dean Moldovan49720f02016-05-26 22:53:38 +020089option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
Henry Schreiner6ec17752020-07-28 00:43:12 -040090option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
Henry Schreiner1729aae2020-08-19 12:26:26 -040091option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
Henry Schreinerdf115972020-07-31 22:45:19 -040092
Henry Schreiner6ec17752020-07-28 00:43:12 -040093cmake_dependent_option(
Henry Schreiner94db5c52020-07-30 16:20:10 -040094 USE_PYTHON_INCLUDE_DIR
95 "Install pybind11 headers in Python include directory instead of default installation prefix"
96 OFF "PYBIND11_INSTALL" OFF)
Wenzel Jakob3350b5e2015-11-24 21:33:18 +010097
Henry Schreiner1729aae2020-08-19 12:26:26 -040098cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" OFF
99 "NOT CMAKE_VERSION VERSION_LESS 3.12" OFF)
100
Henry Schreiner6ec17752020-07-28 00:43:12 -0400101# NB: when adding a header don't forget to also add it to setup.py
102set(PYBIND11_HEADERS
103 include/pybind11/detail/class.h
104 include/pybind11/detail/common.h
105 include/pybind11/detail/descr.h
106 include/pybind11/detail/init.h
107 include/pybind11/detail/internals.h
108 include/pybind11/detail/typeid.h
109 include/pybind11/attr.h
110 include/pybind11/buffer_info.h
111 include/pybind11/cast.h
112 include/pybind11/chrono.h
113 include/pybind11/common.h
114 include/pybind11/complex.h
115 include/pybind11/options.h
116 include/pybind11/eigen.h
117 include/pybind11/embed.h
118 include/pybind11/eval.h
Henry Schreiner1caf1d02020-08-01 15:24:30 -0400119 include/pybind11/iostream.h
Henry Schreiner6ec17752020-07-28 00:43:12 -0400120 include/pybind11/functional.h
121 include/pybind11/numpy.h
122 include/pybind11/operators.h
123 include/pybind11/pybind11.h
124 include/pybind11/pytypes.h
125 include/pybind11/stl.h
Henry Schreiner94db5c52020-07-30 16:20:10 -0400126 include/pybind11/stl_bind.h)
Henry Schreiner1651c322020-07-30 16:04:26 -0400127
Henry Schreiner1caf1d02020-08-01 15:24:30 -0400128# Compare with grep and warn if mismatched
129if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
130 file(
131 GLOB_RECURSE _pybind11_header_check
132 LIST_DIRECTORIES false
133 RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
134 CONFIGURE_DEPENDS "include/pybind11/*.h")
135 set(_pybind11_here_only ${PYBIND11_HEADERS})
136 set(_pybind11_disk_only ${_pybind11_header_check})
137 list(REMOVE_ITEM _pybind11_here_only ${_pybind11_header_check})
138 list(REMOVE_ITEM _pybind11_disk_only ${PYBIND11_HEADERS})
139 if(_pybind11_here_only)
140 message(AUTHOR_WARNING "PYBIND11_HEADERS has extra files:" ${_pybind11_here_only})
141 endif()
142 if(_pybind11_disk_only)
143 message(AUTHOR_WARNING "PYBIND11_HEADERS is missing files:" ${_pybind11_disk_only})
144 endif()
145endif()
Henry Schreiner1651c322020-07-30 16:04:26 -0400146
Henry Schreiner1caf1d02020-08-01 15:24:30 -0400147# CMake 3.12 added list(TRANSFORM <list> PREPEND
Henry Schreiner6ec17752020-07-28 00:43:12 -0400148# But we can't use it yet
Henry Schreiner94db5c52020-07-30 16:20:10 -0400149string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" PYBIND11_HEADERS
150 "${PYBIND11_HEADERS}")
Henry Schreiner6ec17752020-07-28 00:43:12 -0400151
Henry Schreinerb8dc60e2020-11-02 20:45:54 -0500152# Cache variable so this can be used in parent projects
153set(pybind11_INCLUDE_DIR
Henry Schreiner94db5c52020-07-30 16:20:10 -0400154 "${CMAKE_CURRENT_LIST_DIR}/include"
Henry Schreinerb8dc60e2020-11-02 20:45:54 -0500155 CACHE INTERNAL "Directory where pybind11 headers are located")
156
157# Backward compatible variable for add_subdirectory mode
158if(NOT PYBIND11_MASTER_PROJECT)
159 set(PYBIND11_INCLUDE_DIR
160 "${pybind11_INCLUDE_DIR}"
161 CACHE INTERNAL "")
162endif()
Sylvain Corlayd5ce82b2017-02-14 13:16:14 +0100163
Henry Schreiner6ec17752020-07-28 00:43:12 -0400164# Note: when creating targets, you cannot use if statements at configure time -
165# you need generator expressions, because those will be placed in the target file.
Henry Schreiner1651c322020-07-30 16:04:26 -0400166# You can also place ifs *in* the Config.in, but not here.
Dean Moldovan7f5c85c2017-03-23 13:32:54 +0100167
Henry Schreiner1729aae2020-08-19 12:26:26 -0400168# This section builds targets, but does *not* touch Python
Henry Schreiner130c9952021-01-19 18:49:03 -0500169# Non-IMPORT targets cannot be defined twice
170if(NOT TARGET pybind11_headers)
171 # Build the headers-only target (no Python included):
172 # (long name used here to keep this from clashing in subdirectory mode)
173 add_library(pybind11_headers INTERFACE)
174 add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target
175 add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember
Dean Moldovanb0f38852016-12-14 01:43:39 +0100176
Henry Schreiner130c9952021-01-19 18:49:03 -0500177 target_include_directories(
178 pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
179 $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
180
181 target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
182 cxx_right_angle_brackets)
183else()
184 # It is invalid to install a target twice, too.
185 set(PYBIND11_INSTALL OFF)
186endif()
Henry Schreiner1729aae2020-08-19 12:26:26 -0400187
188include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
189
Henry Schreiner1729aae2020-08-19 12:26:26 -0400190# Relative directory setting
191if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
192 file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})
193elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
194 file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
195endif()
196
Henry Schreiner6ec17752020-07-28 00:43:12 -0400197if(PYBIND11_INSTALL)
Henry Schreinerb8dc60e2020-11-02 20:45:54 -0500198 install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
Henry Schreiner94db5c52020-07-30 16:20:10 -0400199 set(PYBIND11_CMAKECONFIG_INSTALL_DIR
Henry Schreineredda89b2020-10-13 13:08:54 -0400200 "${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
Henry Schreiner94db5c52020-07-30 16:20:10 -0400201 CACHE STRING "install path for pybind11Config.cmake")
Henry Schreiner6ec17752020-07-28 00:43:12 -0400202
Henry Schreiner94db5c52020-07-30 16:20:10 -0400203 configure_package_config_file(
204 tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
205 INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
Henry Schreiner6ec17752020-07-28 00:43:12 -0400206
Henry Schreiner94db5c52020-07-30 16:20:10 -0400207 if(CMAKE_VERSION VERSION_LESS 3.14)
208 # Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does
209 # not depend on architecture specific settings or libraries.
210 set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
211 unset(CMAKE_SIZEOF_VOID_P)
Henry Schreiner6ec17752020-07-28 00:43:12 -0400212
Henry Schreiner94db5c52020-07-30 16:20:10 -0400213 write_basic_package_version_file(
214 ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
215 VERSION ${PROJECT_VERSION}
216 COMPATIBILITY AnyNewerVersion)
Henry Schreiner6ec17752020-07-28 00:43:12 -0400217
Henry Schreiner94db5c52020-07-30 16:20:10 -0400218 set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})
219 else()
220 # CMake 3.14+ natively supports header-only libraries
221 write_basic_package_version_file(
222 ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
223 VERSION ${PROJECT_VERSION}
224 COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
225 endif()
Henry Schreiner6ec17752020-07-28 00:43:12 -0400226
Henry Schreiner94db5c52020-07-30 16:20:10 -0400227 install(
228 FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
229 ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
Henry Schreiner1729aae2020-08-19 12:26:26 -0400230 tools/FindPythonLibsNew.cmake
231 tools/pybind11Common.cmake
232 tools/pybind11Tools.cmake
233 tools/pybind11NewTools.cmake
Henry Schreiner94db5c52020-07-30 16:20:10 -0400234 DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
Henry Schreiner6ec17752020-07-28 00:43:12 -0400235
Henry Schreiner94db5c52020-07-30 16:20:10 -0400236 if(NOT PYBIND11_EXPORT_NAME)
237 set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets")
238 endif()
Dean Moldovan3dde6dd2017-08-07 22:47:19 +0200239
Henry Schreinerc58f7b72020-08-22 09:06:01 -0400240 install(TARGETS pybind11_headers EXPORT "${PYBIND11_EXPORT_NAME}")
Henry Schreiner6ec17752020-07-28 00:43:12 -0400241
Henry Schreiner94db5c52020-07-30 16:20:10 -0400242 install(
243 EXPORT "${PYBIND11_EXPORT_NAME}"
244 NAMESPACE "pybind11::"
245 DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
acxz6f6e9392020-07-30 21:16:50 -0400246
Henry Schreinerb8047242020-07-31 04:16:40 -0400247 # Uninstall target
248 if(PYBIND11_MASTER_PROJECT)
249 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"
250 "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
acxz6f6e9392020-07-30 21:16:50 -0400251
Henry Schreinerb8047242020-07-31 04:16:40 -0400252 add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P
253 ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
254 endif()
acxz6f6e9392020-07-30 21:16:50 -0400255endif()
Henry Schreinerdf115972020-07-31 22:45:19 -0400256
Paul Fultz II69821d92020-08-18 07:34:18 -0500257# BUILD_TESTING takes priority, but only if this is the master project
258if(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)
259 if(BUILD_TESTING)
Henry Schreiner1729aae2020-08-19 12:26:26 -0400260 if(_pybind11_nopython)
261 message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
262 else()
263 add_subdirectory(tests)
264 endif()
Paul Fultz II69821d92020-08-18 07:34:18 -0500265 endif()
266else()
267 if(PYBIND11_TEST)
Henry Schreiner1729aae2020-08-19 12:26:26 -0400268 if(_pybind11_nopython)
269 message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
270 else()
271 add_subdirectory(tests)
272 endif()
Paul Fultz II69821d92020-08-18 07:34:18 -0500273 endif()
Henry Schreinerdf115972020-07-31 22:45:19 -0400274endif()
Henry Schreiner1729aae2020-08-19 12:26:26 -0400275
276# Better symmetry with find_package(pybind11 CONFIG) mode.
277if(NOT PYBIND11_MASTER_PROJECT)
278 set(pybind11_FOUND
279 TRUE
Henry Schreinerb8dc60e2020-11-02 20:45:54 -0500280 CACHE INTERNAL "True if pybind11 and all required components found on the system")
Henry Schreiner1729aae2020-08-19 12:26:26 -0400281endif()