blob: 5f4d09836a92940bbc17c2e18d1aea5796dbb059 [file] [log] [blame]
Wenzel Jakob4a48afb2016-03-09 21:31:21 +01001Build systems
2#############
3
4Building with setuptools
5========================
6
7For projects on PyPI, building with setuptools is the way to go. Sylvain Corlay
8has kindly provided an example project which shows how to set up everything,
9including automatic generation of documentation using Sphinx. Please refer to
10the [pbtest]_ repository.
11
12.. [pbtest] https://github.com/pybind/pbtest
13
Wenzel Jakoba439cca2016-05-17 10:47:52 +020014Building with cppimport
15========================
16
17 cppimport is a small Python import hook that determines whether there is a C++
18 source file whose name matches the requested module. If there is, the file is
19 compiled as a Python extension using pybind11 and placed in the same folder as
20 the C++ source file. Python is then able to find the module and load it.
21
22.. [cppimport] https://github.com/tbenthompson/cppimport
23
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020024.. _cmake:
25
26Building with CMake
27===================
28
Wenzel Jakob4a48afb2016-03-09 21:31:21 +010029For C++ codebases that already have an existing CMake-based build system, the
30following snippet should be a good starting point to create bindings across
31platforms. It assumes that the code is located in a file named
32:file:`example.cpp`, and that the pybind11 repository is located in a
33subdirectory named :file:`pybind11`.
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020034
35.. code-block:: cmake
36
37 cmake_minimum_required(VERSION 2.8)
38
39 project(example)
40
41 # Add a CMake parameter for choosing a desired Python version
Wenzel Jakobf64feaf2016-04-28 14:33:45 +020042 set(EXAMPLE_PYTHON_VERSION "" CACHE STRING
43 "Python version to use for compiling the example library")
44
Ivan Smirnov4f88edd2016-01-17 16:42:11 +000045 include(CheckCXXCompilerFlag)
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020046
Wenzel Jakobf64feaf2016-04-28 14:33:45 +020047 # Set a default build configuration if none is specified.
48 # 'MinSizeRel' produces the smallest binaries
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020049 if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
50 message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
51 set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
52 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
53 "MinSizeRel" "RelWithDebInfo")
54 endif()
55 string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
56
57 # Try to autodetect Python (can be overridden manually if needed)
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010058 set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
Wenzel Jakobd4db8bc2016-01-20 01:26:44 +010059 if (NOT ${EXAMPLE_PYTHON_VERSION} STREQUAL "")
60 find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} EXACT)
Wenzel Jakob9ac5bc52016-05-05 16:27:06 +020061 if (NOT PYTHONLIBS_FOUND)
Wenzel Jakobd4db8bc2016-01-20 01:26:44 +010062 find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} REQUIRED)
Wenzel Jakob48548ea2016-01-17 22:36:44 +010063 endif()
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010064 else()
65 find_package(PythonLibs REQUIRED)
66 endif()
67
Wenzel Jakobf64feaf2016-04-28 14:33:45 +020068 # The above sometimes returns version numbers like "3.4.3+";
69 # the "+" must be removed for the next lines to work
Wenzel Jakobc91551b2016-02-07 15:45:56 +010070 string(REPLACE "+" "" PYTHONLIBS_VERSION_STRING "+${PYTHONLIBS_VERSION_STRING}")
71
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010072 # Uncomment the following line if you will also require a matching Python interpreter
73 # find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED)
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020074
Wenzel Jakobf1532bd2015-12-07 18:24:43 +010075 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
Wenzel Jakob66c9a402016-01-17 22:36:36 +010076 CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
77 CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG)
78
79 if (HAS_CPP14_FLAG)
80 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
81 elseif (HAS_CPP11_FLAG)
82 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
83 else()
84 message(FATAL_ERROR "Unsupported compiler -- at least C++11 support is needed!")
85 endif()
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020086
87 # Enable link time optimization and set the default symbol
88 # visibility to hidden (very important to obtain small binaries)
89 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Wenzel Jakobf1532bd2015-12-07 18:24:43 +010090 # Default symbol visibility
91 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
92
93 # Check for Link Time Optimization support
94 CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
95 if (HAS_LTO_FLAG)
96 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
97 endif()
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020098 endif()
99 endif()
100
101 # Include path for Python header files
102 include_directories(${PYTHON_INCLUDE_DIR})
103
Wenzel Jakobf64feaf2016-04-28 14:33:45 +0200104 # Include path for pybind11 header files -- this may need to be
105 # changed depending on your setup
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200106 include_directories(${PROJECT_SOURCE_DIR}/pybind11/include)
107
108 # Create the binding library
109 add_library(example SHARED
110 example.cpp
111 # ... extra files go here ...
112 )
113
114 # Don't add a 'lib' prefix to the shared library
115 set_target_properties(example PROPERTIES PREFIX "")
116
117 if (WIN32)
118 if (MSVC)
Wenzel Jakobbdd11032016-05-01 12:56:09 +0200119 # /MP enables multithreaded builds (relevant when there are many files), /bigobj is
120 # needed for bigger binding projects due to the limit to 64k addressable sections
121 set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS /MP /bigobj)
122 # Enforce size-based optimization and link time code generation on MSVC
123 # (~30% smaller binaries in experiments); do nothing in debug mode.
124 set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS
125 "$<$<CONFIG:Release>:/Os>" "$<$<CONFIG:Release>:/GL>"
126 "$<$<CONFIG:MinSizeRel>:/Os>" "$<$<CONFIG:MinSizeRel>:/GL>"
127 "$<$<CONFIG:RelWithDebInfo>:/Os>" "$<$<CONFIG:RelWithDebInfo>:/GL>"
128 )
129 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELEASE "/LTCG ")
130 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL "/LTCG ")
131 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO "/LTCG ")
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200132 endif()
133
134 # .PYD file extension on Windows
135 set_target_properties(example PROPERTIES SUFFIX ".pyd")
136
137 # Link against the Python shared library
138 target_link_libraries(example ${PYTHON_LIBRARY})
139 elseif (UNIX)
140 # It's quite common to have multiple copies of the same Python version
141 # installed on one's system. E.g.: one copy from the OS and another copy
142 # that's statically linked into an application like Blender or Maya.
143 # If we link our plugin library against the OS Python here and import it
144 # into Blender or Maya later on, this will cause segfaults when multiple
Wenzel Jakob6eb11da2016-01-17 22:36:36 +0100145 # conflicting Python instances are active at the same time (even when they
146 # are of the same version).
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200147
Wenzel Jakob93296692015-10-13 23:21:54 +0200148 # Windows is not affected by this issue since it handles DLL imports
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200149 # differently. The solution for Linux and Mac OS is simple: we just don't
150 # link against the Python library. The resulting shared library will have
151 # missing symbols, but that's perfectly fine -- they will be resolved at
152 # import time.
153
154 # .SO file extension on Linux/Mac OS
155 set_target_properties(example PROPERTIES SUFFIX ".so")
156
157 # Strip unnecessary sections of the binary on Linux/Mac OS
158 if(APPLE)
159 set_target_properties(example PROPERTIES MACOSX_RPATH ".")
Wenzel Jakob48548ea2016-01-17 22:36:44 +0100160 set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200161 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Wenzel Jakobf64feaf2016-04-28 14:33:45 +0200162 add_custom_command(TARGET example POST_BUILD
163 COMMAND strip -u -r ${PROJECT_BINARY_DIR}/example.so)
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200164 endif()
165 else()
166 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Wenzel Jakobf64feaf2016-04-28 14:33:45 +0200167 add_custom_command(TARGET example POST_BUILD
168 COMMAND strip ${PROJECT_BINARY_DIR}/example.so)
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200169 endif()
170 endif()
171 endif()