blob: 3f10bd3756165aee7f62cefea1a56a9d32f3f2fc [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 Jakob25c03ce2016-05-15 20:50:38 +0200111 include/pybind11/stl_bind.h
Wenzel Jakob66c9a402016-01-17 22:36:36 +0100112 include/pybind11/typeid.h
Luka Čehovin19af3572015-11-24 21:20:56 +0100113)
114
Axel Huebl6c37f212016-01-20 09:24:25 +0100115set(PYBIND11_EXAMPLES
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200116 example/example1.cpp
117 example/example2.cpp
118 example/example3.cpp
119 example/example4.cpp
120 example/example5.cpp
121 example/example6.cpp
122 example/example7.cpp
123 example/example8.cpp
124 example/example9.cpp
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200125 example/example10.cpp
Wenzel Jakoba576e6a2015-07-29 17:51:54 +0200126 example/example11.cpp
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +0200127 example/example12.cpp
Wenzel Jakob5f218b32016-01-17 22:36:39 +0100128 example/example13.cpp
Wenzel Jakobeda978e2016-03-15 15:05:40 +0100129 example/example14.cpp
Wenzel Jakob1c329aa2016-04-13 02:37:36 +0200130 example/example15.cpp
Wenzel Jakobd7efa4f2016-04-13 13:45:09 +0200131 example/example16.cpp
Sergey Lyskoveae77442016-05-07 00:26:19 -0400132 example/example17.cpp
Wenzel Jakob17cdb062016-03-10 13:24:10 +0100133 example/issues.cpp
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200134)
Axel Huebl6c37f212016-01-20 09:24:25 +0100135
Wenzel Jakob9e0a0562016-05-05 20:33:54 +0200136if (EIGEN3_FOUND)
137 include_directories(${EIGEN3_INCLUDE_DIR})
138 list(APPEND PYBIND11_EXAMPLES example/eigen.cpp)
139 add_definitions(-DPYBIND11_TEST_EIGEN)
140 message(STATUS "Building Eigen testcase")
141else()
142 message(STATUS "NOT Building Eigen testcase")
143endif()
144
Axel Huebl6c37f212016-01-20 09:24:25 +0100145# Create the binding library
146add_library(example SHARED
147 ${PYBIND11_HEADERS}
148 example/example.cpp
149 ${PYBIND11_EXAMPLES}
150)
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200151
Wenzel Jakobbcd31822015-10-12 23:57:20 +0200152# Don't add a 'lib' prefix to the shared library
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200153set_target_properties(example PROPERTIES PREFIX "")
Wenzel Jakobbcd31822015-10-12 23:57:20 +0200154
Wenzel Jakob607654f2015-10-13 23:58:10 +0200155# Always write the output file directly into the 'example' directory (even on MSVC)
156set(CompilerFlags
157 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_RELEASE LIBRARY_OUTPUT_DIRECTORY_DEBUG
158 LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO
159 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_RELEASE RUNTIME_OUTPUT_DIRECTORY_DEBUG
160 RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO)
161
162foreach(CompilerFlag ${CompilerFlags})
163 set_target_properties(example PROPERTIES ${CompilerFlag} ${PROJECT_SOURCE_DIR}/example)
164endforeach()
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200165
166if (WIN32)
167 if (MSVC)
Wenzel Jakobbdd11032016-05-01 12:56:09 +0200168 # /MP enables multithreaded builds (relevant when there are many files), /bigobj is
169 # needed for bigger binding projects due to the limit to 64k addressable sections
170 set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS /MP /bigobj)
171 # Enforce size-based optimization and link time code generation on MSVC
172 # (~30% smaller binaries in experiments); do nothing in debug mode.
173 set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS
174 "$<$<CONFIG:Release>:/Os>" "$<$<CONFIG:Release>:/GL>"
175 "$<$<CONFIG:MinSizeRel>:/Os>" "$<$<CONFIG:MinSizeRel>:/GL>"
176 "$<$<CONFIG:RelWithDebInfo>:/Os>" "$<$<CONFIG:RelWithDebInfo>:/GL>"
177 )
178 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELEASE "/LTCG ")
179 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL "/LTCG ")
180 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO "/LTCG ")
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200181 endif()
182
183 # .PYD file extension on Windows
184 set_target_properties(example PROPERTIES SUFFIX ".pyd")
185
186 # Link against the Python shared library
187 target_link_libraries(example ${PYTHON_LIBRARY})
188elseif (UNIX)
189 # It's quite common to have multiple copies of the same Python version
190 # installed on one's system. E.g.: one copy from the OS and another copy
191 # that's statically linked into an application like Blender or Maya.
192 # If we link our plugin library against the OS Python here and import it
193 # into Blender or Maya later on, this will cause segfaults when multiple
Wenzel Jakob6eb11da2016-01-17 22:36:36 +0100194 # conflicting Python instances are active at the same time (even when they
195 # are of the same version).
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200196
Wenzel Jakob518cf722016-01-21 19:17:58 +0100197 # Windows is not affected by this issue since it handles DLL imports
Wenzel Jakobbcd31822015-10-12 23:57:20 +0200198 # differently. The solution for Linux and Mac OS is simple: we just don't
199 # link against the Python library. The resulting shared library will have
200 # missing symbols, but that's perfectly fine -- they will be resolved at
201 # import time.
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200202
203 # .SO file extension on Linux/Mac OS
204 set_target_properties(example PROPERTIES SUFFIX ".so")
205
Wenzel Jakob867ae372015-10-15 22:41:25 +0200206 # Optimize for a small binary size
207 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
208 set_target_properties(example PROPERTIES COMPILE_FLAGS "-Os")
209 endif()
210
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200211 # Strip unnecessary sections of the binary on Linux/Mac OS
212 if(APPLE)
213 set_target_properties(example PROPERTIES MACOSX_RPATH ".")
Wenzel Jakob48548ea2016-01-17 22:36:44 +0100214 set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200215 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
216 add_custom_command(TARGET example POST_BUILD COMMAND strip -u -r ${PROJECT_SOURCE_DIR}/example/example.so)
217 endif()
218 else()
219 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
220 add_custom_command(TARGET example POST_BUILD COMMAND strip ${PROJECT_SOURCE_DIR}/example/example.so)
221 endif()
222 endif()
223endif()
224
225enable_testing()
Wenzel Jakob80c24512016-02-20 20:53:10 +0100226
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200227set(RUN_TEST ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example/run_test.py)
Wenzel Jakob80c24512016-02-20 20:53:10 +0100228if (MSVC OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
229 set(RUN_TEST ${RUN_TEST} --relaxed)
230endif()
231
Wenzel Jakob17cdb062016-03-10 13:24:10 +0100232foreach(VALUE ${PYBIND11_EXAMPLES})
233 string(REGEX REPLACE "^example/(.+).cpp$" "\\1" EXAMPLE_NAME "${VALUE}")
234 add_test(NAME ${EXAMPLE_NAME} COMMAND ${RUN_TEST} ${EXAMPLE_NAME})
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200235endforeach()
Luka Čehovin19af3572015-11-24 21:20:56 +0100236
Wenzel Jakob3350b5e2015-11-24 21:33:18 +0100237if (PYBIND11_INSTALL)
Luka Čehovin19af3572015-11-24 21:20:56 +0100238 install(FILES ${PYBIND11_HEADERS} DESTINATION include/pybind11)
239endif()