You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
6.2 KiB

  1. Build systems
  2. #############
  3. Building with setuptools
  4. ========================
  5. For projects on PyPI, building with setuptools is the way to go. Sylvain Corlay
  6. has kindly provided an example project which shows how to set up everything,
  7. including automatic generation of documentation using Sphinx. Please refer to
  8. the [pbtest]_ repository.
  9. .. [pbtest] https://github.com/pybind/pbtest
  10. .. _cmake:
  11. Building with CMake
  12. ===================
  13. For C++ codebases that already have an existing CMake-based build system, the
  14. following snippet should be a good starting point to create bindings across
  15. platforms. It assumes that the code is located in a file named
  16. :file:`example.cpp`, and that the pybind11 repository is located in a
  17. subdirectory named :file:`pybind11`.
  18. .. code-block:: cmake
  19. cmake_minimum_required(VERSION 2.8)
  20. project(example)
  21. # Add a CMake parameter for choosing a desired Python version
  22. set(EXAMPLE_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling the example library")
  23. include(CheckCXXCompilerFlag)
  24. # Set a default build configuration if none is specified. 'MinSizeRel' produces the smallest binaries
  25. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  26. message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
  27. set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
  28. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
  29. "MinSizeRel" "RelWithDebInfo")
  30. endif()
  31. string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
  32. # Try to autodetect Python (can be overridden manually if needed)
  33. set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
  34. if (NOT ${EXAMPLE_PYTHON_VERSION} STREQUAL "")
  35. find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} EXACT)
  36. if (NOT PythonLibs_FOUND)
  37. find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} REQUIRED)
  38. endif()
  39. else()
  40. find_package(PythonLibs REQUIRED)
  41. endif()
  42. # The above sometimes returns version numbers like "3.4.3+"; the "+" must be removed for the next lines to work
  43. string(REPLACE "+" "" PYTHONLIBS_VERSION_STRING "+${PYTHONLIBS_VERSION_STRING}")
  44. # Uncomment the following line if you will also require a matching Python interpreter
  45. # find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED)
  46. if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  47. CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
  48. CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG)
  49. if (HAS_CPP14_FLAG)
  50. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
  51. elseif (HAS_CPP11_FLAG)
  52. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
  53. else()
  54. message(FATAL_ERROR "Unsupported compiler -- at least C++11 support is needed!")
  55. endif()
  56. # Enable link time optimization and set the default symbol
  57. # visibility to hidden (very important to obtain small binaries)
  58. if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
  59. # Default symbol visibility
  60. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
  61. # Check for Link Time Optimization support
  62. CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
  63. if (HAS_LTO_FLAG)
  64. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
  65. endif()
  66. endif()
  67. endif()
  68. # Include path for Python header files
  69. include_directories(${PYTHON_INCLUDE_DIR})
  70. # Include path for pybind11 header files -- this may need to be changed depending on your setup
  71. include_directories(${PROJECT_SOURCE_DIR}/pybind11/include)
  72. # Create the binding library
  73. add_library(example SHARED
  74. example.cpp
  75. # ... extra files go here ...
  76. )
  77. # Don't add a 'lib' prefix to the shared library
  78. set_target_properties(example PROPERTIES PREFIX "")
  79. if (WIN32)
  80. if (MSVC)
  81. # /bigobj is needed for bigger binding projects due to the limit to 64k
  82. # addressable sections. /MP enables multithreaded builds (relevant when
  83. # there are many files).
  84. set_target_properties(example PROPERTIES COMPILE_FLAGS "/MP /bigobj ")
  85. if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
  86. # Enforce size-based optimization and link time code generation on MSVC
  87. # (~30% smaller binaries in experiments).
  88. set_target_properties(example APPEND_STRING PROPERTY COMPILE_FLAGS "/Os /GL ")
  89. set_target_properties(example APPEND_STRING PROPERTY LINK_FLAGS "/LTCG ")
  90. endif()
  91. endif()
  92. # .PYD file extension on Windows
  93. set_target_properties(example PROPERTIES SUFFIX ".pyd")
  94. # Link against the Python shared library
  95. target_link_libraries(example ${PYTHON_LIBRARY})
  96. elseif (UNIX)
  97. # It's quite common to have multiple copies of the same Python version
  98. # installed on one's system. E.g.: one copy from the OS and another copy
  99. # that's statically linked into an application like Blender or Maya.
  100. # If we link our plugin library against the OS Python here and import it
  101. # into Blender or Maya later on, this will cause segfaults when multiple
  102. # conflicting Python instances are active at the same time (even when they
  103. # are of the same version).
  104. # Windows is not affected by this issue since it handles DLL imports
  105. # differently. The solution for Linux and Mac OS is simple: we just don't
  106. # link against the Python library. The resulting shared library will have
  107. # missing symbols, but that's perfectly fine -- they will be resolved at
  108. # import time.
  109. # .SO file extension on Linux/Mac OS
  110. set_target_properties(example PROPERTIES SUFFIX ".so")
  111. # Strip unnecessary sections of the binary on Linux/Mac OS
  112. if(APPLE)
  113. set_target_properties(example PROPERTIES MACOSX_RPATH ".")
  114. set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
  115. if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
  116. add_custom_command(TARGET example POST_BUILD COMMAND strip -u -r ${PROJECT_BINARY_DIR}/example.so)
  117. endif()
  118. else()
  119. if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
  120. add_custom_command(TARGET example POST_BUILD COMMAND strip ${PROJECT_BINARY_DIR}/example.so)
  121. endif()
  122. endif()
  123. endif()