pybind11Tools.cmake revision 12037
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 2111986Sandreas.sandberg@arm.comfunction(select_cxx_standard) 2211986Sandreas.sandberg@arm.com if(NOT MSVC AND NOT PYBIND11_CPP_STANDARD) 2311986Sandreas.sandberg@arm.com check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG) 2411986Sandreas.sandberg@arm.com check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG) 2511986Sandreas.sandberg@arm.com 2611986Sandreas.sandberg@arm.com if (HAS_CPP14_FLAG) 2711986Sandreas.sandberg@arm.com set(PYBIND11_CPP_STANDARD -std=c++14) 2811986Sandreas.sandberg@arm.com elseif (HAS_CPP11_FLAG) 2911986Sandreas.sandberg@arm.com set(PYBIND11_CPP_STANDARD -std=c++11) 3011986Sandreas.sandberg@arm.com else() 3111986Sandreas.sandberg@arm.com message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!") 3211986Sandreas.sandberg@arm.com endif() 3311986Sandreas.sandberg@arm.com 3411986Sandreas.sandberg@arm.com set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING 3511986Sandreas.sandberg@arm.com "C++ standard flag, e.g. -std=c++11 or -std=c++14. Defaults to latest available." FORCE) 3611986Sandreas.sandberg@arm.com endif() 3711986Sandreas.sandberg@arm.comendfunction() 3811986Sandreas.sandberg@arm.com 3912037Sandreas.sandberg@arm.com# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and 4012037Sandreas.sandberg@arm.com# linkerflags are lists of flags to use. The result variable is a unique variable name for each set 4112037Sandreas.sandberg@arm.com# of flags: the compilation result will be cached base on the result variable. If the flags work, 4212037Sandreas.sandberg@arm.com# sets them in cxxflags_out/linkerflags_out internal cache variables (in addition to ${result}). 4312037Sandreas.sandberg@arm.comfunction(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out linkerflags_out) 4412037Sandreas.sandberg@arm.com set(CMAKE_REQUIRED_LIBRARIES ${linkerflags}) 4512037Sandreas.sandberg@arm.com check_cxx_compiler_flag("${cxxflags}" ${result}) 4612037Sandreas.sandberg@arm.com if (${result}) 4712037Sandreas.sandberg@arm.com set(${cxxflags_out} "${cxxflags}" CACHE INTERNAL "" FORCE) 4812037Sandreas.sandberg@arm.com set(${linkerflags_out} "${linkerflags}" CACHE INTERNAL "" FORCE) 4912037Sandreas.sandberg@arm.com endif() 5012037Sandreas.sandberg@arm.comendfunction() 5112037Sandreas.sandberg@arm.com 5212037Sandreas.sandberg@arm.com# Internal: find the appropriate link time optimization flags for this compiler 5312037Sandreas.sandberg@arm.comfunction(_pybind11_add_lto_flags target_name prefer_thin_lto) 5412037Sandreas.sandberg@arm.com if (NOT DEFINED PYBIND11_LTO_CXX_FLAGS) 5512037Sandreas.sandberg@arm.com set(PYBIND11_LTO_CXX_FLAGS "" CACHE INTERNAL "") 5612037Sandreas.sandberg@arm.com set(PYBIND11_LTO_LINKER_FLAGS "" CACHE INTERNAL "") 5712037Sandreas.sandberg@arm.com 5812037Sandreas.sandberg@arm.com if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") 5912037Sandreas.sandberg@arm.com set(cxx_append "") 6012037Sandreas.sandberg@arm.com set(linker_append "") 6112037Sandreas.sandberg@arm.com if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE) 6212037Sandreas.sandberg@arm.com # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it 6312037Sandreas.sandberg@arm.com set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>") 6412037Sandreas.sandberg@arm.com elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") 6512037Sandreas.sandberg@arm.com set(cxx_append ";-fno-fat-lto-objects") 6612037Sandreas.sandberg@arm.com endif() 6712037Sandreas.sandberg@arm.com 6812037Sandreas.sandberg@arm.com if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto) 6912037Sandreas.sandberg@arm.com _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO_THIN 7012037Sandreas.sandberg@arm.com "-flto=thin${cxx_append}" "-flto=thin${linker_append}" 7112037Sandreas.sandberg@arm.com PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) 7212037Sandreas.sandberg@arm.com endif() 7312037Sandreas.sandberg@arm.com 7412037Sandreas.sandberg@arm.com if (NOT HAS_FLTO_THIN) 7512037Sandreas.sandberg@arm.com _pybind11_return_if_cxx_and_linker_flags_work(HAS_FLTO 7612037Sandreas.sandberg@arm.com "-flto${cxx_append}" "-flto${linker_append}" 7712037Sandreas.sandberg@arm.com PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) 7812037Sandreas.sandberg@arm.com endif() 7912037Sandreas.sandberg@arm.com elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel") 8012037Sandreas.sandberg@arm.com # Intel equivalent to LTO is called IPO 8112037Sandreas.sandberg@arm.com _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO 8212037Sandreas.sandberg@arm.com "-ipo" "-ipo" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) 8312037Sandreas.sandberg@arm.com elseif(MSVC) 8412037Sandreas.sandberg@arm.com # cmake only interprets libraries as linker flags when they start with a - (otherwise it 8512037Sandreas.sandberg@arm.com # converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags 8612037Sandreas.sandberg@arm.com # with - instead of /, even if it is a bit non-standard: 8712037Sandreas.sandberg@arm.com _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG 8812037Sandreas.sandberg@arm.com "/GL" "-LTCG" PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS) 8912037Sandreas.sandberg@arm.com endif() 9012037Sandreas.sandberg@arm.com 9112037Sandreas.sandberg@arm.com if (PYBIND11_LTO_CXX_FLAGS) 9212037Sandreas.sandberg@arm.com message(STATUS "LTO enabled") 9312037Sandreas.sandberg@arm.com else() 9412037Sandreas.sandberg@arm.com message(STATUS "LTO disabled (not supported by the compiler and/or linker)") 9512037Sandreas.sandberg@arm.com endif() 9612037Sandreas.sandberg@arm.com endif() 9712037Sandreas.sandberg@arm.com 9812037Sandreas.sandberg@arm.com # Enable LTO flags if found, except for Debug builds 9912037Sandreas.sandberg@arm.com if (PYBIND11_LTO_CXX_FLAGS) 10012037Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:${PYBIND11_LTO_CXX_FLAGS}>") 10112037Sandreas.sandberg@arm.com endif() 10212037Sandreas.sandberg@arm.com if (PYBIND11_LTO_LINKER_FLAGS) 10312037Sandreas.sandberg@arm.com target_link_libraries(${target_name} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:${PYBIND11_LTO_LINKER_FLAGS}>") 10412037Sandreas.sandberg@arm.com endif() 10512037Sandreas.sandberg@arm.comendfunction() 10612037Sandreas.sandberg@arm.com 10711986Sandreas.sandberg@arm.com# Build a Python extension module: 10812037Sandreas.sandberg@arm.com# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL] 10912037Sandreas.sandberg@arm.com# [NO_EXTRAS] [THIN_LTO] source1 [source2 ...]) 11011986Sandreas.sandberg@arm.com# 11111986Sandreas.sandberg@arm.comfunction(pybind11_add_module target_name) 11212037Sandreas.sandberg@arm.com set(options MODULE SHARED EXCLUDE_FROM_ALL NO_EXTRAS THIN_LTO) 11312037Sandreas.sandberg@arm.com cmake_parse_arguments(ARG "${options}" "" "" ${ARGN}) 11411986Sandreas.sandberg@arm.com 11512037Sandreas.sandberg@arm.com if(ARG_MODULE AND ARG_SHARED) 11612037Sandreas.sandberg@arm.com message(FATAL_ERROR "Can't be both MODULE and SHARED") 11712037Sandreas.sandberg@arm.com elseif(ARG_SHARED) 11812037Sandreas.sandberg@arm.com set(lib_type SHARED) 11912037Sandreas.sandberg@arm.com else() 12012037Sandreas.sandberg@arm.com set(lib_type MODULE) 12112037Sandreas.sandberg@arm.com endif() 12211986Sandreas.sandberg@arm.com 12312037Sandreas.sandberg@arm.com if(ARG_EXCLUDE_FROM_ALL) 12412037Sandreas.sandberg@arm.com set(exclude_from_all EXCLUDE_FROM_ALL) 12512037Sandreas.sandberg@arm.com endif() 12612037Sandreas.sandberg@arm.com 12712037Sandreas.sandberg@arm.com add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS}) 12811986Sandreas.sandberg@arm.com 12911986Sandreas.sandberg@arm.com target_include_directories(${target_name} 13011986Sandreas.sandberg@arm.com PRIVATE ${PYBIND11_INCLUDE_DIR} # from project CMakeLists.txt 13111986Sandreas.sandberg@arm.com PRIVATE ${pybind11_INCLUDE_DIR} # from pybind11Config 13211986Sandreas.sandberg@arm.com PRIVATE ${PYTHON_INCLUDE_DIRS}) 13311986Sandreas.sandberg@arm.com 13411986Sandreas.sandberg@arm.com # The prefix and extension are provided by FindPythonLibsNew.cmake 13511986Sandreas.sandberg@arm.com set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") 13611986Sandreas.sandberg@arm.com set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}") 13711986Sandreas.sandberg@arm.com 13811986Sandreas.sandberg@arm.com if(WIN32 OR CYGWIN) 13911986Sandreas.sandberg@arm.com # Link against the Python shared library on Windows 14011986Sandreas.sandberg@arm.com target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES}) 14111986Sandreas.sandberg@arm.com elseif(APPLE) 14211986Sandreas.sandberg@arm.com # It's quite common to have multiple copies of the same Python version 14311986Sandreas.sandberg@arm.com # installed on one's system. E.g.: one copy from the OS and another copy 14411986Sandreas.sandberg@arm.com # that's statically linked into an application like Blender or Maya. 14511986Sandreas.sandberg@arm.com # If we link our plugin library against the OS Python here and import it 14611986Sandreas.sandberg@arm.com # into Blender or Maya later on, this will cause segfaults when multiple 14711986Sandreas.sandberg@arm.com # conflicting Python instances are active at the same time (even when they 14811986Sandreas.sandberg@arm.com # are of the same version). 14911986Sandreas.sandberg@arm.com 15011986Sandreas.sandberg@arm.com # Windows is not affected by this issue since it handles DLL imports 15111986Sandreas.sandberg@arm.com # differently. The solution for Linux and Mac OS is simple: we just don't 15211986Sandreas.sandberg@arm.com # link against the Python library. The resulting shared library will have 15311986Sandreas.sandberg@arm.com # missing symbols, but that's perfectly fine -- they will be resolved at 15411986Sandreas.sandberg@arm.com # import time. 15511986Sandreas.sandberg@arm.com 15611986Sandreas.sandberg@arm.com target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup") 15712037Sandreas.sandberg@arm.com 15812037Sandreas.sandberg@arm.com if(ARG_SHARED) 15912037Sandreas.sandberg@arm.com # Suppress CMake >= 3.0 warning for shared libraries 16012037Sandreas.sandberg@arm.com set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON) 16112037Sandreas.sandberg@arm.com endif() 16211986Sandreas.sandberg@arm.com endif() 16311986Sandreas.sandberg@arm.com 16411986Sandreas.sandberg@arm.com select_cxx_standard() 16511986Sandreas.sandberg@arm.com if(NOT MSVC) 16611986Sandreas.sandberg@arm.com # Make sure C++11/14 are enabled 16711986Sandreas.sandberg@arm.com target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD}) 16812037Sandreas.sandberg@arm.com endif() 16911986Sandreas.sandberg@arm.com 17012037Sandreas.sandberg@arm.com if(ARG_NO_EXTRAS) 17112037Sandreas.sandberg@arm.com return() 17212037Sandreas.sandberg@arm.com endif() 17311986Sandreas.sandberg@arm.com 17412037Sandreas.sandberg@arm.com _pybind11_add_lto_flags(${target_name} ${ARG_THIN_LTO}) 17511986Sandreas.sandberg@arm.com 17612037Sandreas.sandberg@arm.com if (NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug) 17712037Sandreas.sandberg@arm.com # Set the default symbol visibility to hidden (very important to obtain small binaries) 17812037Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE "-fvisibility=hidden") 17911986Sandreas.sandberg@arm.com 18012037Sandreas.sandberg@arm.com # Strip unnecessary sections of the binary on Linux/Mac OS 18112037Sandreas.sandberg@arm.com if(CMAKE_STRIP) 18212037Sandreas.sandberg@arm.com if(APPLE) 18312037Sandreas.sandberg@arm.com add_custom_command(TARGET ${target_name} POST_BUILD 18412037Sandreas.sandberg@arm.com COMMAND ${CMAKE_STRIP} -x $<TARGET_FILE:${target_name}>) 18512037Sandreas.sandberg@arm.com else() 18612037Sandreas.sandberg@arm.com add_custom_command(TARGET ${target_name} POST_BUILD 18712037Sandreas.sandberg@arm.com COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target_name}>) 18811986Sandreas.sandberg@arm.com endif() 18911986Sandreas.sandberg@arm.com endif() 19012037Sandreas.sandberg@arm.com endif() 19112037Sandreas.sandberg@arm.com 19212037Sandreas.sandberg@arm.com if(MSVC) 19311986Sandreas.sandberg@arm.com # /MP enables multithreaded builds (relevant when there are many files), /bigobj is 19411986Sandreas.sandberg@arm.com # needed for bigger binding projects due to the limit to 64k addressable sections 19511986Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE /MP /bigobj) 19611986Sandreas.sandberg@arm.com endif() 19711986Sandreas.sandberg@arm.comendfunction() 198