blob: 4698566d6b3877a2cc96d6d77c547f67b44913b0 [file] [log] [blame]
Lori A. Burns545b4db2016-12-13 10:59:21 -05001# tools/pybind11Tools.cmake -- Build system for the pybind11 modules
2#
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
8cmake_minimum_required(VERSION 2.8.12)
9
10# Add a CMake parameter for choosing a desired Python version
11set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules")
12
13set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4)
14find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
15
16include(CheckCXXCompilerFlag)
Dean Moldovan0cbec5c2016-12-16 22:58:37 +010017include(CMakeParseArguments)
Lori A. Burns545b4db2016-12-13 10:59:21 -050018
19function(select_cxx_standard)
20 if(NOT MSVC AND NOT PYBIND11_CPP_STANDARD)
21 check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
22 check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
23
24 if (HAS_CPP14_FLAG)
25 set(PYBIND11_CPP_STANDARD -std=c++14)
26 elseif (HAS_CPP11_FLAG)
27 set(PYBIND11_CPP_STANDARD -std=c++11)
28 else()
29 message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
30 endif()
31
32 set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
33 "C++ standard flag, e.g. -std=c++11 or -std=c++14. Defaults to latest available." FORCE)
34 endif()
35endfunction()
36
Dean Moldovan0cbec5c2016-12-16 22:58:37 +010037# Internal: find the appropriate LTO flag for this compiler
38macro(_pybind11_find_lto_flag output_var prefer_thin_lto)
39 if(${prefer_thin_lto})
40 # Check for ThinLTO support (Clang)
41 check_cxx_compiler_flag("-flto=thin" HAS_THIN_LTO_FLAG)
42 set(${output_var} $<${HAS_THIN_LTO_FLAG}:-flto=thin>)
43 endif()
44
45 if(NOT ${prefer_thin_lto} OR NOT HAS_THIN_LTO_FLAG)
46 if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Intel")
47 # Check for Link Time Optimization support (GCC/Clang)
48 check_cxx_compiler_flag("-flto" HAS_LTO_FLAG)
49 set(${output_var} $<${HAS_LTO_FLAG}:-flto>)
50 else()
51 # Intel equivalent to LTO is called IPO
52 check_cxx_compiler_flag("-ipo" HAS_IPO_FLAG)
53 set(${output_var} $<${HAS_IPO_FLAG}:-ipo>)
54 endif()
55 endif()
56endmacro()
57
Lori A. Burns545b4db2016-12-13 10:59:21 -050058# Build a Python extension module:
Dean Moldovan0cbec5c2016-12-16 22:58:37 +010059# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
60# [NO_EXTRAS] [THIN_LTO] source1 [source2 ...])
Lori A. Burns545b4db2016-12-13 10:59:21 -050061#
62function(pybind11_add_module target_name)
Dean Moldovan0cbec5c2016-12-16 22:58:37 +010063 set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS THIN_LTO)
64 cmake_parse_arguments(ARG "${options}" "" "" ${ARGN})
Lori A. Burns545b4db2016-12-13 10:59:21 -050065
Dean Moldovan0cbec5c2016-12-16 22:58:37 +010066 if(ARG_MODULE AND ARG_SHARED)
67 message(FATAL_ERROR "Can't be both MODULE and SHARED")
68 elseif(ARG_SHARED)
69 set(lib_type SHARED)
70 else()
71 set(lib_type MODULE)
72 endif()
Lori A. Burns545b4db2016-12-13 10:59:21 -050073
Dean Moldovan0cbec5c2016-12-16 22:58:37 +010074 if(ARG_EXCLUDE_FROM_ALL)
75 set(exclude_from_all EXCLUDE_FROM_ALL)
76 endif()
77
78 add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS})
Lori A. Burns545b4db2016-12-13 10:59:21 -050079
80 target_include_directories(${target_name}
81 PRIVATE ${PYBIND11_INCLUDE_DIR} # from project CMakeLists.txt
82 PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config
83 PRIVATE ${PYTHON_INCLUDE_DIRS})
84
85 # The prefix and extension are provided by FindPythonLibsNew.cmake
86 set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
87 set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
88
89 if(WIN32 OR CYGWIN)
90 # Link against the Python shared library on Windows
91 target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES})
92 elseif(APPLE)
93 # It's quite common to have multiple copies of the same Python version
94 # installed on one's system. E.g.: one copy from the OS and another copy
95 # that's statically linked into an application like Blender or Maya.
96 # If we link our plugin library against the OS Python here and import it
97 # into Blender or Maya later on, this will cause segfaults when multiple
98 # conflicting Python instances are active at the same time (even when they
99 # are of the same version).
100
101 # Windows is not affected by this issue since it handles DLL imports
102 # differently. The solution for Linux and Mac OS is simple: we just don't
103 # link against the Python library. The resulting shared library will have
104 # missing symbols, but that's perfectly fine -- they will be resolved at
105 # import time.
106
107 target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup")
Dean Moldovanb0f38852016-12-14 01:43:39 +0100108
Dean Moldovan0cbec5c2016-12-16 22:58:37 +0100109 if(ARG_SHARED)
Dean Moldovanb0f38852016-12-14 01:43:39 +0100110 # Suppress CMake >= 3.0 warning for shared libraries
111 set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON)
112 endif()
Lori A. Burns545b4db2016-12-13 10:59:21 -0500113 endif()
114
115 select_cxx_standard()
116 if(NOT MSVC)
117 # Make sure C++11/14 are enabled
118 target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD})
Dean Moldovan0cbec5c2016-12-16 22:58:37 +0100119 endif()
Lori A. Burns545b4db2016-12-13 10:59:21 -0500120
Dean Moldovan0cbec5c2016-12-16 22:58:37 +0100121 if(ARG_NO_EXTRAS)
122 return()
123 endif()
124
125 if(NOT MSVC)
Lori A. Burns545b4db2016-12-13 10:59:21 -0500126 # Enable link time optimization and set the default symbol
127 # visibility to hidden (very important to obtain small binaries)
128 string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
129 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Dean Moldovan0cbec5c2016-12-16 22:58:37 +0100130 # Link Time Optimization
131 if(NOT CYGWIN)
132 _pybind11_find_lto_flag(lto_flag ARG_THIN_LTO)
133 target_compile_options(${target_name} PRIVATE ${lto_flag})
Lori A. Burns545b4db2016-12-13 10:59:21 -0500134 endif()
135
136 # Default symbol visibility
137 target_compile_options(${target_name} PRIVATE "-fvisibility=hidden")
138
139 # Strip unnecessary sections of the binary on Linux/Mac OS
140 if(CMAKE_STRIP)
141 if(APPLE)
142 add_custom_command(TARGET ${target_name} POST_BUILD
Wenzel Jakoba9730be2017-01-06 14:18:44 +0100143 COMMAND ${CMAKE_STRIP} -x $<TARGET_FILE:${target_name}>)
Lori A. Burns545b4db2016-12-13 10:59:21 -0500144 else()
145 add_custom_command(TARGET ${target_name} POST_BUILD
146 COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target_name}>)
147 endif()
148 endif()
149 endif()
150 elseif(MSVC)
151 # /MP enables multithreaded builds (relevant when there are many files), /bigobj is
152 # needed for bigger binding projects due to the limit to 64k addressable sections
153 target_compile_options(${target_name} PRIVATE /MP /bigobj)
154
155 # Enforce link time code generation on MSVC, except in debug mode
156 target_compile_options(${target_name} PRIVATE $<$<NOT:$<CONFIG:Debug>>:/GL>)
157
158 # Fancy generator expressions don't work with linker flags, for reasons unknown
159 set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE /LTCG)
160 set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL /LTCG)
161 set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO /LTCG)
162 endif()
163endfunction()