blob: 38297dbbb263c2a45705a19609c38c419cf58bc3 [file] [log] [blame]
Wenzel Jakob38bd7112015-07-05 20:05:44 +02001# CMakeLists.txt -- Build system for the pybind11 examples
2#
3# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
4#
5# All rights reserved. Use of this source code is governed by a
6# BSD-style license that can be found in the LICENSE file.
7
8cmake_minimum_required(VERSION 2.8)
9
Wenzel Jakob8f4eb002015-10-15 18:13:33 +020010project(pybind11)
Wenzel Jakob38bd7112015-07-05 20:05:44 +020011
Wenzel Jakob3350b5e2015-11-24 21:33:18 +010012option(PYBIND11_INSTALL "Install pybind11 header files?" ON)
13
Wenzel Jakobbcd31822015-10-12 23:57:20 +020014# Add a CMake parameter for choosing a desired Python version
Wenzel Jakobb1b71402015-10-18 16:48:30 +020015set(PYBIND11_PYTHON_VERSION "" CACHE STRING "Python version to use for compiling the example application")
Wenzel Jakobbcd31822015-10-12 23:57:20 +020016
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010017include(CheckCXXCompilerFlag)
18
Wenzel Jakobbcd31822015-10-12 23:57:20 +020019# Set a default build configuration if none is specified. 'MinSizeRel' produces the smallest binaries
Wenzel Jakob38bd7112015-07-05 20:05:44 +020020if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
21 message(STATUS "Setting build type to 'MinSizeRel' as none was specified.")
22 set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE)
23 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
24 "MinSizeRel" "RelWithDebInfo")
25endif()
Wenzel Jakobbcd31822015-10-12 23:57:20 +020026string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
Wenzel Jakob3b806d42015-10-11 16:29:35 +020027
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010028set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
29if (NOT ${PYBIND11_PYTHON_VERSION} STREQUAL "")
30 find_package(PythonLibs ${PYBIND11_PYTHON_VERSION} EXACT)
Wenzel Jakob9ac5bc52016-05-05 16:27:06 +020031 if (NOT PYTHONLIBS_FOUND)
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010032 find_package(PythonLibs ${PYBIND11_PYTHON_VERSION} REQUIRED)
33 endif()
34else()
35 find_package(PythonLibs REQUIRED)
36endif()
Wenzel Jakobc91551b2016-02-07 15:45:56 +010037# The above sometimes returns version numbers like "3.4.3+"; the "+" must be removed for the next line to work
38string(REPLACE "+" "" PYTHONLIBS_VERSION_STRING "+${PYTHONLIBS_VERSION_STRING}")
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010039find_package(PythonInterp ${PYTHONLIBS_VERSION_STRING} EXACT REQUIRED)
Wenzel Jakobfaaee1c2015-11-30 10:17:01 +010040
Ben Pritchard70ee47d2016-02-18 13:06:43 -050041if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
Wenzel Jakob66c9a402016-01-17 22:36:36 +010042 CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
43 CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CPP11_FLAG)
44
45 if (HAS_CPP14_FLAG)
46 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
47 elseif (HAS_CPP11_FLAG)
48 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
49 else()
50 message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
51 endif()
Wenzel Jakobbcd31822015-10-12 23:57:20 +020052
53 # Enable link time optimization and set the default symbol
54 # visibility to hidden (very important to obtain small binaries)
Wenzel Jakob38bd7112015-07-05 20:05:44 +020055 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Wenzel Jakobfaaee1c2015-11-30 10:17:01 +010056 # Default symbol visibility
57 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
58
59 # Check for Link Time Optimization support
Ben Pritchard70ee47d2016-02-18 13:06:43 -050060 # (GCC/Clang)
Wenzel Jakobfaaee1c2015-11-30 10:17:01 +010061 CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
62 if (HAS_LTO_FLAG)
63 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
64 endif()
Ben Pritchard70ee47d2016-02-18 13:06:43 -050065
66 # Intel equivalent to LTO is called IPO
Wenzel Jakobe2bb4eb2016-02-19 13:27:20 +010067 if (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
68 CHECK_CXX_COMPILER_FLAG("-ipo" HAS_IPO_FLAG)
69 if (HAS_IPO_FLAG)
70 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ipo")
71 endif()
Ben Pritchard70ee47d2016-02-18 13:06:43 -050072 endif()
Wenzel Jakob38bd7112015-07-05 20:05:44 +020073 endif()
74endif()
75
76# Compile with compiler warnings turned on
77if(MSVC)
78 if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
79 string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
80 else()
81 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
82 endif()
Wenzel Jakobf2331662015-11-28 14:24:44 +010083elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
Wenzel Jakob38bd7112015-07-05 20:05:44 +020084 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
85endif()
86
Wenzel Jakob9e0a0562016-05-05 20:33:54 +020087
88# Check if Eigen is available
89set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools")
90find_package(Eigen3 QUIET)
91
Wenzel Jakobbcd31822015-10-12 23:57:20 +020092# Include path for pybind11 header files
93include_directories(include)
94
Wenzel Jakobe44e56f2016-04-30 22:59:58 +020095# Include path for Python header files
96include_directories(${PYTHON_INCLUDE_DIR})
97
Luka Čehovin19af3572015-11-24 21:20:56 +010098set(PYBIND11_HEADERS
Wenzel Jakob48548ea2016-01-17 22:36:44 +010099 include/pybind11/attr.h
Wenzel Jakob8f4eb002015-10-15 18:13:33 +0200100 include/pybind11/cast.h
101 include/pybind11/common.h
Wenzel Jakob66c9a402016-01-17 22:36:36 +0100102 include/pybind11/complex.h
103 include/pybind11/descr.h
Wenzel Jakob9e0a0562016-05-05 20:33:54 +0200104 include/pybind11/eigen.h
Wenzel Jakob66c9a402016-01-17 22:36:36 +0100105 include/pybind11/functional.h
106 include/pybind11/numpy.h
Wenzel Jakob8f4eb002015-10-15 18:13:33 +0200107 include/pybind11/operators.h
108 include/pybind11/pybind11.h
109 include/pybind11/pytypes.h
Wenzel Jakobe52cf8a2015-12-15 11:32:29 +0100110 include/pybind11/stl.h
Wenzel Jakob66c9a402016-01-17 22:36:36 +0100111 include/pybind11/typeid.h
Luka Čehovin19af3572015-11-24 21:20:56 +0100112)
113
Axel Huebl6c37f212016-01-20 09:24:25 +0100114set(PYBIND11_EXAMPLES
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200115 example/example1.cpp
116 example/example2.cpp
117 example/example3.cpp
118 example/example4.cpp
119 example/example5.cpp
120 example/example6.cpp
121 example/example7.cpp
122 example/example8.cpp
123 example/example9.cpp
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200124 example/example10.cpp
Wenzel Jakoba576e6a2015-07-29 17:51:54 +0200125 example/example11.cpp
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +0200126 example/example12.cpp
Wenzel Jakob5f218b32016-01-17 22:36:39 +0100127 example/example13.cpp
Wenzel Jakobeda978e2016-03-15 15:05:40 +0100128 example/example14.cpp
Wenzel Jakob1c329aa2016-04-13 02:37:36 +0200129 example/example15.cpp
Wenzel Jakobd7efa4f2016-04-13 13:45:09 +0200130 example/example16.cpp
Wenzel Jakob17cdb062016-03-10 13:24:10 +0100131 example/issues.cpp
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200132)
Axel Huebl6c37f212016-01-20 09:24:25 +0100133
Wenzel Jakob9e0a0562016-05-05 20:33:54 +0200134if (EIGEN3_FOUND)
135 include_directories(${EIGEN3_INCLUDE_DIR})
136 list(APPEND PYBIND11_EXAMPLES example/eigen.cpp)
137 add_definitions(-DPYBIND11_TEST_EIGEN)
138 message(STATUS "Building Eigen testcase")
139else()
140 message(STATUS "NOT Building Eigen testcase")
141endif()
142
Axel Huebl6c37f212016-01-20 09:24:25 +0100143# Create the binding library
144add_library(example SHARED
145 ${PYBIND11_HEADERS}
146 example/example.cpp
147 ${PYBIND11_EXAMPLES}
148)
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200149
Wenzel Jakobbcd31822015-10-12 23:57:20 +0200150# Don't add a 'lib' prefix to the shared library
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200151set_target_properties(example PROPERTIES PREFIX "")
Wenzel Jakobbcd31822015-10-12 23:57:20 +0200152
Wenzel Jakob607654f2015-10-13 23:58:10 +0200153# Always write the output file directly into the 'example' directory (even on MSVC)
154set(CompilerFlags
155 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_RELEASE LIBRARY_OUTPUT_DIRECTORY_DEBUG
156 LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO
157 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_RELEASE RUNTIME_OUTPUT_DIRECTORY_DEBUG
158 RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO)
159
160foreach(CompilerFlag ${CompilerFlags})
161 set_target_properties(example PROPERTIES ${CompilerFlag} ${PROJECT_SOURCE_DIR}/example)
162endforeach()
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200163
164if (WIN32)
165 if (MSVC)
Wenzel Jakobbdd11032016-05-01 12:56:09 +0200166 # /MP enables multithreaded builds (relevant when there are many files), /bigobj is
167 # needed for bigger binding projects due to the limit to 64k addressable sections
168 set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS /MP /bigobj)
169 # Enforce size-based optimization and link time code generation on MSVC
170 # (~30% smaller binaries in experiments); do nothing in debug mode.
171 set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS
172 "$<$<CONFIG:Release>:/Os>" "$<$<CONFIG:Release>:/GL>"
173 "$<$<CONFIG:MinSizeRel>:/Os>" "$<$<CONFIG:MinSizeRel>:/GL>"
174 "$<$<CONFIG:RelWithDebInfo>:/Os>" "$<$<CONFIG:RelWithDebInfo>:/GL>"
175 )
176 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELEASE "/LTCG ")
177 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL "/LTCG ")
178 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO "/LTCG ")
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200179 endif()
180
181 # .PYD file extension on Windows
182 set_target_properties(example PROPERTIES SUFFIX ".pyd")
183
184 # Link against the Python shared library
185 target_link_libraries(example ${PYTHON_LIBRARY})
186elseif (UNIX)
187 # It's quite common to have multiple copies of the same Python version
188 # installed on one's system. E.g.: one copy from the OS and another copy
189 # that's statically linked into an application like Blender or Maya.
190 # If we link our plugin library against the OS Python here and import it
191 # into Blender or Maya later on, this will cause segfaults when multiple
Wenzel Jakob6eb11da2016-01-17 22:36:36 +0100192 # conflicting Python instances are active at the same time (even when they
193 # are of the same version).
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200194
Wenzel Jakob518cf722016-01-21 19:17:58 +0100195 # Windows is not affected by this issue since it handles DLL imports
Wenzel Jakobbcd31822015-10-12 23:57:20 +0200196 # differently. The solution for Linux and Mac OS is simple: we just don't
197 # link against the Python library. The resulting shared library will have
198 # missing symbols, but that's perfectly fine -- they will be resolved at
199 # import time.
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200200
201 # .SO file extension on Linux/Mac OS
202 set_target_properties(example PROPERTIES SUFFIX ".so")
203
Wenzel Jakob867ae372015-10-15 22:41:25 +0200204 # Optimize for a small binary size
205 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
206 set_target_properties(example PROPERTIES COMPILE_FLAGS "-Os")
207 endif()
208
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200209 # Strip unnecessary sections of the binary on Linux/Mac OS
210 if(APPLE)
211 set_target_properties(example PROPERTIES MACOSX_RPATH ".")
Wenzel Jakob48548ea2016-01-17 22:36:44 +0100212 set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200213 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
214 add_custom_command(TARGET example POST_BUILD COMMAND strip -u -r ${PROJECT_SOURCE_DIR}/example/example.so)
215 endif()
216 else()
217 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
218 add_custom_command(TARGET example POST_BUILD COMMAND strip ${PROJECT_SOURCE_DIR}/example/example.so)
219 endif()
220 endif()
221endif()
222
223enable_testing()
Wenzel Jakob80c24512016-02-20 20:53:10 +0100224
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200225set(RUN_TEST ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/run_test.py)
Wenzel Jakob80c24512016-02-20 20:53:10 +0100226if (MSVC OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
227 set(RUN_TEST ${RUN_TEST} --relaxed)
228endif()
229
Wenzel Jakob17cdb062016-03-10 13:24:10 +0100230foreach(VALUE ${PYBIND11_EXAMPLES})
231 string(REGEX REPLACE "^example/(.+).cpp$" "\\1" EXAMPLE_NAME "${VALUE}")
232 add_test(NAME ${EXAMPLE_NAME} COMMAND ${RUN_TEST} ${EXAMPLE_NAME})
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200233endforeach()
Luka Čehovin19af3572015-11-24 21:20:56 +0100234
Wenzel Jakob3350b5e2015-11-24 21:33:18 +0100235if (PYBIND11_INSTALL)
Luka Čehovin19af3572015-11-24 21:20:56 +0100236 install(FILES ${PYBIND11_HEADERS} DESTINATION include/pybind11)
237endif()