feat: new FindPython support (#2370)

* feat: FindPython support

* refactor: rename to PYBIND11_FINDPYTHON

* docs: Caps fixes

* feat: NOPYTHON mode

* test: check simple call

* docs: add changelog/upgrade guide

* feat: Support Python3 and Python2

* refactor: Use targets in tests

* fix: support CMake 3.4+

* feat: classic search also finds virtual environments

* docs: some updates from @wjakob's review

* fix: wrong name for QUIET mode variable, reported by @skoslowski

* refactor: cleaner output messaging

* fix: support debug Python's in FindPython mode too

* fixup! refactor: cleaner output messaging

* fix: missing pybind11_FOUND and pybind11_INCLUDE_DIR restored to subdir mode

* fix: nicer reporting of Python / PyPy

* fix: out-of-order variable fix

* docs: minor last-minute cleanup
diff --git a/tools/pybind11Config.cmake.in b/tools/pybind11Config.cmake.in
index c86e0de..4f0500a 100644
--- a/tools/pybind11Config.cmake.in
+++ b/tools/pybind11Config.cmake.in
@@ -8,6 +8,7 @@
 
   pybind11_FOUND - true if pybind11 and all required components found on the system
   pybind11_VERSION - pybind11 version in format Major.Minor.Release
+  pybind11_VERSION_TYPE - pybind11 version type (dev, release)
   pybind11_INCLUDE_DIRS - Directories where pybind11 and python headers are located.
   pybind11_INCLUDE_DIR - Directory where pybind11 headers are located.
   pybind11_DEFINITIONS - Definitions necessary to use pybind11, namely USING_pybind11.
@@ -28,21 +29,61 @@
 
 Python headers, libraries (as needed by platform), and the C++ standard
 are attached to the target.
+
+Advanced targets are also supplied - these are primary for users building
+complex applications, and they are available in all modes::
+
+  pybind11::headers - Just the pybind11 headers and minimum compile requirements
+  pybind11::pybind11 - Python headers too
+  pybind11::python_link_helper - Just the "linking" part of pybind11:module, for CMake < 3.15
+  pybind11::python2_no_register - Quiets the warning/error when mixing C++14+ and Python 2, also included in pybind11::module
+  pybind11::thin_lto - An alternative to INTERPROCEDURAL_OPTIMIZATION
+  pybind11::lto - An alternative to INTERPROCEDURAL_OPTIMIZATION (also avoids thin LTO on clang)
+  pybind11::windows_extras - Adds bigobj and mp for MSVC
+
+Modes::
+
+There are two modes provided; classic, which is built on the old Python
+discovery packages in CMake, or the new FindPython mode, which uses FindPython
+from 3.12+ forward (3.15+ _highly_ recommended).
+
+New FindPython mode::
+
+To activate this mode, either call ``find_package(Python COMPONENTS Interpreter Development)``
+before finding this package, or set the ``PYBIND11_FINDPYTHON`` variable to ON. In this mode,
+you can either use the basic targets, or use the FindPython tools::
+
+  find_package(Python COMPONENTS Interpreter Development)
+  find_package(pybind11 CONFIG)
+
+  # pybind11 method:
+  pybind11_add_module(MyModule1 src1.cpp)
+
+  # Python method:
+  Python_add_library(MyModule2 src2.cpp)
+  target_link_libraries(MyModule2 pybind11::headers)
+  set_target_properties(MyModule2 PROPERTIES
+                                  INTERPROCEDURAL_OPTIMIZATION ON
+                                  CXX__VISIBILITY_PRESET ON
+                                  VISIBLITY_INLINES_HIDDEN ON)
+
+If you build targets yourself, you may be interested in stripping the output
+for reduced size; this is the one other feature that the helper function gives you.
+
 Classic mode::
 
 Set PythonLibsNew variables to influence python detection and
 CMAKE_CXX_STANDARD to influence standard setting. ::
 
   find_package(pybind11 CONFIG REQUIRED)
-  message(STATUS "Found pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}: ${pybind11_INCLUDE_DIRS}")
 
   # Create an extension module
   add_library(mylib MODULE main.cpp)
-  target_link_libraries(mylib pybind11::module)
+  target_link_libraries(mylib PUBLIC pybind11::module)
 
   # Or embed the Python interpreter into an executable
   add_executable(myexe main.cpp)
-  target_link_libraries(myexe pybind11::embed)
+  target_link_libraries(myexe PUBLIC pybind11::embed)
 
 Suggested usage::
 
@@ -59,8 +100,17 @@
   PATH - environment variable, set to bin directory of this package
   CMAKE_DISABLE_FIND_PACKAGE_pybind11 - CMake variable, disables
     find_package(pybind11) when not REQUIRED, perhaps to force internal build
-#]=============================================================================]
 
+Helper functions::
+
+  pybind11_add_module(...) - Add a library and setup all helpers
+  pybind11_strip(target) - Strip a target after building it (linux/macOS)
+  pybind11_extension(target) - Injects the Python extension name
+
+See ``pybind11Tools.cmake`` or ``pybind11NewTools.cmake`` for details on
+``pybind11_add_module``.
+
+#]=============================================================================]
 @PACKAGE_INIT@
 
 # Location of pybind11/pybind11.h
@@ -72,50 +122,19 @@
 
 check_required_components(pybind11)
 
-include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
+if(TARGET pybind11::python_link_helper)
+  # This has already been setup elsewhere, such as with a previous call or
+  # add_subdirectory
+  return()
+endif()
 
-#-----------------------------------------------------------------------------
-# Don't include targets if this file is being picked up by another
-# project which has already built this as a subproject
-#-----------------------------------------------------------------------------
-if(NOT TARGET pybind11::pybind11)
-  include("${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake")
 
-  list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
-  find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED)
-  list(REMOVE_AT CMAKE_MODULE_PATH -1)
+include("${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake")
 
-  set_property(
-    TARGET pybind11::pybind11
-    APPEND
-    PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
-  set_property(
-    TARGET pybind11::pybind11
-    APPEND
-    PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
-
-  set_property(
-    TARGET pybind11::embed
-    APPEND
-    PROPERTY INTERFACE_LINK_LIBRARIES ${PYTHON_LIBRARIES})
-  set_property(
-    TARGET pybind11::module
-    APPEND
-    PROPERTY
-      INTERFACE_LINK_LIBRARIES
-      "$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>"
+if(NOT pybind11_FIND_QUIETLY)
+  message(
+    STATUS
+      "Found pybind11: ${pybind11_INCLUDE_DIR} (found version \"${pybind11_VERSION}\" ${pybind11_VERSION_TYPE})"
   )
-
-  get_property(
-    _iid
-    TARGET pybind11::pybind11
-    PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
-  get_property(
-    _ill
-    TARGET pybind11::module
-    PROPERTY INTERFACE_LINK_LIBRARIES)
-  set(pybind11_INCLUDE_DIRS ${_iid})
-  set(pybind11_LIBRARIES ${_ico} ${_ill})
-
-  include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
 endif()