blob: 7236ea8b8dcba34b99b99795bac536176086c667 [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 Jakob28f98aa2015-10-13 02:57:16 +020014.. _cmake:
15
16Building with CMake
17===================
18
Wenzel Jakob4a48afb2016-03-09 21:31:21 +010019For C++ codebases that already have an existing CMake-based build system, the
20following snippet should be a good starting point to create bindings across
21platforms. It assumes that the code is located in a file named
22:file:`example.cpp`, and that the pybind11 repository is located in a
23subdirectory named :file:`pybind11`.
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020024
25.. code-block:: cmake
26
27 cmake_minimum_required(VERSION 2.8)
28
29 project(example)
30
31 # Add a CMake parameter for choosing a desired Python version
Wenzel Jakobf64feaf2016-04-28 14:33:45 +020032 set(EXAMPLE_PYTHON_VERSION "" CACHE STRING
33 "Python version to use for compiling the example library")
34
Ivan Smirnov4f88edd2016-01-17 16:42:11 +000035 include(CheckCXXCompilerFlag)
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020036
Wenzel Jakobf64feaf2016-04-28 14:33:45 +020037 # Set a default build configuration if none is specified.
38 # 'MinSizeRel' produces the smallest binaries
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020039 if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
40 message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
41 set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
42 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
43 "MinSizeRel" "RelWithDebInfo")
44 endif()
45 string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
46
47 # Try to autodetect Python (can be overridden manually if needed)
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010048 set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
Wenzel Jakobd4db8bc2016-01-20 01:26:44 +010049 if (NOT ${EXAMPLE_PYTHON_VERSION} STREQUAL "")
50 find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} EXACT)
Wenzel Jakob48548ea2016-01-17 22:36:44 +010051 if (NOT PythonLibs_FOUND)
Wenzel Jakobd4db8bc2016-01-20 01:26:44 +010052 find_package(PythonLibs ${EXAMPLE_PYTHON_VERSION} REQUIRED)
Wenzel Jakob48548ea2016-01-17 22:36:44 +010053 endif()
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010054 else()
55 find_package(PythonLibs REQUIRED)
56 endif()
57
Wenzel Jakobf64feaf2016-04-28 14:33:45 +020058 # The above sometimes returns version numbers like "3.4.3+";
59 # the "+" must be removed for the next lines to work
Wenzel Jakobc91551b2016-02-07 15:45:56 +010060 string(REPLACE "+" "" PYTHONLIBS_VERSION_STRING "+${PYTHONLIBS_VERSION_STRING}")
61
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010062 # Uncomment the following line if you will also require a matching Python interpreter
63 # find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED)
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020064
Wenzel Jakobf1532bd2015-12-07 18:24:43 +010065 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
Wenzel Jakob66c9a402016-01-17 22:36:36 +010066 CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
67 CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG)
68
69 if (HAS_CPP14_FLAG)
70 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
71 elseif (HAS_CPP11_FLAG)
72 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
73 else()
74 message(FATAL_ERROR "Unsupported compiler -- at least C++11 support is needed!")
75 endif()
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020076
77 # Enable link time optimization and set the default symbol
78 # visibility to hidden (very important to obtain small binaries)
79 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Wenzel Jakobf1532bd2015-12-07 18:24:43 +010080 # Default symbol visibility
81 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
82
83 # Check for Link Time Optimization support
84 CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
85 if (HAS_LTO_FLAG)
86 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
87 endif()
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020088 endif()
89 endif()
90
91 # Include path for Python header files
92 include_directories(${PYTHON_INCLUDE_DIR})
93
Wenzel Jakobf64feaf2016-04-28 14:33:45 +020094 # Include path for pybind11 header files -- this may need to be
95 # changed depending on your setup
Wenzel Jakob28f98aa2015-10-13 02:57:16 +020096 include_directories(${PROJECT_SOURCE_DIR}/pybind11/include)
97
98 # Create the binding library
99 add_library(example SHARED
100 example.cpp
101 # ... extra files go here ...
102 )
103
104 # Don't add a 'lib' prefix to the shared library
105 set_target_properties(example PROPERTIES PREFIX "")
106
107 if (WIN32)
108 if (MSVC)
Wenzel Jakob518cf722016-01-21 19:17:58 +0100109 # /bigobj is needed for bigger binding projects due to the limit to 64k
110 # addressable sections. /MP enables multithreaded builds (relevant when
111 # there are many files).
112 set_target_properties(example PROPERTIES COMPILE_FLAGS "/MP /bigobj ")
113
114 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
115 # Enforce size-based optimization and link time code generation on MSVC
116 # (~30% smaller binaries in experiments).
117 set_target_properties(example APPEND_STRING PROPERTY COMPILE_FLAGS "/Os /GL ")
118 set_target_properties(example APPEND_STRING PROPERTY LINK_FLAGS "/LTCG ")
119 endif()
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200120 endif()
121
122 # .PYD file extension on Windows
123 set_target_properties(example PROPERTIES SUFFIX ".pyd")
124
125 # Link against the Python shared library
126 target_link_libraries(example ${PYTHON_LIBRARY})
127 elseif (UNIX)
128 # It's quite common to have multiple copies of the same Python version
129 # installed on one's system. E.g.: one copy from the OS and another copy
130 # that's statically linked into an application like Blender or Maya.
131 # If we link our plugin library against the OS Python here and import it
132 # into Blender or Maya later on, this will cause segfaults when multiple
Wenzel Jakob6eb11da2016-01-17 22:36:36 +0100133 # conflicting Python instances are active at the same time (even when they
134 # are of the same version).
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200135
Wenzel Jakob93296692015-10-13 23:21:54 +0200136 # Windows is not affected by this issue since it handles DLL imports
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200137 # differently. The solution for Linux and Mac OS is simple: we just don't
138 # link against the Python library. The resulting shared library will have
139 # missing symbols, but that's perfectly fine -- they will be resolved at
140 # import time.
141
142 # .SO file extension on Linux/Mac OS
143 set_target_properties(example PROPERTIES SUFFIX ".so")
144
145 # Strip unnecessary sections of the binary on Linux/Mac OS
146 if(APPLE)
147 set_target_properties(example PROPERTIES MACOSX_RPATH ".")
Wenzel Jakob48548ea2016-01-17 22:36:44 +0100148 set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200149 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Wenzel Jakobf64feaf2016-04-28 14:33:45 +0200150 add_custom_command(TARGET example POST_BUILD
151 COMMAND strip -u -r ${PROJECT_BINARY_DIR}/example.so)
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200152 endif()
153 else()
154 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Wenzel Jakobf64feaf2016-04-28 14:33:45 +0200155 add_custom_command(TARGET example POST_BUILD
156 COMMAND strip ${PROJECT_BINARY_DIR}/example.so)
Wenzel Jakob28f98aa2015-10-13 02:57:16 +0200157 endif()
158 endif()
159 endif()