mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
Merge pull request #207 from dean0x7d/cmake
Simplify CMake build using add_subdirectory
This commit is contained in:
commit
1503d2fb50
@ -9,6 +9,7 @@ addons:
|
|||||||
sources:
|
sources:
|
||||||
- ubuntu-toolchain-r-test
|
- ubuntu-toolchain-r-test
|
||||||
- deadsnakes
|
- deadsnakes
|
||||||
|
- kubuntu-backports # cmake 2.8.12
|
||||||
packages:
|
packages:
|
||||||
- g++-4.8
|
- g++-4.8
|
||||||
- g++-4.8-multilib
|
- g++-4.8-multilib
|
||||||
@ -17,6 +18,7 @@ addons:
|
|||||||
- python3.5-dev
|
- python3.5-dev
|
||||||
- python3.5-venv
|
- python3.5-venv
|
||||||
- python3.5-dev:i386
|
- python3.5-dev:i386
|
||||||
|
- cmake
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
|
304
CMakeLists.txt
304
CMakeLists.txt
@ -5,187 +5,62 @@
|
|||||||
# All rights reserved. Use of this source code is governed by a
|
# All rights reserved. Use of this source code is governed by a
|
||||||
# BSD-style license that can be found in the LICENSE file.
|
# BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
|
|
||||||
project(pybind11)
|
project(pybind11)
|
||||||
|
|
||||||
option(PYBIND11_INSTALL "Install pybind11 header files?" ON)
|
# Check if pybind11 is being used directly or via add_subdirectory
|
||||||
|
set(PYBIND11_MASTER_PROJECT OFF)
|
||||||
|
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||||
|
set(PYBIND11_MASTER_PROJECT ON)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
|
||||||
|
option(PYBIND11_TEST "Build tests?" ${PYBIND11_MASTER_PROJECT})
|
||||||
|
|
||||||
# Add a CMake parameter for choosing a desired Python version
|
# Add a CMake parameter for choosing a desired Python version
|
||||||
set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling the example application")
|
set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling the example application")
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools")
|
||||||
|
set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
|
||||||
|
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
# Set a default build configuration if none is specified. 'MinSizeRel' produces the smallest binaries
|
if(NOT MSVC AND NOT PYBIND11_CPP_STANDARD)
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
|
||||||
message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
|
check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
|
||||||
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
|
|
||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
|
|
||||||
"MinSizeRel" "RelWithDebInfo")
|
|
||||||
endif()
|
|
||||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
|
|
||||||
|
|
||||||
set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
|
|
||||||
if (NOT ${PYBIND11_PYTHON_VERSION} STREQUAL "")
|
|
||||||
find_package(PythonLibs ${PYBIND11_PYTHON_VERSION} EXACT)
|
|
||||||
if (NOT PYTHONLIBS_FOUND)
|
|
||||||
find_package(PythonLibs ${PYBIND11_PYTHON_VERSION} REQUIRED)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
find_package(PythonLibs REQUIRED)
|
|
||||||
endif()
|
|
||||||
# The above sometimes returns version numbers like "3.4.3+"; the "+" must be removed for the next line to work
|
|
||||||
string(REPLACE "+" "" PYTHONLIBS_VERSION_STRING "+${PYTHONLIBS_VERSION_STRING}")
|
|
||||||
find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED)
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG)
|
|
||||||
|
|
||||||
if (HAS_CPP14_FLAG)
|
if (HAS_CPP14_FLAG)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
set(PYBIND11_CPP_STANDARD -std=c++14)
|
||||||
elseif (HAS_CPP11_FLAG)
|
elseif (HAS_CPP11_FLAG)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
set(PYBIND11_CPP_STANDARD -std=c++11)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
|
message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Enable link time optimization and set the default symbol
|
set(PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
|
||||||
# visibility to hidden (very important to obtain small binaries)
|
"C++ standard flag, e.g. -std=c++11 or -std=c++14. Defaults to latest available.")
|
||||||
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
|
|
||||||
# Default symbol visibility
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
|
||||||
|
|
||||||
# Check for Link Time Optimization support
|
|
||||||
# (GCC/Clang)
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
|
|
||||||
if (HAS_LTO_FLAG)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Intel equivalent to LTO is called IPO
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-ipo" HAS_IPO_FLAG)
|
|
||||||
if (HAS_IPO_FLAG)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ipo")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Compile with compiler warnings turned on
|
# Cache variables so pybind11_add_module can be used in parent projects
|
||||||
if(MSVC)
|
set(PYBIND11_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include" CACHE INTERNAL "")
|
||||||
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} CACHE INTERNAL "")
|
||||||
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
set(PYTHON_LIBRARIES ${PYTHON_LIBRARIES} CACHE INTERNAL "")
|
||||||
else()
|
set(PYTHON_MODULE_PREFIX ${PYTHON_MODULE_PREFIX} CACHE INTERNAL "")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} CACHE INTERNAL "")
|
||||||
endif()
|
|
||||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
# Build a Python extension module:
|
||||||
|
# pybind11_add_module(<name> source1 [source2 ...])
|
||||||
|
#
|
||||||
|
function(pybind11_add_module target_name)
|
||||||
|
add_library(${target_name} MODULE ${ARGN})
|
||||||
|
target_include_directories(${target_name} PUBLIC ${PYBIND11_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS})
|
||||||
|
|
||||||
# Check if Eigen is available
|
# The prefix and extension are provided by FindPythonLibsNew.cmake
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools")
|
set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
|
||||||
find_package(Eigen3 QUIET)
|
set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
||||||
|
|
||||||
# Include path for pybind11 header files
|
|
||||||
include_directories(include)
|
|
||||||
|
|
||||||
# Include path for Python header files
|
|
||||||
include_directories(${PYTHON_INCLUDE_DIR})
|
|
||||||
|
|
||||||
set(PYBIND11_HEADERS
|
|
||||||
include/pybind11/attr.h
|
|
||||||
include/pybind11/cast.h
|
|
||||||
include/pybind11/common.h
|
|
||||||
include/pybind11/complex.h
|
|
||||||
include/pybind11/descr.h
|
|
||||||
include/pybind11/eigen.h
|
|
||||||
include/pybind11/functional.h
|
|
||||||
include/pybind11/numpy.h
|
|
||||||
include/pybind11/operators.h
|
|
||||||
include/pybind11/pybind11.h
|
|
||||||
include/pybind11/pytypes.h
|
|
||||||
include/pybind11/stl.h
|
|
||||||
include/pybind11/stl_bind.h
|
|
||||||
include/pybind11/typeid.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(PYBIND11_EXAMPLES
|
|
||||||
example/example1.cpp
|
|
||||||
example/example2.cpp
|
|
||||||
example/example3.cpp
|
|
||||||
example/example4.cpp
|
|
||||||
example/example5.cpp
|
|
||||||
example/example6.cpp
|
|
||||||
example/example7.cpp
|
|
||||||
example/example8.cpp
|
|
||||||
example/example9.cpp
|
|
||||||
example/example10.cpp
|
|
||||||
example/example11.cpp
|
|
||||||
example/example12.cpp
|
|
||||||
example/example13.cpp
|
|
||||||
example/example14.cpp
|
|
||||||
example/example15.cpp
|
|
||||||
example/example16.cpp
|
|
||||||
example/example17.cpp
|
|
||||||
example/issues.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
if (EIGEN3_FOUND)
|
|
||||||
include_directories(${EIGEN3_INCLUDE_DIR})
|
|
||||||
list(APPEND PYBIND11_EXAMPLES example/eigen.cpp)
|
|
||||||
add_definitions(-DPYBIND11_TEST_EIGEN)
|
|
||||||
message(STATUS "Building Eigen testcase")
|
|
||||||
else()
|
|
||||||
message(STATUS "NOT Building Eigen testcase")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Create the binding library
|
|
||||||
add_library(example SHARED
|
|
||||||
${PYBIND11_HEADERS}
|
|
||||||
example/example.cpp
|
|
||||||
${PYBIND11_EXAMPLES}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Don't add a 'lib' prefix to the shared library
|
|
||||||
set_target_properties(example PROPERTIES PREFIX "")
|
|
||||||
|
|
||||||
# Always write the output file directly into the 'example' directory (even on MSVC)
|
|
||||||
set(CompilerFlags
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_RELEASE LIBRARY_OUTPUT_DIRECTORY_DEBUG
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_RELEASE RUNTIME_OUTPUT_DIRECTORY_DEBUG
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO)
|
|
||||||
|
|
||||||
foreach(CompilerFlag ${CompilerFlags})
|
|
||||||
set_target_properties(example PROPERTIES ${CompilerFlag} ${PROJECT_SOURCE_DIR}/example)
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
if (MSVC)
|
|
||||||
# /MP enables multithreaded builds (relevant when there are many files), /bigobj is
|
|
||||||
# needed for bigger binding projects due to the limit to 64k addressable sections
|
|
||||||
set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS /MP /bigobj)
|
|
||||||
# Enforce size-based optimization and link time code generation on MSVC
|
|
||||||
# (~30% smaller binaries in experiments); do nothing in debug mode.
|
|
||||||
set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS
|
|
||||||
"$<$<CONFIG:Release>:/Os>" "$<$<CONFIG:Release>:/GL>"
|
|
||||||
"$<$<CONFIG:MinSizeRel>:/Os>" "$<$<CONFIG:MinSizeRel>:/GL>"
|
|
||||||
"$<$<CONFIG:RelWithDebInfo>:/Os>" "$<$<CONFIG:RelWithDebInfo>:/GL>"
|
|
||||||
)
|
|
||||||
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELEASE "/LTCG ")
|
|
||||||
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL "/LTCG ")
|
|
||||||
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO "/LTCG ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# .PYD file extension on Windows
|
|
||||||
set_target_properties(example PROPERTIES SUFFIX ".pyd")
|
|
||||||
|
|
||||||
# Link against the Python shared library
|
|
||||||
target_link_libraries(example ${PYTHON_LIBRARY})
|
|
||||||
elseif (UNIX)
|
|
||||||
# It's quite common to have multiple copies of the same Python version
|
# It's quite common to have multiple copies of the same Python version
|
||||||
# installed on one's system. E.g.: one copy from the OS and another copy
|
# installed on one's system. E.g.: one copy from the OS and another copy
|
||||||
# that's statically linked into an application like Blender or Maya.
|
# that's statically linked into an application like Blender or Maya.
|
||||||
@ -199,41 +74,94 @@ elseif (UNIX)
|
|||||||
# link against the Python library. The resulting shared library will have
|
# link against the Python library. The resulting shared library will have
|
||||||
# missing symbols, but that's perfectly fine -- they will be resolved at
|
# missing symbols, but that's perfectly fine -- they will be resolved at
|
||||||
# import time.
|
# import time.
|
||||||
|
if(MSVC)
|
||||||
# .SO file extension on Linux/Mac OS
|
target_link_libraries(${target_name} PRIVATE ${PYTHON_LIBRARIES})
|
||||||
set_target_properties(example PROPERTIES SUFFIX ".so")
|
elseif(APPLE)
|
||||||
|
# Make sure OS X does not have any issues with missing symbols
|
||||||
# Optimize for a small binary size
|
target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup")
|
||||||
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
|
|
||||||
set_target_properties(example PROPERTIES COMPILE_FLAGS "-Os")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Strip unnecessary sections of the binary on Linux/Mac OS
|
if(NOT MSVC)
|
||||||
if(APPLE)
|
# Make sure C++11/14 are enabled
|
||||||
set_target_properties(example PROPERTIES MACOSX_RPATH ".")
|
target_compile_options(${target_name} PUBLIC ${PYBIND11_CPP_STANDARD})
|
||||||
set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
|
|
||||||
|
# Enable link time optimization and set the default symbol
|
||||||
|
# visibility to hidden (very important to obtain small binaries)
|
||||||
|
string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
|
||||||
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
|
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
|
||||||
add_custom_command(TARGET example POST_BUILD COMMAND strip -u -r ${PROJECT_SOURCE_DIR}/example/example.so)
|
# Check for Link Time Optimization support (GCC/Clang)
|
||||||
|
check_cxx_compiler_flag("-flto" HAS_LTO_FLAG)
|
||||||
|
if(HAS_LTO_FLAG)
|
||||||
|
target_compile_options(${target_name} PRIVATE -flto)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Intel equivalent to LTO is called IPO
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||||
|
check_cxx_compiler_flag("-ipo" HAS_IPO_FLAG)
|
||||||
|
if(HAS_IPO_FLAG)
|
||||||
|
target_compile_options(${target_name} PRIVATE -ipo)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Default symbol visibility
|
||||||
|
target_compile_options(${target_name} PRIVATE "-fvisibility=hidden")
|
||||||
|
|
||||||
|
# Strip unnecessary sections of the binary on Linux/Mac OS
|
||||||
|
if(CMAKE_STRIP)
|
||||||
|
if(APPLE)
|
||||||
|
add_custom_command(TARGET ${target_name} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} -u -r $<TARGET_FILE:${target_name}>)
|
||||||
|
else()
|
||||||
|
add_custom_command(TARGET ${target_name} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target_name}>)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
elseif(MSVC)
|
||||||
|
# /MP enables multithreaded builds (relevant when there are many files), /bigobj is
|
||||||
|
# needed for bigger binding projects due to the limit to 64k addressable sections
|
||||||
|
target_compile_options(${target_name} PRIVATE /MP /bigobj)
|
||||||
|
|
||||||
|
# Enforce link time code generation on MSVC, except in debug mode
|
||||||
|
target_compile_options(${target_name} PRIVATE $<$<NOT:$<CONFIG:Debug>>:/GL>)
|
||||||
|
# Fancy generator expressions don't work with linker flags, for reasons unknown
|
||||||
|
set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE /LTCG)
|
||||||
|
set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL /LTCG)
|
||||||
|
set_property(TARGET ${target_name} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO /LTCG)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Compile with compiler warnings turned on
|
||||||
|
function(pybind11_turn_on_warnings target_name)
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(${target_name} PRIVATE /W4)
|
||||||
else()
|
else()
|
||||||
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
|
target_compile_options(${target_name} PRIVATE -Wall -Wextra)
|
||||||
add_custom_command(TARGET example POST_BUILD COMMAND strip ${PROJECT_SOURCE_DIR}/example/example.so)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
if (PYBIND11_TEST)
|
||||||
|
enable_testing()
|
||||||
|
add_subdirectory(example)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
enable_testing()
|
|
||||||
|
|
||||||
set(RUN_TEST ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/run_test.py)
|
|
||||||
if (MSVC OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
|
||||||
set(RUN_TEST ${RUN_TEST} --relaxed)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
foreach(VALUE ${PYBIND11_EXAMPLES})
|
|
||||||
string(REGEX REPLACE "^example/(.+).cpp$" "\\1" EXAMPLE_NAME "${VALUE}")
|
|
||||||
add_test(NAME ${EXAMPLE_NAME} COMMAND ${RUN_TEST} ${EXAMPLE_NAME})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
if (PYBIND11_INSTALL)
|
if (PYBIND11_INSTALL)
|
||||||
install(FILES ${PYBIND11_HEADERS} DESTINATION include/pybind11)
|
set(PYBIND11_HEADERS
|
||||||
|
include/pybind11/attr.h
|
||||||
|
include/pybind11/cast.h
|
||||||
|
include/pybind11/common.h
|
||||||
|
include/pybind11/complex.h
|
||||||
|
include/pybind11/descr.h
|
||||||
|
include/pybind11/eigen.h
|
||||||
|
include/pybind11/functional.h
|
||||||
|
include/pybind11/numpy.h
|
||||||
|
include/pybind11/operators.h
|
||||||
|
include/pybind11/pybind11.h
|
||||||
|
include/pybind11/pytypes.h
|
||||||
|
include/pybind11/stl.h
|
||||||
|
include/pybind11/stl_bind.h
|
||||||
|
include/pybind11/typeid.h
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES ${PYBIND11_HEADERS} DESTINATION include/pybind11)
|
||||||
endif()
|
endif()
|
||||||
|
@ -26,146 +26,28 @@ Building with cppimport
|
|||||||
Building with CMake
|
Building with CMake
|
||||||
===================
|
===================
|
||||||
|
|
||||||
For C++ codebases that already have an existing CMake-based build system, the
|
For C++ codebases that have an existing CMake-based build system, a Python
|
||||||
following snippet should be a good starting point to create bindings across
|
extension module can be created with just a few lines of code:
|
||||||
platforms. It assumes that the code is located in a file named
|
|
||||||
:file:`example.cpp`, and that the pybind11 repository is located in a
|
|
||||||
subdirectory named :file:`pybind11`.
|
|
||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
|
|
||||||
project(example)
|
project(example)
|
||||||
|
|
||||||
# Add a CMake parameter for choosing a desired Python version
|
add_subdirectory(pybind11)
|
||||||
set(EXAMPLE_PYTHON_VERSION "" CACHE STRING
|
pybind11_add_module(example example.cpp)
|
||||||
"Python version to use for compiling the example library")
|
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
This assumes that the pybind11 repository is located in a subdirectory named
|
||||||
|
:file:`pybind11` and that the code is located in a file named :file:`example.cpp`.
|
||||||
|
The CMake command ``add_subdirectory`` will import a function with the signature
|
||||||
|
``pybind11_add_module(<name> source1 [source2 ...])``. It will take care of all
|
||||||
|
the details needed to build a Python extension module on any platform.
|
||||||
|
|
||||||
# Set a default build configuration if none is specified.
|
The target Python version can be selected by setting the ``PYBIND11_PYTHON_VERSION``
|
||||||
# 'MinSizeRel' produces the smallest binaries
|
variable before adding the pybind11 subdirectory. Alternatively, an exact Python
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
installation can be specified by setting ``PYTHON_EXECUTABLE``.
|
||||||
message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
|
|
||||||
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
|
|
||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
|
|
||||||
"MinSizeRel" "RelWithDebInfo")
|
|
||||||
endif()
|
|
||||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
|
|
||||||
|
|
||||||
# Try to autodetect Python (can be overridden manually if needed)
|
A working sample project, including a way to invoke CMake from :file:`setup.py` for
|
||||||
set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
|
PyPI integration, can be found in the [cmake_example]_ repository.
|
||||||
if (NOT ${EXAMPLE_PYTHON_VERSION} STREQUAL "")
|
|
||||||
find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} EXACT)
|
|
||||||
if (NOT PYTHONLIBS_FOUND)
|
|
||||||
find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} REQUIRED)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
find_package(PythonLibs REQUIRED)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# The above sometimes returns version numbers like "3.4.3+";
|
.. [cmake_example] https://github.com/dean0x7d/pybind11_cmake_example
|
||||||
# the "+" must be removed for the next lines to work
|
|
||||||
string(REPLACE "+" "" PYTHONLIBS_VERSION_STRING "+${PYTHONLIBS_VERSION_STRING}")
|
|
||||||
|
|
||||||
# Uncomment the following line if you will also require a matching Python interpreter
|
|
||||||
# find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED)
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG)
|
|
||||||
|
|
||||||
if (HAS_CPP14_FLAG)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
|
|
||||||
elseif (HAS_CPP11_FLAG)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unsupported compiler -- at least C++11 support is needed!")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Enable link time optimization and set the default symbol
|
|
||||||
# visibility to hidden (very important to obtain small binaries)
|
|
||||||
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
|
|
||||||
# Default symbol visibility
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
|
||||||
|
|
||||||
# Check for Link Time Optimization support
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
|
|
||||||
if (HAS_LTO_FLAG)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Include path for Python header files
|
|
||||||
include_directories(${PYTHON_INCLUDE_DIR})
|
|
||||||
|
|
||||||
# Include path for pybind11 header files -- this may need to be
|
|
||||||
# changed depending on your setup
|
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/pybind11/include)
|
|
||||||
|
|
||||||
# Create the binding library
|
|
||||||
add_library(example SHARED
|
|
||||||
example.cpp
|
|
||||||
# ... extra files go here ...
|
|
||||||
)
|
|
||||||
|
|
||||||
# Don't add a 'lib' prefix to the shared library
|
|
||||||
set_target_properties(example PROPERTIES PREFIX "")
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
if (MSVC)
|
|
||||||
# /MP enables multithreaded builds (relevant when there are many files), /bigobj is
|
|
||||||
# needed for bigger binding projects due to the limit to 64k addressable sections
|
|
||||||
set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS /MP /bigobj)
|
|
||||||
# Enforce size-based optimization and link time code generation on MSVC
|
|
||||||
# (~30% smaller binaries in experiments); do nothing in debug mode.
|
|
||||||
set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS
|
|
||||||
"$<$<CONFIG:Release>:/Os>" "$<$<CONFIG:Release>:/GL>"
|
|
||||||
"$<$<CONFIG:MinSizeRel>:/Os>" "$<$<CONFIG:MinSizeRel>:/GL>"
|
|
||||||
"$<$<CONFIG:RelWithDebInfo>:/Os>" "$<$<CONFIG:RelWithDebInfo>:/GL>"
|
|
||||||
)
|
|
||||||
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELEASE "/LTCG ")
|
|
||||||
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL "/LTCG ")
|
|
||||||
set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO "/LTCG ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# .PYD file extension on Windows
|
|
||||||
set_target_properties(example PROPERTIES SUFFIX ".pyd")
|
|
||||||
|
|
||||||
# Link against the Python shared library
|
|
||||||
target_link_libraries(example ${PYTHON_LIBRARY})
|
|
||||||
elseif (UNIX)
|
|
||||||
# It's quite common to have multiple copies of the same Python version
|
|
||||||
# installed on one's system. E.g.: one copy from the OS and another copy
|
|
||||||
# that's statically linked into an application like Blender or Maya.
|
|
||||||
# If we link our plugin library against the OS Python here and import it
|
|
||||||
# into Blender or Maya later on, this will cause segfaults when multiple
|
|
||||||
# conflicting Python instances are active at the same time (even when they
|
|
||||||
# are of the same version).
|
|
||||||
|
|
||||||
# Windows is not affected by this issue since it handles DLL imports
|
|
||||||
# differently. The solution for Linux and Mac OS is simple: we just don't
|
|
||||||
# link against the Python library. The resulting shared library will have
|
|
||||||
# missing symbols, but that's perfectly fine -- they will be resolved at
|
|
||||||
# import time.
|
|
||||||
|
|
||||||
# .SO file extension on Linux/Mac OS
|
|
||||||
set_target_properties(example PROPERTIES SUFFIX ".so")
|
|
||||||
|
|
||||||
# Strip unnecessary sections of the binary on Linux/Mac OS
|
|
||||||
if(APPLE)
|
|
||||||
set_target_properties(example PROPERTIES MACOSX_RPATH ".")
|
|
||||||
set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
|
|
||||||
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
|
|
||||||
add_custom_command(TARGET example POST_BUILD
|
|
||||||
COMMAND strip -u -r ${PROJECT_BINARY_DIR}/example.so)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
|
|
||||||
add_custom_command(TARGET example POST_BUILD
|
|
||||||
COMMAND strip ${PROJECT_BINARY_DIR}/example.so)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
68
example/CMakeLists.txt
Normal file
68
example/CMakeLists.txt
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# Set a default build configuration if none is specified. 'MinSizeRel' produces the smallest binaries
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
|
||||||
|
set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
|
||||||
|
"MinSizeRel" "RelWithDebInfo")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(PYBIND11_EXAMPLES
|
||||||
|
example1.cpp
|
||||||
|
example2.cpp
|
||||||
|
example3.cpp
|
||||||
|
example4.cpp
|
||||||
|
example5.cpp
|
||||||
|
example6.cpp
|
||||||
|
example7.cpp
|
||||||
|
example8.cpp
|
||||||
|
example9.cpp
|
||||||
|
example10.cpp
|
||||||
|
example11.cpp
|
||||||
|
example12.cpp
|
||||||
|
example13.cpp
|
||||||
|
example14.cpp
|
||||||
|
example15.cpp
|
||||||
|
example16.cpp
|
||||||
|
example17.cpp
|
||||||
|
issues.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if Eigen is available
|
||||||
|
find_package(Eigen3 QUIET)
|
||||||
|
|
||||||
|
if(EIGEN3_FOUND)
|
||||||
|
list(APPEND PYBIND11_EXAMPLES eigen.cpp)
|
||||||
|
message(STATUS "Building Eigen testcase")
|
||||||
|
else()
|
||||||
|
message(STATUS "NOT Building Eigen testcase")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create the binding library
|
||||||
|
pybind11_add_module(example example.cpp ${PYBIND11_EXAMPLES})
|
||||||
|
pybind11_turn_on_warnings(example)
|
||||||
|
|
||||||
|
if(EIGEN3_FOUND)
|
||||||
|
target_include_directories(example PRIVATE ${EIGEN3_INCLUDE_DIR})
|
||||||
|
target_compile_definitions(example PRIVATE -DPYBIND11_TEST_EIGEN)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Always write the output file directly into the 'example' directory (even on MSVC)
|
||||||
|
set(CompilerFlags
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_RELEASE LIBRARY_OUTPUT_DIRECTORY_DEBUG
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_RELEASE RUNTIME_OUTPUT_DIRECTORY_DEBUG
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO)
|
||||||
|
|
||||||
|
foreach(CompilerFlag ${CompilerFlags})
|
||||||
|
set_target_properties(example PROPERTIES ${CompilerFlag} ${PROJECT_SOURCE_DIR}/example)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(RUN_TEST ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_test.py)
|
||||||
|
if(MSVC OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||||
|
set(RUN_TEST ${RUN_TEST} --relaxed)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(VALUE ${PYBIND11_EXAMPLES})
|
||||||
|
string(REGEX REPLACE "^(.+).cpp$" "\\1" EXAMPLE_NAME "${VALUE}")
|
||||||
|
add_test(NAME ${EXAMPLE_NAME} COMMAND ${RUN_TEST} ${EXAMPLE_NAME})
|
||||||
|
endforeach()
|
187
tools/FindPythonLibsNew.cmake
Normal file
187
tools/FindPythonLibsNew.cmake
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
# - Find python libraries
|
||||||
|
# This module finds the libraries corresponding to the Python interpeter
|
||||||
|
# FindPythonInterp provides.
|
||||||
|
# This code sets the following variables:
|
||||||
|
#
|
||||||
|
# PYTHONLIBS_FOUND - have the Python libs been found
|
||||||
|
# PYTHON_PREFIX - path to the Python installation
|
||||||
|
# PYTHON_LIBRARIES - path to the python library
|
||||||
|
# PYTHON_INCLUDE_DIRS - path to where Python.h is found
|
||||||
|
# PYTHON_SITE_PACKAGES - path to installation site-packages
|
||||||
|
# PYTHON_IS_DEBUG - whether the Python interpreter is a debug build
|
||||||
|
#
|
||||||
|
# PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated)
|
||||||
|
#
|
||||||
|
# A function PYTHON_ADD_MODULE(<name> src1 src2 ... srcN) is defined
|
||||||
|
# to build modules for python.
|
||||||
|
#
|
||||||
|
# Thanks to talljimbo for the patch adding the 'LDVERSION' config
|
||||||
|
# variable usage.
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2001-2009 Kitware, Inc.
|
||||||
|
# Copyright 2012 Continuum Analytics, Inc.
|
||||||
|
#
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||||
|
# nor the names of their contributors may be used to endorse or promote
|
||||||
|
# products derived from this software without specific prior written
|
||||||
|
# permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
# Use the Python interpreter to find the libs.
|
||||||
|
if(PythonLibsNew_FIND_REQUIRED)
|
||||||
|
find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} REQUIRED)
|
||||||
|
else()
|
||||||
|
find_package(PythonInterp ${PythonLibsNew_FIND_VERSION})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT PYTHONINTERP_FOUND)
|
||||||
|
set(PYTHONLIBS_FOUND FALSE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# According to http://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter
|
||||||
|
# testing whether sys has the gettotalrefcount function is a reliable, cross-platform
|
||||||
|
# way to detect a CPython debug interpreter.
|
||||||
|
#
|
||||||
|
# The library suffix is from the config var LDVERSION sometimes, otherwise
|
||||||
|
# VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows.
|
||||||
|
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
|
||||||
|
"from distutils import sysconfig as s;import sys;import struct;
|
||||||
|
print('.'.join(str(v) for v in sys.version_info));
|
||||||
|
print(sys.prefix);
|
||||||
|
print(s.get_python_inc(plat_specific=True));
|
||||||
|
print(s.get_python_lib(plat_specific=True));
|
||||||
|
print(s.get_config_var('SO'));
|
||||||
|
print(hasattr(sys, 'gettotalrefcount')+0);
|
||||||
|
print(struct.calcsize('@P'));
|
||||||
|
print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION'));
|
||||||
|
"
|
||||||
|
RESULT_VARIABLE _PYTHON_SUCCESS
|
||||||
|
OUTPUT_VARIABLE _PYTHON_VALUES
|
||||||
|
ERROR_VARIABLE _PYTHON_ERROR_VALUE
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
|
if(NOT _PYTHON_SUCCESS MATCHES 0)
|
||||||
|
if(PythonLibsNew_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Python config failure:\n${_PYTHON_ERROR_VALUE}")
|
||||||
|
endif()
|
||||||
|
set(PYTHONLIBS_FOUND FALSE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Convert the process output into a list
|
||||||
|
string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES})
|
||||||
|
string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES})
|
||||||
|
list(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST)
|
||||||
|
list(GET _PYTHON_VALUES 1 PYTHON_PREFIX)
|
||||||
|
list(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)
|
||||||
|
list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)
|
||||||
|
list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)
|
||||||
|
list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG)
|
||||||
|
list(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)
|
||||||
|
list(GET _PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX)
|
||||||
|
|
||||||
|
# Make sure the Python has the same pointer-size as the chosen compiler
|
||||||
|
# Skip if CMAKE_SIZEOF_VOID_P is not defined
|
||||||
|
if(CMAKE_SIZEOF_VOID_P AND (NOT "${PYTHON_SIZEOF_VOID_P}" STREQUAL "${CMAKE_SIZEOF_VOID_P}"))
|
||||||
|
if(PythonLibsNew_FIND_REQUIRED)
|
||||||
|
math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8")
|
||||||
|
math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Python config failure: Python is ${_PYTHON_BITS}-bit, "
|
||||||
|
"chosen compiler is ${_CMAKE_BITS}-bit")
|
||||||
|
endif()
|
||||||
|
set(PYTHONLIBS_FOUND FALSE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# The built-in FindPython didn't always give the version numbers
|
||||||
|
string(REGEX REPLACE "\\." ";" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST})
|
||||||
|
list(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR)
|
||||||
|
list(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR)
|
||||||
|
list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH)
|
||||||
|
|
||||||
|
# Make sure all directory separators are '/'
|
||||||
|
string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX})
|
||||||
|
string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR})
|
||||||
|
string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES ${PYTHON_SITE_PACKAGES})
|
||||||
|
|
||||||
|
# TODO: All the nuances of CPython debug builds have not been dealt with/tested.
|
||||||
|
if(PYTHON_IS_DEBUG)
|
||||||
|
set(PYTHON_MODULE_EXTENSION "_d${PYTHON_MODULE_EXTENSION}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_HOST_WIN32)
|
||||||
|
set(PYTHON_LIBRARY
|
||||||
|
"${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
|
||||||
|
elseif(APPLE)
|
||||||
|
set(PYTHON_LIBRARY
|
||||||
|
"${PYTHON_PREFIX}/lib/libpython${PYTHON_LIBRARY_SUFFIX}.dylib")
|
||||||
|
else()
|
||||||
|
if(${PYTHON_SIZEOF_VOID_P} MATCHES 8)
|
||||||
|
set(_PYTHON_LIBS_SEARCH "${PYTHON_PREFIX}/lib64" "${PYTHON_PREFIX}/lib")
|
||||||
|
else()
|
||||||
|
set(_PYTHON_LIBS_SEARCH "${PYTHON_PREFIX}/lib")
|
||||||
|
endif()
|
||||||
|
#message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}")
|
||||||
|
# Probably this needs to be more involved. It would be nice if the config
|
||||||
|
# information the python interpreter itself gave us were more complete.
|
||||||
|
find_library(PYTHON_LIBRARY
|
||||||
|
NAMES "python${PYTHON_LIBRARY_SUFFIX}"
|
||||||
|
PATHS ${_PYTHON_LIBS_SEARCH}
|
||||||
|
NO_DEFAULT_PATH)
|
||||||
|
|
||||||
|
# If all else fails, just set the name/version and let the linker figure out the path.
|
||||||
|
if(NOT PYTHON_LIBRARY)
|
||||||
|
set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# For backward compatibility, set PYTHON_INCLUDE_PATH, but make it internal.
|
||||||
|
SET(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}" CACHE INTERNAL
|
||||||
|
"Path to where Python.h is found (deprecated)")
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
PYTHON_LIBRARY
|
||||||
|
PYTHON_INCLUDE_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the
|
||||||
|
# cache entries because they are meant to specify the location of a single
|
||||||
|
# library. We now set the variables listed by the documentation for this
|
||||||
|
# module.
|
||||||
|
SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
|
||||||
|
SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
|
||||||
|
SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")
|
||||||
|
|
||||||
|
find_package_message(PYTHON
|
||||||
|
"Found PythonLibs: ${PYTHON_LIBRARY}"
|
||||||
|
"${PYTHON_EXECUTABLE}${PYTHON_VERSION}")
|
Loading…
Reference in New Issue
Block a user