# CMakeLists.txt -- Build system for the pybind11 modules
#
# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
#
# All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# Propagate this policy (FindPythonInterp removal) so it can be detected later
if(NOT CMAKE_VERSION VERSION_LESS "3.27")
  cmake_policy(GET CMP0148 _pybind11_cmp0148)
endif()

cmake_minimum_required(VERSION 3.15...4.0)

if(_pybind11_cmp0148)
  cmake_policy(SET CMP0148 ${_pybind11_cmp0148})
  unset(_pybind11_cmp0148)
endif()

# Avoid infinite recursion if tests include this as a subdirectory
include_guard(GLOBAL)

# Extract project version from source
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
     pybind11_version_defines REGEX "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) ")

foreach(ver ${pybind11_version_defines})
  if(ver MATCHES [[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])
    set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
  endif()
endforeach()

if(PYBIND11_VERSION_PATCH MATCHES [[\.([a-zA-Z0-9]+)$]])
  set(pybind11_VERSION_TYPE "${CMAKE_MATCH_1}")
endif()
string(REGEX MATCH "^[0-9]+" PYBIND11_VERSION_PATCH "${PYBIND11_VERSION_PATCH}")

project(
  pybind11
  LANGUAGES CXX
  VERSION "${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}")

# Standard includes
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)

if(NOT pybind11_FIND_QUIETLY)
  message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
endif()

# Check if pybind11 is being used directly or via add_subdirectory
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
  ### Warn if not an out-of-source builds
  if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
    set(lines
        "You are building in-place. If that is not what you intended to "
        "do, you can clean the source directory with:\n"
        "rm -r CMakeCache.txt CMakeFiles/ cmake_uninstall.cmake pybind11Config.cmake "
        "pybind11ConfigVersion.cmake tests/CMakeFiles/\n")
    message(AUTHOR_WARNING ${lines})
  endif()

  set(PYBIND11_MASTER_PROJECT ON)

  message(STATUS "CMake ${CMAKE_VERSION}")

  if(DEFINED SKBUILD AND DEFINED ENV{PYBIND11_GLOBAL_SDIST})
    message(
      FATAL_ERROR
        "PYBIND11_GLOBAL_SDIST is not supported, use nox -s build_global or a pybind11-global SDist instead."
    )
  endif()

  if(CMAKE_CXX_STANDARD)
    set(CMAKE_CXX_EXTENSIONS OFF)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
  endif()

  set(pybind11_system "")

  set_property(GLOBAL PROPERTY USE_FOLDERS ON)
  if(CMAKE_VERSION VERSION_LESS "3.18")
    set(_pybind11_findpython_default OFF)
  else()
    set(_pybind11_findpython_default ON)
  endif()
else()
  set(PYBIND11_MASTER_PROJECT OFF)
  set(pybind11_system SYSTEM)
  set(_pybind11_findpython_default COMPAT)
endif()

# Options
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_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
       "To enforce that a handle_type_name<> specialization exists" OFF)
option(PYBIND11_SIMPLE_GIL_MANAGEMENT
       "Use simpler GIL management logic that does not support disassociation" OFF)
