pybind11Tools.cmake revision 12391
111986Sandreas.sandberg@arm.com# tools/pybind11Tools.cmake -- Build system for the pybind11 modules 211986Sandreas.sandberg@arm.com# 311986Sandreas.sandberg@arm.com# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> 411986Sandreas.sandberg@arm.com# 511986Sandreas.sandberg@arm.com# All rights reserved. Use of this source code is governed by a 611986Sandreas.sandberg@arm.com# BSD-style license that can be found in the LICENSE file. 711986Sandreas.sandberg@arm.com 811986Sandreas.sandberg@arm.comcmake_minimum_required(VERSION 2.8.12) 911986Sandreas.sandberg@arm.com 1011986Sandreas.sandberg@arm.com# Add a CMake parameter for choosing a desired Python version 1112037Sandreas.sandberg@arm.comif(NOT PYBIND11_PYTHON_VERSION) 1212037Sandreas.sandberg@arm.com set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling modules") 1312037Sandreas.sandberg@arm.comendif() 1411986Sandreas.sandberg@arm.com 1511986Sandreas.sandberg@arm.comset(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4) 1611986Sandreas.sandberg@arm.comfind_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED) 1711986Sandreas.sandberg@arm.com 1811986Sandreas.sandberg@arm.cominclude(CheckCXXCompilerFlag) 1912037Sandreas.sandberg@arm.cominclude(CMakeParseArguments) 2011986Sandreas.sandberg@arm.com 2112391Sjason@lowepower.comif(NOT PYBIND11_CPP_STANDARD AND NOT CMAKE_CXX_STANDARD) 2212391Sjason@lowepower.com if(NOT MSVC) 2311986Sandreas.sandberg@arm.com check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG) 2411986Sandreas.sandberg@arm.com 2511986Sandreas.sandberg@arm.com if (HAS_CPP14_FLAG) 2611986Sandreas.sandberg@arm.com set(PYBIND11_CPP_STANDARD -std=c++14) 2711986Sandreas.sandberg@arm.com else() 2812391Sjason@lowepower.com check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG) 2912391Sjason@lowepower.com if (HAS_CPP11_FLAG) 3012391Sjason@lowepower.com set(PYBIND11_CPP_STANDARD -std=c++11) 3112391Sjason@lowepower.com else() 3212391Sjason@lowepower.com message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!") 3312391Sjason@lowepower.com endif() 3411986Sandreas.sandberg@arm.com endif() 3512391Sjason@lowepower.com elseif(MSVC) 3612391Sjason@lowepower.com set(PYBIND11_CPP_STANDARD /std:c++14) 3712391Sjason@lowepower.com endif() 3811986Sandreas.sandberg@arm.com 3912391Sjason@lowepower.com set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING 4012391Sjason@lowepower.com "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to C++14 mode." FORCE) 4112391Sjason@lowepower.comendif() 4211986Sandreas.sandberg@arm.com 4312037Sandreas.sandberg@arm.com# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and 4412037Sandreas.sandberg@arm.com# linkerflags are lists of flags to use. The result variable is a unique variable name for each set 4512037Sandreas.sandberg@arm.com# of flags: the compilation result will be cached base on the result variable. If the flags work, 4612037Sandreas.sandberg@arm.com# sets them in cxxflags_out/linkerflags_out internal cache variables (in addition to ${result}). 4712037Sandreas.sandberg@arm.comfunction(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out linkerflags_out) 4812037Sandreas.sandberg@arm.com set(CMAKE_REQUIRED_LIBRARIES ${linkerflags}) 4912037Sandreas.sandberg@arm.com check_cxx_compiler_flag("${cxxflags}" ${result}) 5012037Sandreas.sandberg@arm.com if (${result}) 5112037Sandreas.sandberg@arm.com set(${cxxflags_out} "${cxxflags}" CACHE INTERNAL "" FORCE) 5212037Sandreas.sandberg@arm.com set(${linkerflags_out} "${linkerflags}" CACHE INTERNAL "" FORCE) 5312037Sandreas.sandberg@arm.com endif() 5412037Sandreas.sandberg@arm.comendfunction() 5512037Sandreas.sandberg@arm.com 5612037Sandreas.sandberg@arm.com# Internal: find the appropriate link time optimization flags for this compiler 5712037Sandreas.sandberg@arm.comfunction(_pybind11_add_lto_flags target_name prefer_thin_lto) 5812037Sandreas.sandberg@arm.com if (NOT DEFINED PYBIND11_LTO_CXX_FLAGS) 5912037Sandreas.sandberg@arm.com set(PYBIND11_LTO_CXX_FLAGS "" CACHE INTERNAL "") 6012037Sandreas.sandberg@arm.com set(PYBIND11_LTO_LINKER_FLAGS "" CACHE INTERNAL "") 6112037Sandreas.sandberg@arm.com 6212037Sandreas.sandberg@arm.com if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") 6312037Sandreas.sandberg@arm.com set(cxx_append "") 6412037Sandreas.sandberg@arm.com set(linker_append "") 6512037Sandreas.sandberg@arm.com if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE) 6612037Sandreas.sandberg@arm.com # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it 6712037Sandreas.sandberg@arm.com set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>") 6812037Sandreas.sandberg@arm.com elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") 6912037Sandreas.sandberg@arm.com set(cxx_append ";-fno-fat-lto-objects") 7012037Sandreas.sandberg@arm.com endif() 7112037Sandreas.sandberg@arm.com 7212037Sandreas.sandberg@arm.com if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto) 7312037Sandreas.sandberg@arm.com _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO_THIN 7412037Sandreas.sandberg@arm.com "-flto=thin${cxx_append}" "-flto=thin${linker_append}" 7512037Sandreas.sandberg@arm.com PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) 7612037Sandreas.sandberg@arm.com endif() 7712037Sandreas.sandberg@arm.com 7812037Sandreas.sandberg@arm.com if (NOT HAS_FLTO_THIN) 7912037Sandreas.sandberg@arm.com _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO 8012037Sandreas.sandberg@arm.com "-flto${cxx_append}" "-flto${linker_append}" 8112037Sandreas.sandberg@arm.com PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) 8212037Sandreas.sandberg@arm.com endif() 8312037Sandreas.sandberg@arm.com elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel") 8412037Sandreas.sandberg@arm.com # Intel equivalent to LTO is called IPO 8512037Sandreas.sandberg@arm.com _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO 8612037Sandreas.sandberg@arm.com "-ipo" "-ipo" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) 8712037Sandreas.sandberg@arm.com elseif(MSVC) 8812037Sandreas.sandberg@arm.com # cmake only interprets libraries as linker flags when they start with a - (otherwise it 8912037Sandreas.sandberg@arm.com # converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags 9012037Sandreas.sandberg@arm.com # with - instead of /, even if it is a bit non-standard: 9112037Sandreas.sandberg@arm.com _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG 9212037Sandreas.sandberg@arm.com "/GL" "-LTCG" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) 9312037Sandreas.sandberg@arm.com endif() 9412037Sandreas.sandberg@arm.com 9512037Sandreas.sandberg@arm.com if (PYBIND11_LTO_CXX_FLAGS) 9612037Sandreas.sandberg@arm.com message(STATUS "LTO enabled") 9712037Sandreas.sandberg@arm.com else() 9812037Sandreas.sandberg@arm.com message(STATUS "LTO disabled (not supported by the compiler and/or linker)") 9912037Sandreas.sandberg@arm.com endif() 10012037Sandreas.sandberg@arm.com endif() 10112037Sandreas.sandberg@arm.com 10212037Sandreas.sandberg@arm.com # Enable LTO flags if found, except for Debug builds 10312037Sandreas.sandberg@arm.com if (PYBIND11_LTO_CXX_FLAGS) 10412037Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:${PYBIND11_LTO_CXX_FLAGS}>") 10512037Sandreas.sandberg@arm.com endif() 10612037Sandreas.sandberg@arm.com if (PYBIND11_LTO_LINKER_FLAGS) 10712037Sandreas.sandberg@arm.com target_link_libraries(${target_name} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:${PYBIND11_LTO_LINKER_FLAGS}>") 10812037Sandreas.sandberg@arm.com endif() 10912037Sandreas.sandberg@arm.comendfunction() 11012037Sandreas.sandberg@arm.com 11111986Sandreas.sandberg@arm.com# Build a Python extension module: 11212037Sandreas.sandberg@arm.com# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL] 11312037Sandreas.sandberg@arm.com# [NO_EXTRAS] [THIN_LTO] source1 [source2 ...]) 11411986Sandreas.sandberg@arm.com# 11511986Sandreas.sandberg@arm.comfunction(pybind11_add_module target_name) 11612037Sandreas.sandberg@arm.com set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS THIN_LTO) 11712037Sandreas.sandberg@arm.com cmake_parse_arguments(ARG "${options}" "" "" ${ARGN}) 11811986Sandreas.sandberg@arm.com 11912037Sandreas.sandberg@arm.com if(ARG_MODULE AND ARG_SHARED) 12012037Sandreas.sandberg@arm.com message(FATAL_ERROR "Can't be both MODULE and SHARED") 12112037Sandreas.sandberg@arm.com elseif(ARG_SHARED) 12212037Sandreas.sandberg@arm.com set(lib_type SHARED) 12312037Sandreas.sandberg@arm.com else() 12412037Sandreas.sandberg@arm.com set(lib_type MODULE) 12512037Sandreas.sandberg@arm.com endif() 12611986Sandreas.sandberg@arm.com 12712037Sandreas.sandberg@arm.com if(ARG_EXCLUDE_FROM_ALL) 12812037Sandreas.sandberg@arm.com set(exclude_from_all EXCLUDE_FROM_ALL) 12912037Sandreas.sandberg@arm.com endif() 13012037Sandreas.sandberg@arm.com 13112037Sandreas.sandberg@arm.com add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS}) 13211986Sandreas.sandberg@arm.com 13311986Sandreas.sandberg@arm.com target_include_directories(${target_name} 13411986Sandreas.sandberg@arm.com PRIVATE ${PYBIND11_INCLUDE_DIR} # from project CMakeLists.txt 13511986Sandreas.sandberg@arm.com PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config 13611986Sandreas.sandberg@arm.com PRIVATE ${PYTHON_INCLUDE_DIRS}) 13711986Sandreas.sandberg@arm.com 13811986Sandreas.sandberg@arm.com # The prefix and extension are provided by FindPythonLibsNew.cmake 13911986Sandreas.sandberg@arm.com set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") 14011986Sandreas.sandberg@arm.com set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}") 14111986Sandreas.sandberg@arm.com 14212391Sjason@lowepower.com # -fvisibility=hidden is required to allow multiple modules compiled against 14312391Sjason@lowepower.com # different pybind versions to work properly, and for some features (e.g. 14412391Sjason@lowepower.com # py::module_local). We force it on everything inside the `pybind11` 14512391Sjason@lowepower.com # namespace; also turning it on for a pybind module compilation here avoids 14612391Sjason@lowepower.com # potential warnings or issues from having mixed hidden/non-hidden types. 14712391Sjason@lowepower.com set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden") 14812391Sjason@lowepower.com 14911986Sandreas.sandberg@arm.com if(WIN32 OR CYGWIN) 15011986Sandreas.sandberg@arm.com # Link against the Python shared library on Windows 15111986Sandreas.sandberg@arm.com target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES}) 15211986Sandreas.sandberg@arm.com elseif(APPLE) 15311986Sandreas.sandberg@arm.com # It's quite common to have multiple copies of the same Python version 15411986Sandreas.sandberg@arm.com # installed on one's system. E.g.: one copy from the OS and another copy 15511986Sandreas.sandberg@arm.com # that's statically linked into an application like Blender or Maya. 15611986Sandreas.sandberg@arm.com # If we link our plugin library against the OS Python here and import it 15711986Sandreas.sandberg@arm.com # into Blender or Maya later on, this will cause segfaults when multiple 15811986Sandreas.sandberg@arm.com # conflicting Python instances are active at the same time (even when they 15911986Sandreas.sandberg@arm.com # are of the same version). 16011986Sandreas.sandberg@arm.com 16111986Sandreas.sandberg@arm.com # Windows is not affected by this issue since it handles DLL imports 16211986Sandreas.sandberg@arm.com # differently. The solution for Linux and Mac OS is simple: we just don't 16311986Sandreas.sandberg@arm.com # link against the Python library. The resulting shared library will have 16411986Sandreas.sandberg@arm.com # missing symbols, but that's perfectly fine -- they will be resolved at 16511986Sandreas.sandberg@arm.com # import time. 16611986Sandreas.sandberg@arm.com 16711986Sandreas.sandberg@arm.com target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup") 16812037Sandreas.sandberg@arm.com 16912037Sandreas.sandberg@arm.com if(ARG_SHARED) 17012037Sandreas.sandberg@arm.com # Suppress CMake >= 3.0 warning for shared libraries 17112037Sandreas.sandberg@arm.com set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON) 17212037Sandreas.sandberg@arm.com endif() 17311986Sandreas.sandberg@arm.com endif() 17411986Sandreas.sandberg@arm.com 17512391Sjason@lowepower.com # Make sure C++11/14 are enabled 17612391Sjason@lowepower.com target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD}) 17711986Sandreas.sandberg@arm.com 17812037Sandreas.sandberg@arm.com if(ARG_NO_EXTRAS) 17912037Sandreas.sandberg@arm.com return() 18012037Sandreas.sandberg@arm.com endif() 18111986Sandreas.sandberg@arm.com 18212037Sandreas.sandberg@arm.com _pybind11_add_lto_flags(${target_name} ${ARG_THIN_LTO}) 18311986Sandreas.sandberg@arm.com 18412037Sandreas.sandberg@arm.com if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug) 18512037Sandreas.sandberg@arm.com # Strip unnecessary sections of the binary on Linux/Mac OS 18612037Sandreas.sandberg@arm.com if(CMAKE_STRIP) 18712037Sandreas.sandberg@arm.com if(APPLE) 18812037Sandreas.sandberg@arm.com add_custom_command(TARGET ${target_name} POST_BUILD 18912037Sandreas.sandberg@arm.com COMMAND ${CMAKE_STRIP} -x $<TARGET_FILE:${target_name}>) 19012037Sandreas.sandberg@arm.com else() 19112037Sandreas.sandberg@arm.com add_custom_command(TARGET ${target_name} POST_BUILD 19212037Sandreas.sandberg@arm.com COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target_name}>) 19311986Sandreas.sandberg@arm.com endif() 19411986Sandreas.sandberg@arm.com endif() 19512037Sandreas.sandberg@arm.com endif() 19612037Sandreas.sandberg@arm.com 19712037Sandreas.sandberg@arm.com if(MSVC) 19811986Sandreas.sandberg@arm.com # /MP enables multithreaded builds (relevant when there are many files), /bigobj is 19911986Sandreas.sandberg@arm.com # needed for bigger binding projects due to the limit to 64k addressable sections 20011986Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE /MP /bigobj) 20111986Sandreas.sandberg@arm.com endif() 20211986Sandreas.sandberg@arm.comendfunction() 203