Add cross-module test plugin

This adds the infrastructure for a separate test plugin for cross-module
tests.  (This commit contains no tests that actually use it, but the
following commits do; this is separated simply to provide a cleaner
commit history).
This commit is contained in:
Jason Rhinelander 2017-07-28 20:57:57 -04:00
parent e98d31d697
commit 0bd5979c77
2 changed files with 69 additions and 27 deletions

View File

@ -67,6 +67,12 @@ endif()
string(REPLACE ".cpp" ".py" PYBIND11_PYTEST_FILES "${PYBIND11_TEST_FILES}") string(REPLACE ".cpp" ".py" PYBIND11_PYTEST_FILES "${PYBIND11_TEST_FILES}")
# Contains the set of test files that require pybind11_cross_module_tests to be
# built; if none of these are built (i.e. because TEST_OVERRIDE is used and
# doesn't include them) the second module doesn't get built.
set(PYBIND11_CROSS_MODULE_TESTS
)
# Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but # Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but
# keep it in PYBIND11_PYTEST_FILES, so that we get the "eigen is not installed" # keep it in PYBIND11_PYTEST_FILES, so that we get the "eigen is not installed"
# skip message). # skip message).
@ -120,36 +126,52 @@ function(pybind11_enable_warnings target_name)
endif() endif()
endfunction() endfunction()
set(test_targets pybind11_tests)
# Create the binding library # Build pybind11_cross_module_tests if any test_whatever.py are being built that require it
pybind11_add_module(pybind11_tests THIN_LTO pybind11_tests.cpp foreach(t ${PYBIND11_CROSS_MODULE_TESTS})
${PYBIND11_TEST_FILES} ${PYBIND11_HEADERS}) list(FIND PYBIND11_PYTEST_FILES ${t} i)
if (i GREATER -1)
pybind11_enable_warnings(pybind11_tests) list(APPEND test_targets pybind11_cross_module_tests)
break()
if(MSVC)
target_compile_options(pybind11_tests PRIVATE /utf-8)
endif()
if(EIGEN3_FOUND)
if (PYBIND11_EIGEN_VIA_TARGET)
target_link_libraries(pybind11_tests PRIVATE Eigen3::Eigen)
else()
target_include_directories(pybind11_tests PRIVATE ${EIGEN3_INCLUDE_DIR})
endif() endif()
target_compile_definitions(pybind11_tests PRIVATE -DPYBIND11_TEST_EIGEN) endforeach()
endif()
set(testdir ${CMAKE_CURRENT_SOURCE_DIR}) set(testdir ${CMAKE_CURRENT_SOURCE_DIR})
foreach(tgt ${test_targets})
set(test_files ${PYBIND11_TEST_FILES})
if(NOT tgt STREQUAL "pybind11_tests")
set(test_files "")
endif()
# Always write the output file directly into the 'tests' directory (even on MSVC) # Create the binding library
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY) pybind11_add_module(${tgt} THIN_LTO ${tgt}.cpp
set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${testdir}) ${test_files} ${PYBIND11_HEADERS})
foreach(config ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${config} config) pybind11_enable_warnings(${tgt})
set_target_properties(pybind11_tests PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config} ${testdir})
endforeach() if(MSVC)
endif() target_compile_options(${tgt} PRIVATE /utf-8)
endif()
if(EIGEN3_FOUND)
if (PYBIND11_EIGEN_VIA_TARGET)
target_link_libraries(${tgt} PRIVATE Eigen3::Eigen)
else()
target_include_directories(${tgt} PRIVATE ${EIGEN3_INCLUDE_DIR})
endif()
target_compile_definitions(${tgt} PRIVATE -DPYBIND11_TEST_EIGEN)
endif()
# Always write the output file directly into the 'tests' directory (even on MSVC)
if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set_target_properties(${tgt} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${testdir})
foreach(config ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${config} config)
set_target_properties(${tgt} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config} ${testdir})
endforeach()
endif()
endforeach()
# Make sure pytest is found or produce a fatal error # Make sure pytest is found or produce a fatal error
if(NOT PYBIND11_PYTEST_FOUND) if(NOT PYBIND11_PYTEST_FOUND)
@ -173,7 +195,7 @@ endif()
# A single command to compile and run the tests # A single command to compile and run the tests
add_custom_target(pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PYBIND11_PYTEST_FILES} add_custom_target(pytest COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PYBIND11_PYTEST_FILES}
DEPENDS pybind11_tests WORKING_DIRECTORY ${testdir} ${PYBIND11_USES_TERMINAL}) DEPENDS ${test_targets} WORKING_DIRECTORY ${testdir} ${PYBIND11_USES_TERMINAL})
if(PYBIND11_TEST_OVERRIDE) if(PYBIND11_TEST_OVERRIDE)
add_custom_command(TARGET pytest POST_BUILD add_custom_command(TARGET pytest POST_BUILD
@ -189,7 +211,7 @@ if (NOT PROJECT_NAME STREQUAL "pybind11")
return() return()
endif() endif()
# Add a post-build comment to show the .so size and, if a previous size, compare it: # Add a post-build comment to show the primary test suite .so size and, if a previous size, compare it:
add_custom_command(TARGET pybind11_tests POST_BUILD add_custom_command(TARGET pybind11_tests POST_BUILD
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/libsize.py COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/libsize.py
$<TARGET_FILE:pybind11_tests> ${CMAKE_CURRENT_BINARY_DIR}/sosize-$<TARGET_FILE_NAME:pybind11_tests>.txt) $<TARGET_FILE:pybind11_tests> ${CMAKE_CURRENT_BINARY_DIR}/sosize-$<TARGET_FILE_NAME:pybind11_tests>.txt)

View File

@ -0,0 +1,20 @@
/*
tests/pybind11_cross_module_tests.cpp -- contains tests that require multiple modules
Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#include "pybind11_tests.h"
PYBIND11_MODULE(pybind11_cross_module_tests, m) {
m.doc() = "pybind11 cross-module test module";
// test_local_bindings.py tests:
//
// Definitions here are tested by importing both this module and the
// relevant pybind11_tests submodule from a test_whatever.py
}