CMakeLists.txt revision 12037
112037Sandreas.sandberg@arm.com# CMakeLists.txt -- Build system for the pybind11 test suite 212037Sandreas.sandberg@arm.com# 312037Sandreas.sandberg@arm.com# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch> 412037Sandreas.sandberg@arm.com# 512037Sandreas.sandberg@arm.com# All rights reserved. Use of this source code is governed by a 612037Sandreas.sandberg@arm.com# BSD-style license that can be found in the LICENSE file. 712037Sandreas.sandberg@arm.com 812037Sandreas.sandberg@arm.comcmake_minimum_required(VERSION 2.8.12) 912037Sandreas.sandberg@arm.com 1012037Sandreas.sandberg@arm.comoption(PYBIND11_WERROR "Report all warnings as errors" OFF) 1112037Sandreas.sandberg@arm.com 1212037Sandreas.sandberg@arm.comif (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) 1312037Sandreas.sandberg@arm.com # We're being loaded directly, i.e. not via add_subdirectory, so make this 1412037Sandreas.sandberg@arm.com # work as its own project and load the pybind11Config to get the tools we need 1512037Sandreas.sandberg@arm.com project(pybind11_tests) 1612037Sandreas.sandberg@arm.com 1712037Sandreas.sandberg@arm.com find_package(pybind11 REQUIRED CONFIG) 1812037Sandreas.sandberg@arm.comendif() 1912037Sandreas.sandberg@arm.com 2011986Sandreas.sandberg@arm.comif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 2111986Sandreas.sandberg@arm.com message(STATUS "Setting tests build type to MinSizeRel as none was specified") 2211986Sandreas.sandberg@arm.com set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build." FORCE) 2311986Sandreas.sandberg@arm.com set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" 2411986Sandreas.sandberg@arm.com "MinSizeRel" "RelWithDebInfo") 2511986Sandreas.sandberg@arm.comendif() 2611986Sandreas.sandberg@arm.com 2711986Sandreas.sandberg@arm.com# Full set of test files (you can override these; see below) 2811986Sandreas.sandberg@arm.comset(PYBIND11_TEST_FILES 2911986Sandreas.sandberg@arm.com test_alias_initialization.cpp 3011986Sandreas.sandberg@arm.com test_buffers.cpp 3111986Sandreas.sandberg@arm.com test_callbacks.cpp 3211986Sandreas.sandberg@arm.com test_chrono.cpp 3311986Sandreas.sandberg@arm.com test_class_args.cpp 3411986Sandreas.sandberg@arm.com test_constants_and_functions.cpp 3511986Sandreas.sandberg@arm.com test_copy_move_policies.cpp 3611986Sandreas.sandberg@arm.com test_docstring_options.cpp 3711986Sandreas.sandberg@arm.com test_eigen.cpp 3811986Sandreas.sandberg@arm.com test_enum.cpp 3911986Sandreas.sandberg@arm.com test_eval.cpp 4011986Sandreas.sandberg@arm.com test_exceptions.cpp 4111986Sandreas.sandberg@arm.com test_inheritance.cpp 4211986Sandreas.sandberg@arm.com test_issues.cpp 4311986Sandreas.sandberg@arm.com test_keep_alive.cpp 4411986Sandreas.sandberg@arm.com test_kwargs_and_defaults.cpp 4511986Sandreas.sandberg@arm.com test_methods_and_attributes.cpp 4611986Sandreas.sandberg@arm.com test_modules.cpp 4711986Sandreas.sandberg@arm.com test_multiple_inheritance.cpp 4811986Sandreas.sandberg@arm.com test_numpy_array.cpp 4911986Sandreas.sandberg@arm.com test_numpy_dtypes.cpp 5011986Sandreas.sandberg@arm.com test_numpy_vectorize.cpp 5111986Sandreas.sandberg@arm.com test_opaque_types.cpp 5211986Sandreas.sandberg@arm.com test_operator_overloading.cpp 5311986Sandreas.sandberg@arm.com test_pickling.cpp 5411986Sandreas.sandberg@arm.com test_python_types.cpp 5511986Sandreas.sandberg@arm.com test_sequences_and_iterators.cpp 5611986Sandreas.sandberg@arm.com test_smart_ptr.cpp 5711986Sandreas.sandberg@arm.com test_stl_binders.cpp 5811986Sandreas.sandberg@arm.com test_virtual_functions.cpp 5911986Sandreas.sandberg@arm.com) 6011986Sandreas.sandberg@arm.com 6111986Sandreas.sandberg@arm.com# Invoking cmake with something like: 6211986Sandreas.sandberg@arm.com# cmake -DPYBIND11_TEST_OVERRIDE="test_issues.cpp;test_picking.cpp" .. 6311986Sandreas.sandberg@arm.com# lets you override the tests that get compiled and run. You can restore to all tests with: 6411986Sandreas.sandberg@arm.com# cmake -DPYBIND11_TEST_OVERRIDE= .. 6511986Sandreas.sandberg@arm.comif (PYBIND11_TEST_OVERRIDE) 6611986Sandreas.sandberg@arm.com set(PYBIND11_TEST_FILES ${PYBIND11_TEST_OVERRIDE}) 6711986Sandreas.sandberg@arm.comendif() 6811986Sandreas.sandberg@arm.com 6911986Sandreas.sandberg@arm.comstring(REPLACE ".cpp" ".py" PYBIND11_PYTEST_FILES "${PYBIND11_TEST_FILES}") 7011986Sandreas.sandberg@arm.com 7111986Sandreas.sandberg@arm.com# Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but 7211986Sandreas.sandberg@arm.com# keep it in PYBIND11_PYTEST_FILES, so that we get the "eigen is not installed" 7311986Sandreas.sandberg@arm.com# skip message). 7411986Sandreas.sandberg@arm.comlist(FIND PYBIND11_TEST_FILES test_eigen.cpp PYBIND11_TEST_FILES_EIGEN_I) 7511986Sandreas.sandberg@arm.comif(PYBIND11_TEST_FILES_EIGEN_I GREATER -1) 7612037Sandreas.sandberg@arm.com # Try loading via newer Eigen's Eigen3Config first (bypassing tools/FindEigen3.cmake). 7712037Sandreas.sandberg@arm.com # Eigen 3.3.1+ exports a cmake 3.0+ target for handling dependency requirements, but also 7812037Sandreas.sandberg@arm.com # produces a fatal error if loaded from a pre-3.0 cmake. 7912037Sandreas.sandberg@arm.com if (NOT CMAKE_VERSION VERSION_LESS 3.0) 8012037Sandreas.sandberg@arm.com find_package(Eigen3 QUIET CONFIG) 8112037Sandreas.sandberg@arm.com if (EIGEN3_FOUND) 8212037Sandreas.sandberg@arm.com if (EIGEN3_VERSION_STRING AND NOT EIGEN3_VERSION_STRING VERSION_LESS 3.3.1) 8312037Sandreas.sandberg@arm.com set(PYBIND11_EIGEN_VIA_TARGET 1) 8412037Sandreas.sandberg@arm.com endif() 8512037Sandreas.sandberg@arm.com endif() 8612037Sandreas.sandberg@arm.com endif() 8712037Sandreas.sandberg@arm.com if (NOT EIGEN3_FOUND) 8812037Sandreas.sandberg@arm.com # Couldn't load via target, so fall back to allowing module mode finding, which will pick up 8912037Sandreas.sandberg@arm.com # tools/FindEigen3.cmake 9012037Sandreas.sandberg@arm.com find_package(Eigen3 QUIET) 9112037Sandreas.sandberg@arm.com endif() 9211986Sandreas.sandberg@arm.com 9311986Sandreas.sandberg@arm.com if(EIGEN3_FOUND) 9412037Sandreas.sandberg@arm.com # Eigen 3.3.1+ cmake sets EIGEN3_VERSION_STRING (and hard codes the version when installed 9512037Sandreas.sandberg@arm.com # rather than looking it up in the cmake script); older versions, and the 9612037Sandreas.sandberg@arm.com # tools/FindEigen3.cmake, set EIGEN3_VERSION instead. 9712037Sandreas.sandberg@arm.com if(NOT EIGEN3_VERSION AND EIGEN3_VERSION_STRING) 9812037Sandreas.sandberg@arm.com set(EIGEN3_VERSION ${EIGEN3_VERSION_STRING}) 9912037Sandreas.sandberg@arm.com endif() 10011986Sandreas.sandberg@arm.com message(STATUS "Building tests with Eigen v${EIGEN3_VERSION}") 10111986Sandreas.sandberg@arm.com else() 10211986Sandreas.sandberg@arm.com list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I}) 10311986Sandreas.sandberg@arm.com message(STATUS "Building tests WITHOUT Eigen") 10411986Sandreas.sandberg@arm.com endif() 10511986Sandreas.sandberg@arm.comendif() 10611986Sandreas.sandberg@arm.com 10712037Sandreas.sandberg@arm.com# Compile with compiler warnings turned on 10812037Sandreas.sandberg@arm.comfunction(pybind11_enable_warnings target_name) 10912037Sandreas.sandberg@arm.com if(MSVC) 11012037Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE /W4) 11112037Sandreas.sandberg@arm.com else() 11212037Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wconversion -Wcast-qual) 11312037Sandreas.sandberg@arm.com endif() 11412037Sandreas.sandberg@arm.com 11512037Sandreas.sandberg@arm.com if(PYBIND11_WERROR) 11612037Sandreas.sandberg@arm.com if(MSVC) 11712037Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE /WX) 11812037Sandreas.sandberg@arm.com else() 11912037Sandreas.sandberg@arm.com target_compile_options(${target_name} PRIVATE -Werror) 12012037Sandreas.sandberg@arm.com endif() 12112037Sandreas.sandberg@arm.com endif() 12212037Sandreas.sandberg@arm.comendfunction() 12312037Sandreas.sandberg@arm.com 12412037Sandreas.sandberg@arm.com 12511986Sandreas.sandberg@arm.com# Create the binding library 12612037Sandreas.sandberg@arm.compybind11_add_module(pybind11_tests THIN_LTO pybind11_tests.cpp 12711986Sandreas.sandberg@arm.com ${PYBIND11_TEST_FILES} ${PYBIND11_HEADERS}) 12811986Sandreas.sandberg@arm.com 12911986Sandreas.sandberg@arm.compybind11_enable_warnings(pybind11_tests) 13011986Sandreas.sandberg@arm.com 13111986Sandreas.sandberg@arm.comif(EIGEN3_FOUND) 13212037Sandreas.sandberg@arm.com if (PYBIND11_EIGEN_VIA_TARGET) 13312037Sandreas.sandberg@arm.com target_link_libraries(pybind11_tests PRIVATE Eigen3::Eigen) 13412037Sandreas.sandberg@arm.com else() 13512037Sandreas.sandberg@arm.com target_include_directories(pybind11_tests PRIVATE ${EIGEN3_INCLUDE_DIR}) 13612037Sandreas.sandberg@arm.com endif() 13711986Sandreas.sandberg@arm.com target_compile_definitions(pybind11_tests PRIVATE -DPYBIND11_TEST_EIGEN) 13811986Sandreas.sandberg@arm.comendif() 13911986Sandreas.sandberg@arm.com 14012037Sandreas.sandberg@arm.comset(testdir ${CMAKE_CURRENT_SOURCE_DIR}) 14111986Sandreas.sandberg@arm.com 14211986Sandreas.sandberg@arm.com# Always write the output file directly into the 'tests' directory (even on MSVC) 14311986Sandreas.sandberg@arm.comif(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) 14411986Sandreas.sandberg@arm.com set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${testdir}) 14511986Sandreas.sandberg@arm.com foreach(config ${CMAKE_CONFIGURATION_TYPES}) 14611986Sandreas.sandberg@arm.com string(TOUPPER ${config} config) 14711986Sandreas.sandberg@arm.com set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config} ${testdir}) 14811986Sandreas.sandberg@arm.com endforeach() 14911986Sandreas.sandberg@arm.comendif() 15011986Sandreas.sandberg@arm.com 15111986Sandreas.sandberg@arm.com# Make sure pytest is found or produce a fatal error 15211986Sandreas.sandberg@arm.comif(NOT PYBIND11_PYTEST_FOUND) 15312037Sandreas.sandberg@arm.com execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import pytest; print(pytest.__version__)" 15412037Sandreas.sandberg@arm.com RESULT_VARIABLE pytest_not_found OUTPUT_VARIABLE pytest_version ERROR_QUIET) 15512037Sandreas.sandberg@arm.com if(pytest_not_found) 15612037Sandreas.sandberg@arm.com message(FATAL_ERROR "Running the tests requires pytest. Please install it manually" 15712037Sandreas.sandberg@arm.com " (try: ${PYTHON_EXECUTABLE} -m pip install pytest)") 15812037Sandreas.sandberg@arm.com elseif(pytest_version VERSION_LESS 3.0) 15912037Sandreas.sandberg@arm.com message(FATAL_ERROR "Running the tests requires pytest >= 3.0. Found: ${pytest_version}" 16012037Sandreas.sandberg@arm.com "Please update it (try: ${PYTHON_EXECUTABLE} -m pip install -U pytest)") 16111986Sandreas.sandberg@arm.com endif() 16211986Sandreas.sandberg@arm.com set(PYBIND11_PYTEST_FOUND TRUE CACHE INTERNAL "") 16311986Sandreas.sandberg@arm.comendif() 16411986Sandreas.sandberg@arm.com 16511986Sandreas.sandberg@arm.com# A single command to compile and run the tests 16612037Sandreas.sandberg@arm.comadd_custom_target(pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PYBIND11_PYTEST_FILES} 16711986Sandreas.sandberg@arm.com DEPENDS pybind11_tests WORKING_DIRECTORY ${testdir}) 16811986Sandreas.sandberg@arm.com 16911986Sandreas.sandberg@arm.comif(PYBIND11_TEST_OVERRIDE) 17011986Sandreas.sandberg@arm.com add_custom_command(TARGET pytest POST_BUILD 17111986Sandreas.sandberg@arm.com COMMAND ${CMAKE_COMMAND} -E echo "Note: not all tests run: -DPYBIND11_TEST_OVERRIDE is in effect") 17211986Sandreas.sandberg@arm.comendif() 17311986Sandreas.sandberg@arm.com 17412037Sandreas.sandberg@arm.com# Add a check target to run all the tests, starting with pytest (we add dependencies to this below) 17512037Sandreas.sandberg@arm.comadd_custom_target(check DEPENDS pytest) 17612037Sandreas.sandberg@arm.com 17712037Sandreas.sandberg@arm.com# The remaining tests only apply when being built as part of the pybind11 project, but not if the 17812037Sandreas.sandberg@arm.com# tests are being built independently. 17912037Sandreas.sandberg@arm.comif (NOT PROJECT_NAME STREQUAL "pybind11") 18012037Sandreas.sandberg@arm.com return() 18111986Sandreas.sandberg@arm.comendif() 18211986Sandreas.sandberg@arm.com 18312037Sandreas.sandberg@arm.com# Add a post-build comment to show the .so size and, if a previous size, compare it: 18411986Sandreas.sandberg@arm.comadd_custom_command(TARGET pybind11_tests POST_BUILD 18512037Sandreas.sandberg@arm.com COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/libsize.py 18612037Sandreas.sandberg@arm.com $<TARGET_FILE:pybind11_tests> ${CMAKE_CURRENT_BINARY_DIR}/sosize-$<TARGET_FILE_NAME:pybind11_tests>.txt) 18712037Sandreas.sandberg@arm.com 18812037Sandreas.sandberg@arm.com# Test CMake build using functions and targets from subdirectory or installed location 18912037Sandreas.sandberg@arm.comadd_custom_target(test_cmake_build) 19012037Sandreas.sandberg@arm.comif(NOT CMAKE_VERSION VERSION_LESS 3.1) 19112037Sandreas.sandberg@arm.com # 3.0 needed for interface library for subdirectory_target/installed_target 19212037Sandreas.sandberg@arm.com # 3.1 needed for cmake -E env for testing 19312037Sandreas.sandberg@arm.com 19412037Sandreas.sandberg@arm.com include(CMakeParseArguments) 19512037Sandreas.sandberg@arm.com function(pybind11_add_build_test name) 19612037Sandreas.sandberg@arm.com cmake_parse_arguments(ARG "INSTALL" "" "" ${ARGN}) 19712037Sandreas.sandberg@arm.com 19812037Sandreas.sandberg@arm.com set(build_options "-DCMAKE_PREFIX_PATH=${PROJECT_BINARY_DIR}/mock_install" 19912037Sandreas.sandberg@arm.com "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" 20012037Sandreas.sandberg@arm.com "-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" 20112037Sandreas.sandberg@arm.com "-DPYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}") 20212037Sandreas.sandberg@arm.com if(NOT ARG_INSTALL) 20312037Sandreas.sandberg@arm.com list(APPEND build_options "-DPYBIND11_PROJECT_DIR=${PROJECT_SOURCE_DIR}") 20412037Sandreas.sandberg@arm.com endif() 20512037Sandreas.sandberg@arm.com 20612037Sandreas.sandberg@arm.com add_custom_target(test_${name} ${CMAKE_CTEST_COMMAND} 20712037Sandreas.sandberg@arm.com --quiet --output-log test_cmake_build/${name}.log 20812037Sandreas.sandberg@arm.com --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/test_cmake_build/${name}" 20912037Sandreas.sandberg@arm.com "${CMAKE_CURRENT_BINARY_DIR}/test_cmake_build/${name}" 21012037Sandreas.sandberg@arm.com --build-config Release 21112037Sandreas.sandberg@arm.com --build-noclean 21212037Sandreas.sandberg@arm.com --build-generator ${CMAKE_GENERATOR} 21312037Sandreas.sandberg@arm.com $<$<BOOL:${CMAKE_GENERATOR_PLATFORM}>:--build-generator-platform> ${CMAKE_GENERATOR_PLATFORM} 21412037Sandreas.sandberg@arm.com --build-makeprogram ${CMAKE_MAKE_PROGRAM} 21512037Sandreas.sandberg@arm.com --build-target check 21612037Sandreas.sandberg@arm.com --build-options ${build_options} 21712037Sandreas.sandberg@arm.com ) 21812037Sandreas.sandberg@arm.com if(ARG_INSTALL) 21912037Sandreas.sandberg@arm.com add_dependencies(test_${name} mock_install) 22012037Sandreas.sandberg@arm.com endif() 22112037Sandreas.sandberg@arm.com add_dependencies(test_cmake_build test_${name}) 22212037Sandreas.sandberg@arm.com endfunction() 22312037Sandreas.sandberg@arm.com 22412037Sandreas.sandberg@arm.com pybind11_add_build_test(subdirectory_function) 22512037Sandreas.sandberg@arm.com pybind11_add_build_test(subdirectory_target) 22612037Sandreas.sandberg@arm.com 22712037Sandreas.sandberg@arm.com if(PYBIND11_INSTALL) 22812037Sandreas.sandberg@arm.com add_custom_target(mock_install ${CMAKE_COMMAND} 22912037Sandreas.sandberg@arm.com "-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/mock_install" 23012037Sandreas.sandberg@arm.com -P "${PROJECT_BINARY_DIR}/cmake_install.cmake" 23112037Sandreas.sandberg@arm.com ) 23212037Sandreas.sandberg@arm.com 23312037Sandreas.sandberg@arm.com pybind11_add_build_test(installed_function INSTALL) 23412037Sandreas.sandberg@arm.com pybind11_add_build_test(installed_target INSTALL) 23512037Sandreas.sandberg@arm.com endif() 23612037Sandreas.sandberg@arm.comendif() 23712037Sandreas.sandberg@arm.com 23812037Sandreas.sandberg@arm.comadd_dependencies(check test_cmake_build) 239