Jason Rhinelander | 60d0e0d | 2017-02-24 17:07:53 -0500 | [diff] [blame] | 1 | # CMakeLists.txt -- Build system for the pybind11 test suite |
| 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 | |
| 8 | cmake_minimum_required(VERSION 2.8.12) |
| 9 | |
| 10 | option(PYBIND11_WERROR "Report all warnings as errors" OFF) |
| 11 | |
| 12 | if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) |
| 13 | # We're being loaded directly, i.e. not via add_subdirectory, so make this |
| 14 | # work as its own project and load the pybind11Config to get the tools we need |
| 15 | project(pybind11_tests) |
| 16 | |
| 17 | find_package(pybind11 REQUIRED CONFIG) |
| 18 | endif() |
| 19 | |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 20 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) |
| 21 | message(STATUS "Setting tests build type to MinSizeRel as none was specified") |
Wenzel Jakob | 7962f30 | 2016-09-17 12:58:18 +0200 | [diff] [blame] | 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") |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 25 | endif() |
| 26 | |
Jason Rhinelander | 920e0e3 | 2016-11-12 19:10:53 -0500 | [diff] [blame] | 27 | # Full set of test files (you can override these; see below) |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 28 | set(PYBIND11_TEST_FILES |
Jason Rhinelander | ec62d97 | 2016-09-09 02:42:51 -0400 | [diff] [blame] | 29 | test_alias_initialization.cpp |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 30 | test_buffers.cpp |
Dean Moldovan | 1ac1903 | 2017-03-16 11:22:26 +0100 | [diff] [blame] | 31 | test_call_policies.cpp |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 32 | test_callbacks.cpp |
Trent Houliston | 352149e | 2016-08-25 23:08:04 +1000 | [diff] [blame] | 33 | test_chrono.cpp |
Jason Rhinelander | 5fffe20 | 2016-09-06 12:17:06 -0400 | [diff] [blame] | 34 | test_class_args.cpp |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 35 | test_constants_and_functions.cpp |
Jason Rhinelander | 813d7e8 | 2017-05-14 15:57:26 -0400 | [diff] [blame] | 36 | test_copy_move.cpp |
Alexander Stukowski | 9a110e6 | 2016-11-15 12:38:05 +0100 | [diff] [blame] | 37 | test_docstring_options.cpp |
Jason Rhinelander | 52f4be8 | 2016-09-03 14:54:22 -0400 | [diff] [blame] | 38 | test_eigen.cpp |
Dean Moldovan | a9a37b4 | 2016-08-13 00:57:24 +0200 | [diff] [blame] | 39 | test_enum.cpp |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 40 | test_eval.cpp |
| 41 | test_exceptions.cpp |
| 42 | test_inheritance.cpp |
| 43 | test_issues.cpp |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 44 | test_kwargs_and_defaults.cpp |
| 45 | test_methods_and_attributes.cpp |
| 46 | test_modules.cpp |
Dean Moldovan | 568ec6b | 2016-09-20 11:52:25 +0200 | [diff] [blame] | 47 | test_multiple_inheritance.cpp |
Ivan Smirnov | 91b3d68 | 2016-08-29 02:41:05 +0100 | [diff] [blame] | 48 | test_numpy_array.cpp |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 49 | test_numpy_dtypes.cpp |
| 50 | test_numpy_vectorize.cpp |
| 51 | test_opaque_types.cpp |
| 52 | test_operator_overloading.cpp |
| 53 | test_pickling.cpp |
| 54 | test_python_types.cpp |
| 55 | test_sequences_and_iterators.cpp |
Dean Moldovan | 568ec6b | 2016-09-20 11:52:25 +0200 | [diff] [blame] | 56 | test_smart_ptr.cpp |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 57 | test_stl_binders.cpp |
| 58 | test_virtual_functions.cpp |
| 59 | ) |
| 60 | |
Jason Rhinelander | 920e0e3 | 2016-11-12 19:10:53 -0500 | [diff] [blame] | 61 | # Invoking cmake with something like: |
| 62 | # cmake -DPYBIND11_TEST_OVERRIDE="test_issues.cpp;test_picking.cpp" .. |
| 63 | # lets you override the tests that get compiled and run. You can restore to all tests with: |
| 64 | # cmake -DPYBIND11_TEST_OVERRIDE= .. |
| 65 | if (PYBIND11_TEST_OVERRIDE) |
| 66 | set(PYBIND11_TEST_FILES ${PYBIND11_TEST_OVERRIDE}) |
| 67 | endif() |
| 68 | |
Jason Rhinelander | 52f4be8 | 2016-09-03 14:54:22 -0400 | [diff] [blame] | 69 | string(REPLACE ".cpp" ".py" PYBIND11_PYTEST_FILES "${PYBIND11_TEST_FILES}") |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 70 | |
Jason Rhinelander | 52f4be8 | 2016-09-03 14:54:22 -0400 | [diff] [blame] | 71 | # Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but |
| 72 | # keep it in PYBIND11_PYTEST_FILES, so that we get the "eigen is not installed" |
| 73 | # skip message). |
| 74 | list(FIND PYBIND11_TEST_FILES test_eigen.cpp PYBIND11_TEST_FILES_EIGEN_I) |
| 75 | if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1) |
Jason Rhinelander | 60d0e0d | 2017-02-24 17:07:53 -0500 | [diff] [blame] | 76 | # Try loading via newer Eigen's Eigen3Config first (bypassing tools/FindEigen3.cmake). |
| 77 | # Eigen 3.3.1+ exports a cmake 3.0+ target for handling dependency requirements, but also |
| 78 | # produces a fatal error if loaded from a pre-3.0 cmake. |
| 79 | if (NOT CMAKE_VERSION VERSION_LESS 3.0) |
| 80 | find_package(Eigen3 QUIET CONFIG) |
| 81 | if (EIGEN3_FOUND) |
| 82 | if (EIGEN3_VERSION_STRING AND NOT EIGEN3_VERSION_STRING VERSION_LESS 3.3.1) |
| 83 | set(PYBIND11_EIGEN_VIA_TARGET 1) |
| 84 | endif() |
| 85 | endif() |
| 86 | endif() |
| 87 | if (NOT EIGEN3_FOUND) |
| 88 | # Couldn't load via target, so fall back to allowing module mode finding, which will pick up |
| 89 | # tools/FindEigen3.cmake |
| 90 | find_package(Eigen3 QUIET) |
| 91 | endif() |
Jason Rhinelander | 52f4be8 | 2016-09-03 14:54:22 -0400 | [diff] [blame] | 92 | |
| 93 | if(EIGEN3_FOUND) |
Jason Rhinelander | 60d0e0d | 2017-02-24 17:07:53 -0500 | [diff] [blame] | 94 | # Eigen 3.3.1+ cmake sets EIGEN3_VERSION_STRING (and hard codes the version when installed |
| 95 | # rather than looking it up in the cmake script); older versions, and the |
| 96 | # tools/FindEigen3.cmake, set EIGEN3_VERSION instead. |
| 97 | if(NOT EIGEN3_VERSION AND EIGEN3_VERSION_STRING) |
| 98 | set(EIGEN3_VERSION ${EIGEN3_VERSION_STRING}) |
| 99 | endif() |
Jason Rhinelander | 52f4be8 | 2016-09-03 14:54:22 -0400 | [diff] [blame] | 100 | message(STATUS "Building tests with Eigen v${EIGEN3_VERSION}") |
| 101 | else() |
| 102 | list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I}) |
| 103 | message(STATUS "Building tests WITHOUT Eigen") |
| 104 | endif() |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 105 | endif() |
| 106 | |
Jason Rhinelander | 60d0e0d | 2017-02-24 17:07:53 -0500 | [diff] [blame] | 107 | # Compile with compiler warnings turned on |
| 108 | function(pybind11_enable_warnings target_name) |
| 109 | if(MSVC) |
| 110 | target_compile_options(${target_name} PRIVATE /W4) |
| 111 | else() |
| 112 | target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wconversion -Wcast-qual) |
| 113 | endif() |
| 114 | |
| 115 | if(PYBIND11_WERROR) |
| 116 | if(MSVC) |
| 117 | target_compile_options(${target_name} PRIVATE /WX) |
| 118 | else() |
| 119 | target_compile_options(${target_name} PRIVATE -Werror) |
| 120 | endif() |
| 121 | endif() |
| 122 | endfunction() |
| 123 | |
| 124 | |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 125 | # Create the binding library |
Jason Rhinelander | 1bee6e7 | 2017-01-17 02:13:11 -0500 | [diff] [blame] | 126 | pybind11_add_module(pybind11_tests THIN_LTO pybind11_tests.cpp |
Wenzel Jakob | dac3858 | 2016-09-29 21:30:00 +0200 | [diff] [blame] | 127 | ${PYBIND11_TEST_FILES} ${PYBIND11_HEADERS}) |
| 128 | |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 129 | pybind11_enable_warnings(pybind11_tests) |
| 130 | |
Jason Rhinelander | 8dc63ba | 2017-05-25 01:05:49 -0400 | [diff] [blame] | 131 | if(MSVC) |
| 132 | target_compile_options(pybind11_tests PRIVATE /utf-8) |
| 133 | endif() |
| 134 | |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 135 | if(EIGEN3_FOUND) |
Jason Rhinelander | 60d0e0d | 2017-02-24 17:07:53 -0500 | [diff] [blame] | 136 | if (PYBIND11_EIGEN_VIA_TARGET) |
| 137 | target_link_libraries(pybind11_tests PRIVATE Eigen3::Eigen) |
| 138 | else() |
| 139 | target_include_directories(pybind11_tests PRIVATE ${EIGEN3_INCLUDE_DIR}) |
| 140 | endif() |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 141 | target_compile_definitions(pybind11_tests PRIVATE -DPYBIND11_TEST_EIGEN) |
| 142 | endif() |
| 143 | |
Jason Rhinelander | 60d0e0d | 2017-02-24 17:07:53 -0500 | [diff] [blame] | 144 | set(testdir ${CMAKE_CURRENT_SOURCE_DIR}) |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 145 | |
| 146 | # Always write the output file directly into the 'tests' directory (even on MSVC) |
| 147 | if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) |
| 148 | set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${testdir}) |
| 149 | foreach(config ${CMAKE_CONFIGURATION_TYPES}) |
| 150 | string(TOUPPER ${config} config) |
| 151 | set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config} ${testdir}) |
| 152 | endforeach() |
| 153 | endif() |
| 154 | |
Jason Rhinelander | dd3d56a | 2016-08-26 17:11:40 -0400 | [diff] [blame] | 155 | # Make sure pytest is found or produce a fatal error |
Dean Moldovan | 18319d5 | 2016-08-13 02:44:56 +0200 | [diff] [blame] | 156 | if(NOT PYBIND11_PYTEST_FOUND) |
Dean Moldovan | d47febc | 2017-03-10 15:42:42 +0100 | [diff] [blame] | 157 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import pytest; print(pytest.__version__)" |
| 158 | RESULT_VARIABLE pytest_not_found OUTPUT_VARIABLE pytest_version ERROR_QUIET) |
| 159 | if(pytest_not_found) |
| 160 | message(FATAL_ERROR "Running the tests requires pytest. Please install it manually" |
| 161 | " (try: ${PYTHON_EXECUTABLE} -m pip install pytest)") |
| 162 | elseif(pytest_version VERSION_LESS 3.0) |
| 163 | message(FATAL_ERROR "Running the tests requires pytest >= 3.0. Found: ${pytest_version}" |
| 164 | "Please update it (try: ${PYTHON_EXECUTABLE} -m pip install -U pytest)") |
Dean Moldovan | 18319d5 | 2016-08-13 02:44:56 +0200 | [diff] [blame] | 165 | endif() |
Wenzel Jakob | b55a5c5 | 2016-10-09 13:51:05 +0200 | [diff] [blame] | 166 | set(PYBIND11_PYTEST_FOUND TRUE CACHE INTERNAL "") |
Dean Moldovan | 18319d5 | 2016-08-13 02:44:56 +0200 | [diff] [blame] | 167 | endif() |
| 168 | |
Wenzel Jakob | 7653a11 | 2017-04-28 22:43:14 +0200 | [diff] [blame] | 169 | if(CMAKE_VERSION VERSION_LESS 3.2) |
| 170 | set(PYBIND11_USES_TERMINAL "") |
| 171 | else() |
| 172 | set(PYBIND11_USES_TERMINAL "USES_TERMINAL") |
| 173 | endif() |
| 174 | |
Dean Moldovan | a0c1ccf | 2016-08-12 13:50:00 +0200 | [diff] [blame] | 175 | # A single command to compile and run the tests |
Dean Moldovan | d47febc | 2017-03-10 15:42:42 +0100 | [diff] [blame] | 176 | add_custom_target(pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PYBIND11_PYTEST_FILES} |
Wenzel Jakob | 7653a11 | 2017-04-28 22:43:14 +0200 | [diff] [blame] | 177 | DEPENDS pybind11_tests WORKING_DIRECTORY ${testdir} ${PYBIND11_USES_TERMINAL}) |
Jason Rhinelander | dc0b4bd | 2016-11-04 09:47:41 -0400 | [diff] [blame] | 178 | |
Jason Rhinelander | 920e0e3 | 2016-11-12 19:10:53 -0500 | [diff] [blame] | 179 | if(PYBIND11_TEST_OVERRIDE) |
| 180 | add_custom_command(TARGET pytest POST_BUILD |
| 181 | COMMAND ${CMAKE_COMMAND} -E echo "Note: not all tests run: -DPYBIND11_TEST_OVERRIDE is in effect") |
| 182 | endif() |
| 183 | |
Jason Rhinelander | 60d0e0d | 2017-02-24 17:07:53 -0500 | [diff] [blame] | 184 | # Add a check target to run all the tests, starting with pytest (we add dependencies to this below) |
| 185 | add_custom_target(check DEPENDS pytest) |
| 186 | |
| 187 | # The remaining tests only apply when being built as part of the pybind11 project, but not if the |
| 188 | # tests are being built independently. |
| 189 | if (NOT PROJECT_NAME STREQUAL "pybind11") |
| 190 | return() |
| 191 | endif() |
| 192 | |
| 193 | # Add a post-build comment to show the .so size and, if a previous size, compare it: |
Jason Rhinelander | dc0b4bd | 2016-11-04 09:47:41 -0400 | [diff] [blame] | 194 | add_custom_command(TARGET pybind11_tests POST_BUILD |
Matthew Woehlke | 5e92b3e | 2017-02-08 17:43:23 -0500 | [diff] [blame] | 195 | COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/libsize.py |
Dean Moldovan | b0f3885 | 2016-12-14 01:43:39 +0100 | [diff] [blame] | 196 | $<TARGET_FILE:pybind11_tests> ${CMAKE_CURRENT_BINARY_DIR}/sosize-$<TARGET_FILE_NAME:pybind11_tests>.txt) |
| 197 | |
Dean Moldovan | 9693a5c | 2017-03-23 17:27:32 +0100 | [diff] [blame] | 198 | # Test embedding the interpreter. Provides the `cpptest` target. |
| 199 | add_subdirectory(test_embed) |
| 200 | |
Dean Moldovan | b0f3885 | 2016-12-14 01:43:39 +0100 | [diff] [blame] | 201 | # Test CMake build using functions and targets from subdirectory or installed location |
| 202 | add_custom_target(test_cmake_build) |
| 203 | if(NOT CMAKE_VERSION VERSION_LESS 3.1) |
| 204 | # 3.0 needed for interface library for subdirectory_target/installed_target |
| 205 | # 3.1 needed for cmake -E env for testing |
| 206 | |
| 207 | include(CMakeParseArguments) |
| 208 | function(pybind11_add_build_test name) |
| 209 | cmake_parse_arguments(ARG "INSTALL" "" "" ${ARGN}) |
| 210 | |
| 211 | set(build_options "-DCMAKE_PREFIX_PATH=${PROJECT_BINARY_DIR}/mock_install" |
| 212 | "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" |
Dean Moldovan | 555dc4f | 2017-04-06 22:41:24 +0200 | [diff] [blame] | 213 | "-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}" |
Dean Moldovan | b0f3885 | 2016-12-14 01:43:39 +0100 | [diff] [blame] | 214 | "-DPYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}") |
| 215 | if(NOT ARG_INSTALL) |
| 216 | list(APPEND build_options "-DPYBIND11_PROJECT_DIR=${PROJECT_SOURCE_DIR}") |
| 217 | endif() |
| 218 | |
| 219 | add_custom_target(test_${name} ${CMAKE_CTEST_COMMAND} |
| 220 | --quiet --output-log test_cmake_build/${name}.log |
| 221 | --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/test_cmake_build/${name}" |
| 222 | "${CMAKE_CURRENT_BINARY_DIR}/test_cmake_build/${name}" |
| 223 | --build-config Release |
| 224 | --build-noclean |
| 225 | --build-generator ${CMAKE_GENERATOR} |
| 226 | $<$<BOOL:${CMAKE_GENERATOR_PLATFORM}>:--build-generator-platform> ${CMAKE_GENERATOR_PLATFORM} |
| 227 | --build-makeprogram ${CMAKE_MAKE_PROGRAM} |
| 228 | --build-target check |
| 229 | --build-options ${build_options} |
| 230 | ) |
| 231 | if(ARG_INSTALL) |
| 232 | add_dependencies(test_${name} mock_install) |
| 233 | endif() |
| 234 | add_dependencies(test_cmake_build test_${name}) |
| 235 | endfunction() |
| 236 | |
| 237 | pybind11_add_build_test(subdirectory_function) |
| 238 | pybind11_add_build_test(subdirectory_target) |
Dean Moldovan | 7f5c85c | 2017-03-23 13:32:54 +0100 | [diff] [blame] | 239 | if(NOT ${PYTHON_MODULE_EXTENSION} MATCHES "pypy") |
| 240 | pybind11_add_build_test(subdirectory_embed) |
| 241 | endif() |
Dean Moldovan | b0f3885 | 2016-12-14 01:43:39 +0100 | [diff] [blame] | 242 | |
| 243 | if(PYBIND11_INSTALL) |
| 244 | add_custom_target(mock_install ${CMAKE_COMMAND} |
| 245 | "-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/mock_install" |
| 246 | -P "${PROJECT_BINARY_DIR}/cmake_install.cmake" |
| 247 | ) |
| 248 | |
| 249 | pybind11_add_build_test(installed_function INSTALL) |
| 250 | pybind11_add_build_test(installed_target INSTALL) |
Dean Moldovan | 7f5c85c | 2017-03-23 13:32:54 +0100 | [diff] [blame] | 251 | if(NOT ${PYTHON_MODULE_EXTENSION} MATCHES "pypy") |
| 252 | pybind11_add_build_test(installed_embed INSTALL) |
| 253 | endif() |
Dean Moldovan | b0f3885 | 2016-12-14 01:43:39 +0100 | [diff] [blame] | 254 | endif() |
| 255 | endif() |
Dean Moldovan | 06b9397 | 2016-12-17 21:39:17 +0100 | [diff] [blame] | 256 | |
Jason Rhinelander | 60d0e0d | 2017-02-24 17:07:53 -0500 | [diff] [blame] | 257 | add_dependencies(check test_cmake_build) |