blob: 8fb13a9fbd47a2edf2c6d9557990a01e54f7544e [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
Dean Moldovan4563e9a2016-05-22 22:23:18 +02008cmake_minimum_required(VERSION 2.8.12)
Wenzel Jakob38bd7112015-07-05 20:05:44 +02009
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
Dean Moldovan928fff62016-05-22 19:48:47 +020028list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools")
Wenzel Jakobcaa9d442016-01-17 22:36:34 +010029set(Python_ADDITIONAL_VERSIONS 3.4 3.5 3.6 3.7)
Dean Moldovan928fff62016-05-22 19:48:47 +020030find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
Wenzel Jakobfaaee1c2015-11-30 10:17:01 +010031
Ben Pritchard70ee47d2016-02-18 13:06:43 -050032if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
Wenzel Jakobbcd31822015-10-12 23:57:20 +020033 # Enable link time optimization and set the default symbol
34 # visibility to hidden (very important to obtain small binaries)
Wenzel Jakob38bd7112015-07-05 20:05:44 +020035 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Wenzel Jakobfaaee1c2015-11-30 10:17:01 +010036 # Check for Link Time Optimization support
Ben Pritchard70ee47d2016-02-18 13:06:43 -050037 # (GCC/Clang)
Wenzel Jakobfaaee1c2015-11-30 10:17:01 +010038 CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
39 if (HAS_LTO_FLAG)
40 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
41 endif()
Ben Pritchard70ee47d2016-02-18 13:06:43 -050042
43 # Intel equivalent to LTO is called IPO
Wenzel Jakobe2bb4eb2016-02-19 13:27:20 +010044 if (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
45 CHECK_CXX_COMPILER_FLAG("-ipo" HAS_IPO_FLAG)
46 if (HAS_IPO_FLAG)
47 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ipo")
48 endif()
Ben Pritchard70ee47d2016-02-18 13:06:43 -050049 endif()
Wenzel Jakob38bd7112015-07-05 20:05:44 +020050 endif()
51endif()
52
53# Compile with compiler warnings turned on
54if(MSVC)
55 if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
56 string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
57 else()
58 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
59 endif()
Wenzel Jakobf2331662015-11-28 14:24:44 +010060elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
Wenzel Jakob38bd7112015-07-05 20:05:44 +020061 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
62endif()
63
Dean Moldovan4563e9a2016-05-22 22:23:18 +020064# Cache variables so pybind11_add_module can be used in parent projects
65set(PYBIND11_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include" CACHE INTERNAL "")
66set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS} CACHE INTERNAL "")
67set(PYTHON_MODULE_PREFIX ${PYTHON_MODULE_PREFIX} CACHE INTERNAL "")
68set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} CACHE INTERNAL "")
Wenzel Jakob9e0a0562016-05-05 20:33:54 +020069
Dean Moldovan4563e9a2016-05-22 22:23:18 +020070# Build a Python extension module:
71# pybind11_add_module(<name> source1 [source2 ...])
72#
73function(pybind11_add_module target_name)
74 add_library(${target_name} MODULE ${ARGN})
75 target_include_directories(${target_name} PUBLIC ${PYBIND11_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS})
Wenzel Jakob9e0a0562016-05-05 20:33:54 +020076
Dean Moldovan4563e9a2016-05-22 22:23:18 +020077 # The prefix and extension are provided by FindPythonLibsNew.cmake
78 set_target_properties(${target_name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
79 set_target_properties(${target_name} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
Wenzel Jakobbcd31822015-10-12 23:57:20 +020080
Dean Moldovan4563e9a2016-05-22 22:23:18 +020081 # It's quite common to have multiple copies of the same Python version
82 # installed on one's system. E.g.: one copy from the OS and another copy
83 # that's statically linked into an application like Blender or Maya.
84 # If we link our plugin library against the OS Python here and import it
85 # into Blender or Maya later on, this will cause segfaults when multiple
86 # conflicting Python instances are active at the same time (even when they
87 # are of the same version).
88
89 # Windows is not affected by this issue since it handles DLL imports
90 # differently. The solution for Linux and Mac OS is simple: we just don't
91 # link against the Python library. The resulting shared library will have
92 # missing symbols, but that's perfectly fine -- they will be resolved at
93 # import time.
94 if(MSVC)
95 target_link_libraries(${target_name} ${PYTHON_LIBRARIES})
96 elseif(APPLE)
97 # Make sure OS X does not have any issues with missing symbols
98 set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ".")
99 target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup")
100 endif()
101
102 # Make sure C++11/14 are enabled
103 if(NOT MSVC)
104 check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
105 check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
106
107 if (HAS_CPP14_FLAG)
108 target_compile_options(${target_name} PUBLIC "-std=c++14")
109 elseif (HAS_CPP11_FLAG)
110 target_compile_options(${target_name} PUBLIC "-std=c++11")
111 else()
112 message(FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!")
113 endif()
114
115 string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
116 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
117 # Default symbol visibility
118 target_compile_options(${target_name} PRIVATE "-fvisibility=hidden")
119 endif()
120 endif()
121endfunction()
Wenzel Jakobe44e56f2016-04-30 22:59:58 +0200122
Luka Čehovin19af3572015-11-24 21:20:56 +0100123set(PYBIND11_HEADERS
Wenzel Jakob48548ea2016-01-17 22:36:44 +0100124 include/pybind11/attr.h
Wenzel Jakob8f4eb002015-10-15 18:13:33 +0200125 include/pybind11/cast.h
126 include/pybind11/common.h
Wenzel Jakob66c9a402016-01-17 22:36:36 +0100127 include/pybind11/complex.h
128 include/pybind11/descr.h
Wenzel Jakob9e0a0562016-05-05 20:33:54 +0200129 include/pybind11/eigen.h
Wenzel Jakob66c9a402016-01-17 22:36:36 +0100130 include/pybind11/functional.h
131 include/pybind11/numpy.h
Wenzel Jakob8f4eb002015-10-15 18:13:33 +0200132 include/pybind11/operators.h
133 include/pybind11/pybind11.h
134 include/pybind11/pytypes.h
Wenzel Jakobe52cf8a2015-12-15 11:32:29 +0100135 include/pybind11/stl.h
Wenzel Jakob25c03ce2016-05-15 20:50:38 +0200136 include/pybind11/stl_bind.h
Wenzel Jakob66c9a402016-01-17 22:36:36 +0100137 include/pybind11/typeid.h
Luka Čehovin19af3572015-11-24 21:20:56 +0100138)
139
Axel Huebl6c37f212016-01-20 09:24:25 +0100140set(PYBIND11_EXAMPLES
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200141 example/example1.cpp
142 example/example2.cpp
143 example/example3.cpp
144 example/example4.cpp
145 example/example5.cpp
146 example/example6.cpp
147 example/example7.cpp
148 example/example8.cpp
149 example/example9.cpp
Wenzel Jakobd4258ba2015-07-26 16:33:49 +0200150 example/example10.cpp
Wenzel Jakoba576e6a2015-07-29 17:51:54 +0200151 example/example11.cpp
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +0200152 example/example12.cpp
Wenzel Jakob5f218b32016-01-17 22:36:39 +0100153 example/example13.cpp
Wenzel Jakobeda978e2016-03-15 15:05:40 +0100154 example/example14.cpp
Wenzel Jakob1c329aa2016-04-13 02:37:36 +0200155 example/example15.cpp
Wenzel Jakobd7efa4f2016-04-13 13:45:09 +0200156 example/example16.cpp
Sergey Lyskoveae77442016-05-07 00:26:19 -0400157 example/example17.cpp
Wenzel Jakob17cdb062016-03-10 13:24:10 +0100158 example/issues.cpp
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200159)
Axel Huebl6c37f212016-01-20 09:24:25 +0100160
Dean Moldovan4563e9a2016-05-22 22:23:18 +0200161# Check if Eigen is available
162find_package(Eigen3 QUIET)
163
Wenzel Jakob9e0a0562016-05-05 20:33:54 +0200164if (EIGEN3_FOUND)
Wenzel Jakob9e0a0562016-05-05 20:33:54 +0200165 list(APPEND PYBIND11_EXAMPLES example/eigen.cpp)
Wenzel Jakob9e0a0562016-05-05 20:33:54 +0200166 message(STATUS "Building Eigen testcase")
167else()
168 message(STATUS "NOT Building Eigen testcase")
169endif()
170
Axel Huebl6c37f212016-01-20 09:24:25 +0100171# Create the binding library
Dean Moldovan4563e9a2016-05-22 22:23:18 +0200172pybind11_add_module(example example/example.cpp ${PYBIND11_EXAMPLES})
173if (EIGEN3_FOUND)
174 target_include_directories(example PRIVATE ${EIGEN3_INCLUDE_DIR})
175 target_compile_definitions(example PRIVATE -DPYBIND11_TEST_EIGEN)
176endif()
Wenzel Jakobbcd31822015-10-12 23:57:20 +0200177
Wenzel Jakob607654f2015-10-13 23:58:10 +0200178# Always write the output file directly into the 'example' directory (even on MSVC)
179set(CompilerFlags
180 LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_RELEASE LIBRARY_OUTPUT_DIRECTORY_DEBUG
181 LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO
182 RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_RELEASE RUNTIME_OUTPUT_DIRECTORY_DEBUG
183 RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO)
184
185foreach(CompilerFlag ${CompilerFlags})
186 set_target_properties(example PROPERTIES ${CompilerFlag} ${PROJECT_SOURCE_DIR}/example)
187endforeach()
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200188
189if (WIN32)
190 if (MSVC)
Wenzel Jakobbdd11032016-05-01 12:56:09 +0200191 # /MP enables multithreaded builds (relevant when there are many files), /bigobj is
192 # needed for bigger binding projects due to the limit to 64k addressable sections
193 set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS /MP /bigobj)
194 # Enforce size-based optimization and link time code generation on MSVC
195 # (~30% smaller binaries in experiments); do nothing in debug mode.
196 set_property(TARGET example APPEND PROPERTY COMPILE_OPTIONS
197 "$<$<CONFIG:Release>:/Os>" "$<$<CONFIG:Release>:/GL>"
198 "$<$<CONFIG:MinSizeRel>:/Os>" "$<$<CONFIG:MinSizeRel>:/GL>"
199 "$<$<CONFIG:RelWithDebInfo>:/Os>" "$<$<CONFIG:RelWithDebInfo>:/GL>"
200 )
201 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELEASE "/LTCG ")
202 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL "/LTCG ")
203 set_property(TARGET example APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO "/LTCG ")
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200204 endif()
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200205elseif (UNIX)
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)
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200213 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Dean Moldovan4563e9a2016-05-22 22:23:18 +0200214 add_custom_command(TARGET example POST_BUILD COMMAND strip -u -r $<TARGET_FILE:example>)
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200215 endif()
216 else()
217 if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
Dean Moldovan4563e9a2016-05-22 22:23:18 +0200218 add_custom_command(TARGET example POST_BUILD COMMAND strip $<TARGET_FILE:example>)
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200219 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()