diff --git a/.appveyor.yml b/.appveyor.yml index 740bd5c62..15a7933d8 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -30,4 +30,5 @@ build_script: - cmake -A "%CMAKE_ARCH%" -DPYBIND11_WERROR=ON - set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - cmake --build . --config Release --target pytest -- /v:m /logger:%MSBuildLogger% -- cmake --build . --config Release --target test_install -- /v:m /logger:%MSBuildLogger% +- cmake --build . --config Release --target test_cmake_build -- /v:m /logger:%MSBuildLogger% +on_failure: type tests\test_cmake_build\*.log diff --git a/.travis.yml b/.travis.yml index d4bdafd7e..ccaa6b429 100644 --- a/.travis.yml +++ b/.travis.yml @@ -135,6 +135,7 @@ script: -DPYBIND11_CPP_STANDARD=$CPP -DPYBIND11_WERROR=ON - $SCRIPT_RUN_PREFIX make pytest -j 2 -- $SCRIPT_RUN_PREFIX make test_install +- $SCRIPT_RUN_PREFIX make test_cmake_build +after_failure: cat tests/test_cmake_build/*.log after_script: - if [ -n "$DOCKER" ]; then docker stop "$containerid"; docker rm "$containerid"; fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 28012b8da..4fd68edf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,15 +85,22 @@ foreach(ver ${pybind11_version_defines}) endif() endforeach() set(${PROJECT_NAME}_VERSION ${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}) +message(STATUS "pybind11 v${${PROJECT_NAME}_VERSION}") if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) # CMake >= 3.0 # Build an interface library target: add_library(pybind11 INTERFACE) target_include_directories(pybind11 INTERFACE $ + $ $) - if(APPLE) - target_link_libraries(pybind11 INTERFACE "-undefined dynamic_lookup") + if(WIN32 OR CYGWIN) + target_link_libraries(pybind11 INTERFACE $) + elseif(APPLE) + target_link_libraries(pybind11 INTERFACE "-undefined dynamic_lookup") endif() + target_compile_options(pybind11 INTERFACE $) + + add_library(pybind11::pybind11 ALIAS pybind11) # to match exported target endif() if (PYBIND11_INSTALL) @@ -120,6 +127,5 @@ if (PYBIND11_INSTALL) install(EXPORT "${PROJECT_NAME}Targets" NAMESPACE "${PROJECT_NAME}::" DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR}) - message(STATUS "Exporting ${PROJECT_NAME}::pybind11 interface library target version ${${PROJECT_NAME}_VERSION}") endif() endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 27cb65291..1229acc93 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -105,55 +105,57 @@ if(PYBIND11_TEST_OVERRIDE) COMMAND ${CMAKE_COMMAND} -E echo "Note: not all tests run: -DPYBIND11_TEST_OVERRIDE is in effect") endif() -# test use of installation -if(PYBIND11_INSTALL) - # 2.8.12 needed for test_installed_module - # 3.0 needed for interface library for test_installed_target - # 3.1 needed for cmake -E env for testing - if(NOT CMAKE_VERSION VERSION_LESS 3.1) - add_custom_target(test_installed_target - COMMAND ${CMAKE_COMMAND} - "-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/test_install" - -P "${PROJECT_BINARY_DIR}/cmake_install.cmake" - COMMAND ${CMAKE_CTEST_COMMAND} - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/test_installed_target" - "${CMAKE_CURRENT_BINARY_DIR}/test_installed_target" - --build-noclean - --build-generator ${CMAKE_GENERATOR} - $<$:--build-generator-platform> ${CMAKE_GENERATOR_PLATFORM} - --build-makeprogram ${CMAKE_MAKE_PROGRAM} - --build-target check - --build-options "-DCMAKE_PREFIX_PATH=${PROJECT_BINARY_DIR}/test_install" - "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" - "-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" - "-DPYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}" - ) - add_custom_target(test_installed_module - COMMAND ${CMAKE_COMMAND} - "-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/test_install" - -P "${PROJECT_BINARY_DIR}/cmake_install.cmake" - COMMAND ${CMAKE_CTEST_COMMAND} - --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/test_installed_module" - "${CMAKE_CURRENT_BINARY_DIR}/test_installed_module" - --build-noclean - --build-generator ${CMAKE_GENERATOR} - $<$:--build-generator-platform> ${CMAKE_GENERATOR_PLATFORM} - --build-makeprogram ${CMAKE_MAKE_PROGRAM} - --build-target check - --build-options "-DCMAKE_PREFIX_PATH=${PROJECT_BINARY_DIR}/test_install" - "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" - "-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" - "-DPYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}" - ) - else() - add_custom_target(test_installed_target) - add_custom_target(test_installed_module) - endif() - add_custom_target(test_install) - add_dependencies(test_install test_installed_target test_installed_module) -endif() - # And another to show the .so size and, if a previous size, compare it: add_custom_command(TARGET pybind11_tests POST_BUILD - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/libsize.py - $ ${CMAKE_CURRENT_BINARY_DIR}/sosize-$.txt) + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/libsize.py + $ ${CMAKE_CURRENT_BINARY_DIR}/sosize-$.txt) + +# Test CMake build using functions and targets from subdirectory or installed location +add_custom_target(test_cmake_build) +if(NOT CMAKE_VERSION VERSION_LESS 3.1) + # 3.0 needed for interface library for subdirectory_target/installed_target + # 3.1 needed for cmake -E env for testing + + include(CMakeParseArguments) + function(pybind11_add_build_test name) + cmake_parse_arguments(ARG "INSTALL" "" "" ${ARGN}) + + set(build_options "-DCMAKE_PREFIX_PATH=${PROJECT_BINARY_DIR}/mock_install" + "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" + "-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" + "-DPYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}") + if(NOT ARG_INSTALL) + list(APPEND build_options "-DPYBIND11_PROJECT_DIR=${PROJECT_SOURCE_DIR}") + endif() + + add_custom_target(test_${name} ${CMAKE_CTEST_COMMAND} + --quiet --output-log test_cmake_build/${name}.log + --build-and-test "${CMAKE_CURRENT_SOURCE_DIR}/test_cmake_build/${name}" + "${CMAKE_CURRENT_BINARY_DIR}/test_cmake_build/${name}" + --build-config Release + --build-noclean + --build-generator ${CMAKE_GENERATOR} + $<$:--build-generator-platform> ${CMAKE_GENERATOR_PLATFORM} + --build-makeprogram ${CMAKE_MAKE_PROGRAM} + --build-target check + --build-options ${build_options} + ) + if(ARG_INSTALL) + add_dependencies(test_${name} mock_install) + endif() + add_dependencies(test_cmake_build test_${name}) + endfunction() + + pybind11_add_build_test(subdirectory_function) + pybind11_add_build_test(subdirectory_target) + + if(PYBIND11_INSTALL) + add_custom_target(mock_install ${CMAKE_COMMAND} + "-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/mock_install" + -P "${PROJECT_BINARY_DIR}/cmake_install.cmake" + ) + + pybind11_add_build_test(installed_function INSTALL) + pybind11_add_build_test(installed_target INSTALL) + endif() +endif() diff --git a/tests/test_cmake_build/installed_function/CMakeLists.txt b/tests/test_cmake_build/installed_function/CMakeLists.txt new file mode 100644 index 000000000..ff0b32e9c --- /dev/null +++ b/tests/test_cmake_build/installed_function/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 2.8.12) +project(test_installed_module CXX) + +set(CMAKE_MODULE_PATH "") + +find_package(pybind11 CONFIG REQUIRED) +message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") + +pybind11_add_module(test_cmake_build SHARED ../main.cpp) + +add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ + ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) diff --git a/tests/test_cmake_build/installed_target/CMakeLists.txt b/tests/test_cmake_build/installed_target/CMakeLists.txt new file mode 100644 index 000000000..e09a2fa83 --- /dev/null +++ b/tests/test_cmake_build/installed_target/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.0) +project(test_installed_target CXX) + +set(CMAKE_MODULE_PATH "") + +find_package(pybind11 CONFIG REQUIRED) +message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") + +add_library(test_cmake_build MODULE ../main.cpp) + +target_link_libraries(test_cmake_build PRIVATE pybind11::pybind11) + +# make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib +set_target_properties(test_cmake_build PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" + SUFFIX "${PYTHON_MODULE_EXTENSION}") + +add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ + ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) diff --git a/tests/test_installed_target/main.cpp b/tests/test_cmake_build/main.cpp similarity index 61% rename from tests/test_installed_target/main.cpp rename to tests/test_cmake_build/main.cpp index 2a84c11ce..e0f5b69c9 100644 --- a/tests/test_installed_target/main.cpp +++ b/tests/test_cmake_build/main.cpp @@ -1,8 +1,8 @@ #include namespace py = pybind11; -PYBIND11_PLUGIN(test_installed_target) { - py::module m("test_installed_target"); +PYBIND11_PLUGIN(test_cmake_build) { + py::module m("test_cmake_build"); m.def("add", [](int i, int j) { return i + j; }); diff --git a/tests/test_cmake_build/subdirectory_function/CMakeLists.txt b/tests/test_cmake_build/subdirectory_function/CMakeLists.txt new file mode 100644 index 000000000..71b77359f --- /dev/null +++ b/tests/test_cmake_build/subdirectory_function/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 2.8.12) +project(test_subdirectory_module CXX) + +add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11) +pybind11_add_module(test_cmake_build ../main.cpp) + +add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ + ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) diff --git a/tests/test_cmake_build/subdirectory_target/CMakeLists.txt b/tests/test_cmake_build/subdirectory_target/CMakeLists.txt new file mode 100644 index 000000000..ee3f48944 --- /dev/null +++ b/tests/test_cmake_build/subdirectory_target/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.0) +project(test_subdirectory_target CXX) + +add_subdirectory(${PYBIND11_PROJECT_DIR} pybind11) + +add_library(test_cmake_build MODULE ../main.cpp) + +target_link_libraries(test_cmake_build PRIVATE pybind11::pybind11) + +# make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib +set_target_properties(test_cmake_build PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" + SUFFIX "${PYTHON_MODULE_EXTENSION}") + +add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ + ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/../test.py ${PROJECT_NAME}) diff --git a/tests/test_cmake_build/test.py b/tests/test_cmake_build/test.py new file mode 100644 index 000000000..1467a61dc --- /dev/null +++ b/tests/test_cmake_build/test.py @@ -0,0 +1,5 @@ +import sys +import test_cmake_build + +assert test_cmake_build.add(1, 2) == 3 +print("{} imports, runs, and adds: 1 + 2 = 3".format(sys.argv[1])) diff --git a/tests/test_installed_module/CMakeLists.txt b/tests/test_installed_module/CMakeLists.txt deleted file mode 100644 index 77fd49dc2..000000000 --- a/tests/test_installed_module/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) -project(test_installed_module CXX) - -set(CMAKE_MODULE_PATH "") - -find_package(pybind11 CONFIG REQUIRED) - -message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS} (found version ${pybind11_VERSION})") -message(STATUS "Found Python: ${PYTHON_INCLUDE_DIRS} (found version ${PYTHON_VERSION_STRING})") - -pybind11_add_module(test_installed_module SHARED main.cpp) - -add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ - ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test.py) diff --git a/tests/test_installed_module/main.cpp b/tests/test_installed_module/main.cpp deleted file mode 100644 index a0bda4542..000000000 --- a/tests/test_installed_module/main.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include -namespace py = pybind11; - -PYBIND11_PLUGIN(test_installed_module) { - py::module m("test_installed_module"); - - m.def("add", [](int i, int j) { return i + j; }); - - return m.ptr(); -} diff --git a/tests/test_installed_module/test.py b/tests/test_installed_module/test.py deleted file mode 100644 index 2f0632049..000000000 --- a/tests/test_installed_module/test.py +++ /dev/null @@ -1,3 +0,0 @@ -import test_installed_module -assert test_installed_module.add(11, 22) == 33 -print('test_installed_module imports, runs, and adds: 11 + 22 = 33') diff --git a/tests/test_installed_target/CMakeLists.txt b/tests/test_installed_target/CMakeLists.txt deleted file mode 100644 index 4333dc107..000000000 --- a/tests/test_installed_target/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -cmake_minimum_required(VERSION 3.0) -project(test_installed_target CXX) - -set(CMAKE_MODULE_PATH "") - -find_package(pybind11 CONFIG REQUIRED) - -message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS} (found version ${pybind11_VERSION})") -message(STATUS "Found Python: ${PYTHON_INCLUDE_DIRS} (found version ${PYTHON_VERSION_STRING})") - -add_library(test_installed_target MODULE main.cpp) - -target_link_libraries(test_installed_target PRIVATE pybind11::pybind11) - -# make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib -set_target_properties(test_installed_target PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}" - SUFFIX "${PYTHON_MODULE_EXTENSION}") - -add_custom_target(check ${CMAKE_COMMAND} -E env PYTHONPATH=$ - ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/test.py) diff --git a/tests/test_installed_target/test.py b/tests/test_installed_target/test.py deleted file mode 100644 index b2888a72b..000000000 --- a/tests/test_installed_target/test.py +++ /dev/null @@ -1,3 +0,0 @@ -import test_installed_target -assert test_installed_target.add(1, 2) == 3 -print('test_installed_target imports, runs, and adds: 1 + 2 = 3') diff --git a/tools/pybind11Tools.cmake b/tools/pybind11Tools.cmake index 4922982fa..d629a6fba 100644 --- a/tools/pybind11Tools.cmake +++ b/tools/pybind11Tools.cmake @@ -85,6 +85,11 @@ function(pybind11_add_module target_name) # import time. target_link_libraries(${target_name} PRIVATE "-undefined dynamic_lookup") + + if(${lib_type} STREQUAL "SHARED") + # Suppress CMake >= 3.0 warning for shared libraries + set_target_properties(${target_name} PROPERTIES MACOSX_RPATH ON) + endif() endif() select_cxx_standard()