pybind11Tools.cmake revision 11986:c12e4625ab56
1# 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) 17 18function(select_cxx_standard) 19 if(NOT MSVC AND NOT PYBIND11_CPP_STANDARD) 20 check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG) 21 check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG) 22 23 if (HAS_CPP14_FLAG) 24 set(PYBIND11_CPP_STANDARD -std=c++14) 25 elseif (HAS_CPP11_FLAG) 26 set(PYBIND11_CPP_STANDARD -std=c++11) 27 else() 28 message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!") 29 endif() 30 31 set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING 32 "C++ standard flag, e.g. -std=c++11 or -std=c++14. Defaults to latest available." FORCE) 33 endif() 34endfunction() 35 36# Build a Python extension module: 37# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL] source1 [source2 ...]) 38# 39function(pybind11_add_module target_name) 40 set(lib_type "MODULE") 41 set(do_lto True) 42 set(exclude_from_all "") 43 set(sources "") 44 45 set(_args_to_try "${ARGN}") 46 foreach(_ex_arg IN LISTS _args_to_try) 47 if(${_ex_arg} STREQUAL "MODULE") 48 set(lib_type "MODULE") 49 elseif(${_ex_arg} STREQUAL "SHARED") 50 set(lib_type "SHARED") 51 elseif(${_ex_arg} STREQUAL "EXCLUDE_FROM_ALL") 52 set(exclude_from_all "EXCLUDE_FROM_ALL") 53 else() 54 list(APPEND sources "${_ex_arg}") 55 endif() 56 endforeach() 57 58 add_library(${target_name} ${lib_type} ${exclude_from_all} ${sources}) 59 60 target_include_directories(${target_name} 61 PRIVATE ${PYBIND11_INCLUDE_DIR} # from project CMakeLists.txt 62 PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config 63 PRIVATE ${PYTHON_INCLUDE_DIRS}) 64 65 # The prefix and extension are provided by FindPythonLibsNew.cmake 66 set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") 67 set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}") 68 69 if(WIN32 OR CYGWIN) 70 # Link against the Python shared library on Windows 71 target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES}) 72 elseif(APPLE) 73 # It's quite common to have multiple copies of the same Python version 74 # installed on one's system. E.g.: one copy from the OS and another copy 75 # that's statically linked into an application like Blender or Maya. 76 # If we link our plugin library against the OS Python here and import it 77 # into Blender or Maya later on, this will cause segfaults when multiple 78 # conflicting Python instances are active at the same time (even when they 79 # are of the same version). 80 81 # Windows is not affected by this issue since it handles DLL imports 82 # differently. The solution for Linux and Mac OS is simple: we just don't 83 # link against the Python library. The resulting shared library will have 84 # missing symbols, but that's perfectly fine -- they will be resolved at 85 # import time. 86 87 target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup") 88 endif() 89 90 select_cxx_standard() 91 if(NOT MSVC) 92 # Make sure C++11/14 are enabled 93 target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD}) 94 95 # Enable link time optimization and set the default symbol 96 # visibility to hidden (very important to obtain small binaries) 97 string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE) 98 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG) 99 # Check for Link Time Optimization support (GCC/Clang) 100 check_cxx_compiler_flag("-flto" HAS_LTO_FLAG) 101 if(HAS_LTO_FLAG AND NOT CYGWIN) 102 target_compile_options(${target_name} PRIVATE -flto) 103 endif() 104 105 # Intel equivalent to LTO is called IPO 106 if(CMAKE_CXX_COMPILER_ID MATCHES "Intel") 107 check_cxx_compiler_flag("-ipo" HAS_IPO_FLAG) 108 if(HAS_IPO_FLAG) 109 target_compile_options(${target_name} PRIVATE -ipo) 110 endif() 111 endif() 112 113 # Default symbol visibility 114 target_compile_options(${target_name} PRIVATE "-fvisibility=hidden") 115 116 # Strip unnecessary sections of the binary on Linux/Mac OS 117 if(CMAKE_STRIP) 118 if(APPLE) 119 add_custom_command(TARGET ${target_name} POST_BUILD 120 COMMAND ${CMAKE_STRIP} -u -r $<TARGET_FILE:${target_name}>) 121 else() 122 add_custom_command(TARGET ${target_name} POST_BUILD 123 COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target_name}>) 124 endif() 125 endif() 126 endif() 127 elseif(MSVC) 128 # /MP enables multithreaded builds (relevant when there are many files), /bigobj is 129 # needed for bigger binding projects due to the limit to 64k addressable sections 130 target_compile_options(${target_name} PRIVATE /MP /bigobj) 131 132 # Enforce link time code generation on MSVC, except in debug mode 133 target_compile_options(${target_name} PRIVATE $<$<NOT:$<CONFIG:Debug>>:/GL>) 134 135 # Fancy generator expressions don't work with linker flags, for reasons unknown 136 set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE /LTCG) 137 set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL /LTCG) 138 set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO /LTCG) 139 endif() 140endfunction() 141