set(PYBIND11_INTERNALS_VERSION
    ""
    CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
option(PYBIND11_USE_CROSSCOMPILING "Respect CMAKE_CROSSCOMPILING" OFF)

if(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
  add_compile_definitions(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
endif()
if(PYBIND11_SIMPLE_GIL_MANAGEMENT)
  add_compile_definitions(PYBIND11_SIMPLE_GIL_MANAGEMENT)
endif()

cmake_dependent_option(
  USE_PYTHON_INCLUDE_DIR
  "Install pybind11 headers in Python include directory instead of default installation prefix"
  OFF "PYBIND11_INSTALL" OFF)

set(PYBIND11_FINDPYTHON
    ${_pybind11_findpython_default}
    CACHE STRING "Force new FindPython - NEW, OLD, COMPAT")

if(PYBIND11_MASTER_PROJECT)

  # Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
  # (makes transition easier while we support both modes).
  if(PYBIND11_FINDPYTHON
     AND DEFINED PYTHON_EXECUTABLE
     AND NOT DEFINED Python_EXECUTABLE)
    set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
  endif()

  # This is a shortcut that is primarily for the venv cmake preset,
  # but can be used to quickly setup tests manually, too
  set(PYBIND11_CREATE_WITH_UV
      ""
      CACHE STRING "Create a virtualenv if it doesn't exist")

  if(NOT PYBIND11_CREATE_WITH_UV STREQUAL "")
    set(Python_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/.venv")
    if(EXISTS "${Python_ROOT_DIR}")
      if(EXISTS "${CMAKE_BINARY_DIR}/CMakeCache.txt")
        message(STATUS "Using existing venv at ${Python_ROOT_DIR}, remove or --fresh to recreate")
      else()
        # --fresh used to remove the cache
        file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/.venv")
      endif()
    endif()
    if(NOT EXISTS "${Python_ROOT_DIR}")
      find_program(UV uv REQUIRED)
      # CMake 3.19+ would be able to use COMMAND_ERROR_IS_FATAL
      message(
        STATUS "Creating venv with ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} '${Python_ROOT_DIR}'")
      execute_process(COMMAND ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} "${Python_ROOT_DIR}"
                      RESULT_VARIABLE _venv_result)
      if(_venv_result AND NOT _venv_result EQUAL 0)
        message(FATAL_ERROR "uv venv failed with '${_venv_result}'")
      endif()
      message(
        STATUS
          "Installing deps with ${UV} pip install -p '${Python_ROOT_DIR}' -r tests/requirements.txt"
      )
      execute_process(
        COMMAND ${UV} pip install -p "${Python_ROOT_DIR}" -r
                "${CMAKE_CURRENT_SOURCE_DIR}/tests/requirements.txt" RESULT_VARIABLE _pip_result)
      if(_pip_result AND NOT _pip_result EQUAL 0)
        message(FATAL_ERROR "uv pip install failed with '${_pip_result}'")
      endif()
    endif()
  else()
    if(NOT DEFINED Python3_EXECUTABLE
       AND NOT DEFINED Python_EXECUTABLE
       AND NOT DEFINED Python_ROOT_DIR
       AND NOT DEFINED ENV{VIRTUALENV}
       AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
      message(STATUS "Autodetecting Python in virtual environment")
      set(Python_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
    endif()
  endif()
endif()

set(PYBIND11_HEADERS
    include/pybind11/detail/class.h
    include/pybind11/detail/common.h
    include/pybind11/detail/cpp_conduit.h
    include/pybind11/detail/descr.h
    include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h
    include/pybind11/detail/exception_translation.h
    include/pybind11/detail/function_record_pyobject.h
    include/pybind11/detail/init.h
    include/pybind11/detail/internals.h
    include/pybind11/detail/native_enum_data.h
    include/pybind11/detail/pybind11_namespace_macros.h
    include/pybind11/detail/struct_smart_holder.h
    include/pybind11/detail/type_caster_base.h
    include/pybind11/detail/typeid.h
    include/pybind11/detail/using_smart_holder.h
    include/pybind11/detail/value_and_holder.h
    include/pybind11/attr.h
    include/pybind11/buffer_info.h
    include/pybind11/cast.h
    include/pybind11/chrono.h
    include/pybind11/common.h
    include/pybind11/complex.h
    include/pybind11/conduit/pybind11_conduit_v1.h
    include/pybind11/conduit/pybind11_platform_abi_id.h
    include/pybind11/conduit/wrap_include_python_h.h
    include/pybind11/critical_section.h
    include/pybind11/options.h
    include/pybind11/eigen.h
    include/pybind11/eigen/common.h
    include/pybind11/eigen/matrix.h
    include/pybind11/eigen/tensor.h
    include/pybind11/embed.h
    include/pybind11/eval.h
    include/pybind11/gil.h
    include/pybind11/gil_safe_call_once.h
    include/pybind11/gil_simple.h
    include/pybind11/iostream.h
    include/pybind11/functional.h
    include/pybind11/native_enum.h
    include/pybind11/numpy.h
    include/pybind11/operators.h
    include/pybind11/pybind11.h
    include/pybind11/pytypes.h
    include/pybind11/subinterpreter.h
    include/pybind11/stl.h
    include/pybind11/stl_bind.h
    include/pybind11/stl/filesystem.h
    include/pybind11/trampoline_self_life_support.h
    include/pybind11/type_caster_pyobject_ptr.h
    include/pybind11/typing.h
    include/pybind11/warnings.h)

# Compare with grep and warn if mismatched
if(PYBIND11_MASTER_PROJECT)
  file(
    GLOB_RECURSE _pybind11_header_check
    LIST_DIRECTORIES false
    RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
    CONFIGURE_DEPENDS "include/pybind11/*.h")
  set(_pybind11_here_only ${PYBIND11_HEADERS})
  set(_pybind11_disk_only ${_pybind11_header_check})
  list(REMOVE_ITEM _pybind11_here_only ${_pybind11_header_check})
  list(REMOVE_ITEM _pybind11_disk_only ${PYBIND11_HEADERS})
  if(_pybind11_here_only)
    message(AUTHOR_WARNING "PYBIND11_HEADERS has extra files:" ${_pybind11_here_only})
  endif()
  if(_pybind11_disk_only)
    message(AUTHOR_WARNING "PYBIND11_HEADERS is missing files:" ${_pybind11_disk_only})
  endif()
endif()

list(TRANSFORM PYBIND11_HEADERS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")

# Cache variable so this can be used in parent projects
set(pybind11_INCLUDE_DIR
    "${CMAKE_CURRENT_LIST_DIR}/include"
    CACHE INTERNAL "Directory where pybind11 headers are located")

# Backward compatible variable for add_subdirectory mode
if(NOT PYBIND11_MASTER_PROJECT)
  set(PYBIND11_INCLUDE_DIR
      "${pybind11_INCLUDE_DIR}"
      CACHE INTERNAL "")
endif()

# Note: when creating targets, you cannot use if statements at configure time -
# you need generator expressions, because those will be placed in the target file.
# You can also place ifs *in* the Config.in, but not here.

# This section builds targets, but does *not* touch Python
# Non-IMPORT targets cannot be defined twice
if(NOT TARGET pybind11_headers)
  # Build the headers-only target (no Python included):
  # (long name used here to keep this from clashing in subdirectory mode)
  add_library(pybind11_headers INTERFACE)
  add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target
  add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember

  target_include_directories(
    pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
                                                  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

  target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
                                                     cxx_right_angle_brackets)
  if(NOT "${PYBIND11_INTERNALS_VERSION}" STREQUAL "")
    target_compile_definitions(
      pybind11_headers INTERFACE "PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}")
  endif()
else()
  # It is invalid to install a target twice, too.
  set(PYBIND11_INSTALL OFF)
endif()

include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
# https://github.com/jtojnar/cmake-snips/#concatenating-paths-when-building-pkg-config-files
# TODO: cmake 3.20 adds the cmake_path() function, which obsoletes this snippet
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/JoinPaths.cmake")

# Relative directory setting
if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
  file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})
elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
  file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
endif()

if(PYBIND11_INSTALL)
  if(DEFINED SKBUILD_PROJECT_NAME AND SKBUILD_PROJECT_NAME STREQUAL "pybind11_global")
    install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION "${SKBUILD_HEADERS_DIR}")
  endif()
  install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
  set(PYBIND11_CMAKECONFIG_INSTALL_DIR
      "${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
      CACHE STRING "install path for pybind11Config.cmake")

  if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
    set(pybind11_INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
  else()
    set(pybind11_INCLUDEDIR "\$\{PACKAGE_PREFIX_DIR\}/${CMAKE_INSTALL_INCLUDEDIR}")
  endif()

  configure_package_config_file(
    tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
    INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})

  # CMake natively supports header-only libraries
  write_basic_package_version_file(
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)

  install(
    FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
          ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
          tools/FindPythonLibsNew.cmake
          tools/pybind11Common.cmake
          tools/pybind11Tools.cmake
          tools/pybind11NewTools.cmake
          tools/pybind11GuessPythonExtSuffix.cmake
    DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})

  if(NOT PYBIND11_EXPORT_NAME)
    set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets")
  endif()

  install(TARGETS pybind11_headers EXPORT "${PYBIND11_EXPORT_NAME}")

  install(
    EXPORT "${PYBIND11_EXPORT_NAME}"
    NAMESPACE "pybind11::"
    DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})

  # pkg-config support
  if(NOT prefix_for_pc_file)
    if(IS_ABSOLUTE "${CMAKE_INSTALL_DATAROOTDIR}")
      set(prefix_for_pc_file "${CMAKE_INSTALL_PREFIX}")
    else()
      set(pc_datarootdir "${CMAKE_INSTALL_DATAROOTDIR}")
      if(CMAKE_VERSION VERSION_LESS 3.20)
        set(prefix_for_pc_file "\${pcfiledir}/..")
        while(pc_datarootdir)
          get_filename_component(pc_datarootdir "${pc_datarootdir}" DIRECTORY)
          string(APPEND prefix_for_pc_file "/..")
        endwhile()
      else()
        cmake_path(RELATIVE_PATH CMAKE_INSTALL_PREFIX BASE_DIRECTORY CMAKE_INSTALL_DATAROOTDIR
                   OUTPUT_VARIABLE prefix_for_pc_file)
      endif()
    endif()
  endif()
  join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
  configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11.pc.in"
                 "${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc" @ONLY)
  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc"
          DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")

  # When building a wheel, include __init__.py's for modules
  # (see https://github.com/pybind/pybind11/pull/5552)
  if(DEFINED SKBUILD_PROJECT_NAME AND SKBUILD_PROJECT_NAME STREQUAL "pybind11")
    file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/empty")
    file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py")
    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py"
            DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/")
    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py"
            DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
  endif()

  # Uninstall target
  if(PYBIND11_MASTER_PROJECT)
    configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"
                   "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)

    add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P
                                        ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
  endif()
endif()

# BUILD_TESTING takes priority, but only if this is the master project
if(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)
  if(BUILD_TESTING)
    if(_pybind11_nopython)
      message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
    else()
      add_subdirectory(tests)
    endif()
  endif()
else()
  if(PYBIND11_TEST)
    if(_pybind11_nopython)
      message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
    else()
      add_subdirectory(tests)
    endif()
  endif()
endif()

# Better symmetry with find_package(pybind11 CONFIG) mode.
if(NOT PYBIND11_MASTER_PROJECT)
  set(pybind11_FOUND
      TRUE
      CACHE INTERNAL "True if pybind11 and all required components found on the system")
endif()
