From 56a6d99546e53af4d677d767478dd268c5d49282 Mon Sep 17 00:00:00 2001 From: Roy Jacobson Date: Mon, 13 Jun 2022 11:02:11 +0300 Subject: [PATCH 1/5] Adds a new target 'pybind11::static' that allows compiling pybind11 as a static library and linking against it. This consists of the following changes: 1. CMake infrastructure to support exporting and installing this target, with an option to disable it. 2. Defining some new macros to support this dual mode compilation. 3. Creating one .cc file that is compiled into the new static library. The rest of the code could be refactored in subsequent PRs. 4. Creating tests that compiling against the new target works. Co-authored-by: Ciro Santilli --- .github/CONTRIBUTING.md | 3 +- CMakeLists.txt | 38 +++++++++++++++ docs/Doxyfile | 1 + docs/compiling.rst | 3 ++ include/pybind11/detail/common-inl.h | 25 ++++++++++ include/pybind11/detail/common.h | 42 ++++++++++------- pyproject.toml | 5 +- setup.py | 1 + src/detail/common.cc | 1 + tests/extra_python_package/test_files.py | 1 + tests/test_cmake_build/CMakeLists.txt | 20 ++++++-- .../installed_static/CMakeLists.txt | 46 +++++++++++++++++++ .../subdirectory_static/CMakeLists.txt | 41 +++++++++++++++++ tools/pybind11Common.cmake | 3 +- tools/pybind11Config.cmake.in | 7 +++ 15 files changed, 214 insertions(+), 23 deletions(-) create mode 100644 include/pybind11/detail/common-inl.h create mode 100644 src/detail/common.cc create mode 100644 tests/test_cmake_build/installed_static/CMakeLists.txt create mode 100644 tests/test_cmake_build/subdirectory_static/CMakeLists.txt diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 00b1fea4cf..3a7b380ba0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -116,7 +116,8 @@ The valid options are: * `-DCMAKE_BUILD_TYPE`: Release, Debug, MinSizeRel, RelWithDebInfo * `-DPYBIND11_FINDPYTHON=ON`: Use CMake 3.12+'s FindPython instead of the classic, deprecated, custom FindPythonLibs -* `-DPYBIND11_NOPYTHON=ON`: Disable all Python searching (disables tests) +* `-DPYBIND11_NOPYTHON=ON`: Disable all Python searching (disables tests and the static library target) +* `-DPYBIND11_BUILD_STATIC_LIB=OFF`: Don't build a static library target. * `-DBUILD_TESTING=ON`: Enable the tests * `-DDOWNLOAD_CATCH=ON`: Download catch to build the C++ tests * `-DDOWNLOAD_EIGEN=ON`: Download Eigen for the NumPy tests diff --git a/CMakeLists.txt b/CMakeLists.txt index ee0975bc1f..8b6f5d8cf2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,8 @@ endif() option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT}) option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT}) option(PYBIND11_NOPYTHON "Disable search for Python" OFF) +option(PYBIND11_BUILD_STATIC_LIB + "Create a static library target for pybind11 that is not header-only (default)" ON) set(PYBIND11_INTERNALS_VERSION "" CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.") @@ -107,6 +109,7 @@ cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" OFF set(PYBIND11_HEADERS include/pybind11/detail/class.h include/pybind11/detail/common.h + include/pybind11/detail/common-inl.h include/pybind11/detail/descr.h include/pybind11/detail/init.h include/pybind11/detail/internals.h @@ -133,6 +136,30 @@ set(PYBIND11_HEADERS include/pybind11/stl_bind.h include/pybind11/stl/filesystem.h) +file(GLOB_RECURSE PYBIND11_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc) +# `embed.cc` is the TU to support embedding a python interpreter. But PyPy does not +# support embedding, so remove it from sources. +if("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy") + # Pypy does not support embedding. + list(REMOVE_ITEM PYBIND11_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/embed.cc) +endif() + +# If we're not configured to be header-only, we need to build a shared library +# and define the pybind11::lib target. +if(PYBIND11_BUILD_STATIC_LIB) + add_library(pybind11_static STATIC ${PYBIND11_SOURCES} ${PYBIND11_HEADERS}) + set_property(TARGET pybind11_static PROPERTY POSITION_INDEPENDENT_CODE ON) + target_compile_definitions(pybind11_static PUBLIC -DPYBIND11_AS_STATIC_LIBRARY=1) + add_library(pybind11::static ALIAS pybind11_static) + target_link_libraries(pybind11_static PRIVATE pybind11::pybind11) + target_link_libraries(pybind11_static PUBLIC pybind11::headers) + install( + TARGETS pybind11_static + EXPORT pybind11::static + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + # Compare with grep and warn if mismatched if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12) file( @@ -259,6 +286,13 @@ if(PYBIND11_INSTALL) endif() install(TARGETS pybind11_headers EXPORT "${PYBIND11_EXPORT_NAME}") + if(PYBIND11_BUILD_STATIC_LIB) + install( + TARGETS pybind11_static + EXPORT "${PYBIND11_EXPORT_NAME}" + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + endif() install( EXPORT "${PYBIND11_EXPORT_NAME}" @@ -304,6 +338,10 @@ else() endif() endif() +if(_pybind11_nopython AND PYBIND11_BUILD_STATIC_LIB) + message(FATAL_ERROR "Cannot build static library in NOPYTHON mode") +endif() + # Better symmetry with find_package(pybind11 CONFIG) mode. if(NOT PYBIND11_MASTER_PROJECT) set(pybind11_FOUND diff --git a/docs/Doxyfile b/docs/Doxyfile index 09138db364..f348dc5201 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -11,6 +11,7 @@ XML_PROGRAMLISTING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES EXPAND_AS_DEFINED = PYBIND11_RUNTIME_EXCEPTION +EXCLUDE_PATTERNS = *-inl.h ALIASES = "rst=\verbatim embed:rst" ALIASES += "endrst=\endverbatim" diff --git a/docs/compiling.rst b/docs/compiling.rst index 2b543be0be..687b1ca691 100644 --- a/docs/compiling.rst +++ b/docs/compiling.rst @@ -482,6 +482,9 @@ available in all modes. The targets provided are: ``pybind11::opt_size`` ``/Os`` for MSVC, ``-Os`` for other compilers. Does nothing for debug builds. + ``pybind11::static`` + Statically link against libpybind11, and configure the pybind11 headers to not provide definitions that they would provide in the default header-only mode. + Two helper functions are also provided: ``pybind11_strip(target)`` diff --git a/include/pybind11/detail/common-inl.h b/include/pybind11/detail/common-inl.h new file mode 100644 index 0000000000..551080fbb5 --- /dev/null +++ b/include/pybind11/detail/common-inl.h @@ -0,0 +1,25 @@ +/* + pybind11/detail/common-inl.h -- Basic macros definitions + + Copyright (c) 2016-2022 Wenzel Jakob + + 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/detail/common.h" + +PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +PYBIND11_NOINLINE_ATTR PYBIND11_INLINE void pybind11_fail(const char *reason) { + assert(!PyErr_Occurred()); + throw std::runtime_error(reason); +} +PYBIND11_NOINLINE_ATTR PYBIND11_INLINE void pybind11_fail(const std::string &reason) { + assert(!PyErr_Occurred()); + throw std::runtime_error(reason); +} + +PYBIND11_INLINE error_scope::error_scope() { PyErr_Fetch(&type, &value, &trace); } +PYBIND11_INLINE error_scope::~error_scope() { PyErr_Restore(type, value, trace); }; + +PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 9e6947daa3..329e1b1812 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -117,17 +117,29 @@ # define PYBIND11_NOINLINE_DISABLED #endif -// The PYBIND11_NOINLINE macro is for function DEFINITIONS. -// In contrast, FORWARD DECLARATIONS should never use this macro: -// https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions +// PYBIND11_INLINE should be used for function definitions in '-inl' files, so they +// can be made non-inline when compiles as a static library. +#if defined(PYBIND11_AS_STATIC_LIBRARY) +# define PYBIND11_INLINE +#else +# define PYBIND11_INLINE inline +#endif + #if defined(PYBIND11_NOINLINE_DISABLED) // Option for maximum portability and experimentation. -# define PYBIND11_NOINLINE inline +# define PYBIND11_NOINLINE_ATTR #elif defined(_MSC_VER) -# define PYBIND11_NOINLINE __declspec(noinline) inline +# define PYBIND11_NOINLINE_ATTR __declspec(noinline) #else -# define PYBIND11_NOINLINE __attribute__((noinline)) inline +# define PYBIND11_NOINLINE_ATTR __attribute__((noinline)) #endif +// The PYBIND11_NOINLINE macro is for function DEFINITIONS. +// In contrast, FORWARD DECLARATIONS should never use this macro: +// https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions +// This macro shouldn't be used in '-inl' files. Instead, use `PYBIND11_NOINLINE_ATTR +// PYBIND11_INLINE`. +#define PYBIND11_NOINLINE PYBIND11_NOINLINE_ATTR inline + #if defined(__MINGW32__) // For unknown reasons all PYBIND11_DEPRECATED member trigger a warning when declared // whether it is used or not @@ -936,14 +948,8 @@ PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybin /// casting error PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally -[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) { - assert(!PyErr_Occurred()); - throw std::runtime_error(reason); -} -[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const std::string &reason) { - assert(!PyErr_Occurred()); - throw std::runtime_error(reason); -} +[[noreturn]] void pybind11_fail(const char *reason); +[[noreturn]] void pybind11_fail(const std::string &reason); template struct format_descriptor {}; @@ -992,10 +998,10 @@ constexpr const char /// RAII wrapper that temporarily clears any Python error state struct error_scope { PyObject *type, *value, *trace; - error_scope() { PyErr_Fetch(&type, &value, &trace); } + error_scope(); error_scope(const error_scope &) = delete; error_scope &operator=(const error_scope &) = delete; - ~error_scope() { PyErr_Restore(type, value, trace); } + ~error_scope(); }; /// Dummy destructor wrapper that can be used to expose classes with a private destructor @@ -1185,3 +1191,7 @@ constexpr inline bool silence_msvc_c4127(bool cond) { return cond; } PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#ifndef PYBIND11_AS_STATIC_LIBRARY +# include "common-inl.h" +#endif diff --git a/pyproject.toml b/pyproject.toml index 3ba1b4b22f..1ce4dc1630 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,10 +4,11 @@ build-backend = "setuptools.build_meta" [tool.check-manifest] ignore = [ - "tests/**", "docs/**", - "tools/**", "include/**", + "srcs/**", + "tests/**", + "tools/**", ".*", "pybind11/include/**", "pybind11/share/**", diff --git a/setup.py b/setup.py index 68573519c1..3159c5c39a 100644 --- a/setup.py +++ b/setup.py @@ -128,6 +128,7 @@ def remove_output(*sources: str) -> Iterator[None]: "-DBUILD_TESTING=OFF", "-DPYBIND11_NOPYTHON=ON", "-Dprefix_for_pc_file=${pcfiledir}/../../", + "-DPYBIND11_BUILD_STATIC_LIB=OFF", ] if "CMAKE_ARGS" in os.environ: fcommand = [ diff --git a/src/detail/common.cc b/src/detail/common.cc new file mode 100644 index 0000000000..feb4297ffa --- /dev/null +++ b/src/detail/common.cc @@ -0,0 +1 @@ +#include "pybind11/detail/common-inl.h" diff --git a/tests/extra_python_package/test_files.py b/tests/extra_python_package/test_files.py index 8e1ddd8508..83f24f1b23 100644 --- a/tests/extra_python_package/test_files.py +++ b/tests/extra_python_package/test_files.py @@ -48,6 +48,7 @@ detail_headers = { "include/pybind11/detail/class.h", "include/pybind11/detail/common.h", + "include/pybind11/detail/common-inl.h", "include/pybind11/detail/descr.h", "include/pybind11/detail/init.h", "include/pybind11/detail/internals.h", diff --git a/tests/test_cmake_build/CMakeLists.txt b/tests/test_cmake_build/CMakeLists.txt index 8bfaa386ae..e0785454df 100644 --- a/tests/test_cmake_build/CMakeLists.txt +++ b/tests/test_cmake_build/CMakeLists.txt @@ -37,7 +37,8 @@ function(pybind11_add_build_test name) "${CMAKE_CURRENT_SOURCE_DIR}/${name}" "${CMAKE_CURRENT_BINARY_DIR}/${name}" --build-config - Release + "$<$:Debug>" + "$<$:Release>" --build-noclean --build-generator ${CMAKE_GENERATOR} @@ -59,6 +60,9 @@ possibly_uninitialized(PYTHON_MODULE_EXTENSION Python_INTERPRETER_ID) pybind11_add_build_test(subdirectory_function) pybind11_add_build_test(subdirectory_target) +if(PYBIND11_BUILD_STATIC_LIB) + pybind11_add_build_test(subdirectory_static) +endif() if("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy") message(STATUS "Skipping embed test on PyPy") else() @@ -67,11 +71,21 @@ endif() if(PYBIND11_INSTALL) add_custom_target( - mock_install ${CMAKE_COMMAND} "-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install" -P - "${pybind11_BINARY_DIR}/cmake_install.cmake") + mock_install + ${CMAKE_COMMAND} + "-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install" + "-DBUILD_TYPE=" + "$<$:Debug>" + "$<$:Release>" + -P + "${pybind11_BINARY_DIR}/cmake_install.cmake") pybind11_add_build_test(installed_function INSTALL) pybind11_add_build_test(installed_target INSTALL) + if(PYBIND11_BUILD_STATIC_LIB) + pybind11_add_build_test(installed_static INSTALL) + add_dependencies(mock_install pybind11::static) + endif() if(NOT ("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy" )) pybind11_add_build_test(installed_embed INSTALL) diff --git a/tests/test_cmake_build/installed_static/CMakeLists.txt b/tests/test_cmake_build/installed_static/CMakeLists.txt new file mode 100644 index 0000000000..5f2fada610 --- /dev/null +++ b/tests/test_cmake_build/installed_static/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.4) + +# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with +# some versions of VS that have a patched CMake 3.11. This forces us to emulate +# the behavior using the following workaround: +if(${CMAKE_VERSION} VERSION_LESS 3.18) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +else() + cmake_policy(VERSION 3.18) +endif() + +project(test_installed_static CXX) + +find_package(pybind11 CONFIG REQUIRED) +message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") + +add_library(test_installed_static MODULE ../main.cpp) + +target_link_libraries(test_installed_static PRIVATE pybind11::module pybind11::static) +set_target_properties(test_installed_static PROPERTIES OUTPUT_NAME test_cmake_build) + +# Make sure result is, for example, test_installed_static.so, not libtest_installed_static.dylib +pybind11_extension(test_installed_static) + +# Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::module). +# This may be needed to resolve header conflicts, e.g. between Python release and debug headers. +set_target_properties(test_installed_static PROPERTIES NO_SYSTEM_FROM_IMPORTED ON) + +if(DEFINED Python_EXECUTABLE) + set(_Python_EXECUTABLE "${Python_EXECUTABLE}") +elseif(DEFINED PYTHON_EXECUTABLE) + set(_Python_EXECUTABLE "${PYTHON_EXECUTABLE}") +else() + message(FATAL_ERROR "No Python executable defined (should not be possible at this stage)") +endif() + +add_custom_target( + check_installed_static + ${CMAKE_COMMAND} + -E + env + PYTHONPATH=$ + ${_Python_EXECUTABLE} + ${PROJECT_SOURCE_DIR}/../test.py + ${PROJECT_NAME} + DEPENDS test_installed_static) diff --git a/tests/test_cmake_build/subdirectory_static/CMakeLists.txt b/tests/test_cmake_build/subdirectory_static/CMakeLists.txt new file mode 100644 index 0000000000..6082a6c4ff --- /dev/null +++ b/tests/test_cmake_build/subdirectory_static/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.4) + +# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with +# some versions of VS that have a patched CMake 3.11. This forces us to emulate +# the behavior using the following workaround: +if(${CMAKE_VERSION} VERSION_LESS 3.18) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +else() + cmake_policy(VERSION 3.18) +endif() + +project(test_subdirectory_static CXX) + +add_subdirectory("${pybind11_SOURCE_DIR}" pybind11) + +add_library(test_subdirectory_static MODULE ../main.cpp) +set_target_properties(test_subdirectory_static PROPERTIES OUTPUT_NAME test_cmake_build) + +target_link_libraries(test_subdirectory_static PRIVATE pybind11::module pybind11::static) + +# Make sure result is, for example, test_installed_static.so, not libtest_installed_static.dylib +pybind11_extension(test_subdirectory_static) + +if(DEFINED Python_EXECUTABLE) + set(_Python_EXECUTABLE "${Python_EXECUTABLE}") +elseif(DEFINED PYTHON_EXECUTABLE) + set(_Python_EXECUTABLE "${PYTHON_EXECUTABLE}") +else() + message(FATAL_ERROR "No Python executable defined (should not be possible at this stage)") +endif() + +add_custom_target( + check_subdirectory_static + ${CMAKE_COMMAND} + -E + env + PYTHONPATH=$ + ${_Python_EXECUTABLE} + ${PROJECT_SOURCE_DIR}/../test.py + ${PROJECT_NAME} + DEPENDS test_subdirectory_static) diff --git a/tools/pybind11Common.cmake b/tools/pybind11Common.cmake index e1fb601acc..3ab831e4e6 100644 --- a/tools/pybind11Common.cmake +++ b/tools/pybind11Common.cmake @@ -9,7 +9,8 @@ Adds the following targets:: pybind11::thin_lto - Link time optimizations (manual selection) pybind11::python_link_helper - Adds link to Python libraries pybind11::windows_extras - MSVC bigobj and mp for building multithreaded - pybind11::opt_size - avoid optimizations that increase code size + pybind11::opt_size - Avoid optimizations that increase code size + pybind11::static - Use pybind11 as a static library. Adds the following functions:: diff --git a/tools/pybind11Config.cmake.in b/tools/pybind11Config.cmake.in index 9383e8c671..120bb27a04 100644 --- a/tools/pybind11Config.cmake.in +++ b/tools/pybind11Config.cmake.in @@ -49,6 +49,8 @@ complex applications, and they are available in all modes: Just the pybind11 headers and minimum compile requirements. ``pybind11::pybind11`` Python headers too. +``pybind11::static`` + A static library to link against instead of the default header-only. ``pybind11::python_link_helper`` Just the "linking" part of ``pybind11:module``, for CMake < 3.15. ``pybind11::thin_lto`` @@ -220,6 +222,11 @@ include("${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake") add_library(pybind11::headers IMPORTED INTERFACE) set_target_properties(pybind11::headers PROPERTIES INTERFACE_LINK_LIBRARIES pybind11::pybind11_headers) +if(@PYBIND11_BUILD_STATIC_LIB@) + add_library(pybind11::static IMPORTED INTERFACE) + set_target_properties(pybind11::static PROPERTIES INTERFACE_LINK_LIBRARIES + pybind11::pybind11_static) +endif() include("${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake") From 9af5cb024fe96c62f0708fe357b43f318e710f34 Mon Sep 17 00:00:00 2001 From: Roy Jacobson Date: Sun, 4 Sep 2022 21:46:47 +0300 Subject: [PATCH 2/5] * Remove static library CMake installation because I couldn't get it to work. * Fix typo in pyproject.toml and disable static library in Clang-Tidy CI pass. --- .github/workflows/format.yml | 3 ++ CMakeLists.txt | 12 ----- docs/compiling.rst | 1 + pyproject.toml | 2 +- tests/test_cmake_build/CMakeLists.txt | 7 --- .../installed_static/CMakeLists.txt | 46 ------------------- tools/pybind11Config.cmake.in | 7 --- 7 files changed, 5 insertions(+), 73 deletions(-) delete mode 100644 tests/test_cmake_build/installed_static/CMakeLists.txt diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 31d893c479..3b0280c6d2 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -50,6 +50,9 @@ jobs: -DDOWNLOAD_EIGEN=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_STANDARD=17 + # Disabling the static library mode so Clang-Tidy won't complain about non-inline + # definitions in header ('*-inl.h') files. + -DPYBIND11_BUILD_STATIC_LIB=OFF - name: Build run: cmake --build build -j 2 -- --keep-going diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b6f5d8cf2..f1638e82fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,11 +153,6 @@ if(PYBIND11_BUILD_STATIC_LIB) add_library(pybind11::static ALIAS pybind11_static) target_link_libraries(pybind11_static PRIVATE pybind11::pybind11) target_link_libraries(pybind11_static PUBLIC pybind11::headers) - install( - TARGETS pybind11_static - EXPORT pybind11::static - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() # Compare with grep and warn if mismatched @@ -286,13 +281,6 @@ if(PYBIND11_INSTALL) endif() install(TARGETS pybind11_headers EXPORT "${PYBIND11_EXPORT_NAME}") - if(PYBIND11_BUILD_STATIC_LIB) - install( - TARGETS pybind11_static - EXPORT "${PYBIND11_EXPORT_NAME}" - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) - endif() install( EXPORT "${PYBIND11_EXPORT_NAME}" diff --git a/docs/compiling.rst b/docs/compiling.rst index 687b1ca691..aa431a904e 100644 --- a/docs/compiling.rst +++ b/docs/compiling.rst @@ -484,6 +484,7 @@ available in all modes. The targets provided are: ``pybind11::static`` Statically link against libpybind11, and configure the pybind11 headers to not provide definitions that they would provide in the default header-only mode. + Currently this configuration is only available in subdirectory mode. Two helper functions are also provided: diff --git a/pyproject.toml b/pyproject.toml index 1ce4dc1630..88f50e42b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" ignore = [ "docs/**", "include/**", - "srcs/**", + "src/**", "tests/**", "tools/**", ".*", diff --git a/tests/test_cmake_build/CMakeLists.txt b/tests/test_cmake_build/CMakeLists.txt index e0785454df..3e8cba9ce2 100644 --- a/tests/test_cmake_build/CMakeLists.txt +++ b/tests/test_cmake_build/CMakeLists.txt @@ -74,18 +74,11 @@ if(PYBIND11_INSTALL) mock_install ${CMAKE_COMMAND} "-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install" - "-DBUILD_TYPE=" - "$<$:Debug>" - "$<$:Release>" -P "${pybind11_BINARY_DIR}/cmake_install.cmake") pybind11_add_build_test(installed_function INSTALL) pybind11_add_build_test(installed_target INSTALL) - if(PYBIND11_BUILD_STATIC_LIB) - pybind11_add_build_test(installed_static INSTALL) - add_dependencies(mock_install pybind11::static) - endif() if(NOT ("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy" )) pybind11_add_build_test(installed_embed INSTALL) diff --git a/tests/test_cmake_build/installed_static/CMakeLists.txt b/tests/test_cmake_build/installed_static/CMakeLists.txt deleted file mode 100644 index 5f2fada610..0000000000 --- a/tests/test_cmake_build/installed_static/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -cmake_minimum_required(VERSION 3.4) - -# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with -# some versions of VS that have a patched CMake 3.11. This forces us to emulate -# the behavior using the following workaround: -if(${CMAKE_VERSION} VERSION_LESS 3.18) - cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) -else() - cmake_policy(VERSION 3.18) -endif() - -project(test_installed_static CXX) - -find_package(pybind11 CONFIG REQUIRED) -message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") - -add_library(test_installed_static MODULE ../main.cpp) - -target_link_libraries(test_installed_static PRIVATE pybind11::module pybind11::static) -set_target_properties(test_installed_static PROPERTIES OUTPUT_NAME test_cmake_build) - -# Make sure result is, for example, test_installed_static.so, not libtest_installed_static.dylib -pybind11_extension(test_installed_static) - -# Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::module). -# This may be needed to resolve header conflicts, e.g. between Python release and debug headers. -set_target_properties(test_installed_static PROPERTIES NO_SYSTEM_FROM_IMPORTED ON) - -if(DEFINED Python_EXECUTABLE) - set(_Python_EXECUTABLE "${Python_EXECUTABLE}") -elseif(DEFINED PYTHON_EXECUTABLE) - set(_Python_EXECUTABLE "${PYTHON_EXECUTABLE}") -else() - message(FATAL_ERROR "No Python executable defined (should not be possible at this stage)") -endif() - -add_custom_target( - check_installed_static - ${CMAKE_COMMAND} - -E - env - PYTHONPATH=$ - ${_Python_EXECUTABLE} - ${PROJECT_SOURCE_DIR}/../test.py - ${PROJECT_NAME} - DEPENDS test_installed_static) diff --git a/tools/pybind11Config.cmake.in b/tools/pybind11Config.cmake.in index 120bb27a04..9383e8c671 100644 --- a/tools/pybind11Config.cmake.in +++ b/tools/pybind11Config.cmake.in @@ -49,8 +49,6 @@ complex applications, and they are available in all modes: Just the pybind11 headers and minimum compile requirements. ``pybind11::pybind11`` Python headers too. -``pybind11::static`` - A static library to link against instead of the default header-only. ``pybind11::python_link_helper`` Just the "linking" part of ``pybind11:module``, for CMake < 3.15. ``pybind11::thin_lto`` @@ -222,11 +220,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake") add_library(pybind11::headers IMPORTED INTERFACE) set_target_properties(pybind11::headers PROPERTIES INTERFACE_LINK_LIBRARIES pybind11::pybind11_headers) -if(@PYBIND11_BUILD_STATIC_LIB@) - add_library(pybind11::static IMPORTED INTERFACE) - set_target_properties(pybind11::static PROPERTIES INTERFACE_LINK_LIBRARIES - pybind11::pybind11_static) -endif() include("${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake") From bc78754ca0db02730bad2ec07ec9db2213e10ad8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 4 Sep 2022 18:47:32 +0000 Subject: [PATCH 3/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_cmake_build/CMakeLists.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/test_cmake_build/CMakeLists.txt b/tests/test_cmake_build/CMakeLists.txt index 3e8cba9ce2..164cefaecf 100644 --- a/tests/test_cmake_build/CMakeLists.txt +++ b/tests/test_cmake_build/CMakeLists.txt @@ -71,11 +71,8 @@ endif() if(PYBIND11_INSTALL) add_custom_target( - mock_install - ${CMAKE_COMMAND} - "-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install" - -P - "${pybind11_BINARY_DIR}/cmake_install.cmake") + mock_install ${CMAKE_COMMAND} "-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install" -P + "${pybind11_BINARY_DIR}/cmake_install.cmake") pybind11_add_build_test(installed_function INSTALL) pybind11_add_build_test(installed_target INSTALL) From ff8f8fd9660a0d626a91315908dd5bd8a27bc9ec Mon Sep 17 00:00:00 2001 From: Roy Jacobson Date: Sun, 4 Sep 2022 22:22:24 +0300 Subject: [PATCH 4/5] Move the comment outside. --- .github/workflows/format.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 3b0280c6d2..a81464a722 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -43,6 +43,8 @@ jobs: - name: Install requirements run: apt-get update && apt-get install -y python3-dev python3-pytest + # The static library mode is disabled so Clang-Tidy does't complain about + # non-inline definitions in header files ('*-inl.h'). - name: Configure run: > cmake -S . -B build @@ -50,8 +52,6 @@ jobs: -DDOWNLOAD_EIGEN=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_STANDARD=17 - # Disabling the static library mode so Clang-Tidy won't complain about non-inline - # definitions in header ('*-inl.h') files. -DPYBIND11_BUILD_STATIC_LIB=OFF - name: Build From c64b9e01c538ce1ca1fa1b153aa1aeacaf9a036b Mon Sep 17 00:00:00 2001 From: Roy Jacobson Date: Mon, 5 Sep 2022 00:17:01 +0300 Subject: [PATCH 5/5] Fix typo --- .github/workflows/format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index a81464a722..d8d9766ef9 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -43,7 +43,7 @@ jobs: - name: Install requirements run: apt-get update && apt-get install -y python3-dev python3-pytest - # The static library mode is disabled so Clang-Tidy does't complain about + # The static library mode is disabled so Clang-Tidy doesn't complain about # non-inline definitions in header files ('*-inl.h'). - name: Configure run: >