xref: /llvm-project/mlir/cmake/modules/MLIRDetectPythonEnv.cmake (revision 5cd427477218d8bdb659c6c53a7758f741c3990a)
1f4f8a67aSStella Laurenzo# Macros and functions related to detecting details of the Python environment.
2f4f8a67aSStella Laurenzo
33d92722fSStella Laurenzo# Finds and configures python packages needed to build MLIR Python bindings.
43d92722fSStella Laurenzomacro(mlir_configure_python_dev_packages)
565339e4dSStella Laurenzo  if(NOT MLIR_DISABLE_CONFIGURE_PYTHON_DEV_PACKAGES)
6d75ac581Srkayaith    if(MLIR_DETECT_PYTHON_ENV_PRIME_SEARCH)
7d75ac581Srkayaith      # Prime the search for python to see if there is a full development
8d75ac581Srkayaith      # package. This seems to work around cmake bugs searching only for
9d75ac581Srkayaith      # Development.Module in some environments. However, in other environments
10d75ac581Srkayaith      # it may interfere with the subsequent search for Development.Module.
1184fe34a0SStephen Neuendorffer      find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION}
12cb318526SJohn Demme        COMPONENTS Interpreter Development)
13d75ac581Srkayaith    endif()
14e0af5032SMike Urbach
15e0af5032SMike Urbach    # After CMake 3.18, we are able to limit the scope of the search to just
16e0af5032SMike Urbach    # Development.Module. Searching for Development will fail in situations where
17e0af5032SMike Urbach    # the Python libraries are not available. When possible, limit to just
18e0af5032SMike Urbach    # Development.Module.
19e0af5032SMike Urbach    # See https://pybind11.readthedocs.io/en/stable/compiling.html#findpython-mode
203d92722fSStella Laurenzo    set(_python_development_component Development.Module)
21e0af5032SMike Urbach
223d92722fSStella Laurenzo    find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION}
23e7a1dc23SErick Ochoa      COMPONENTS Interpreter ${_python_development_component} REQUIRED)
24392622d0SMaksim Levental
25392622d0SMaksim Levental    # It's a little silly to detect Python a second time, but nanobind's cmake
26392622d0SMaksim Levental    # code looks for Python_ not Python3_.
27392622d0SMaksim Levental    find_package(Python ${LLVM_MINIMUM_PYTHON_VERSION}
28392622d0SMaksim Levental      COMPONENTS Interpreter ${_python_development_component} REQUIRED)
29392622d0SMaksim Levental
303d92722fSStella Laurenzo    unset(_python_development_component)
313d92722fSStella Laurenzo    message(STATUS "Found python include dirs: ${Python3_INCLUDE_DIRS}")
323d92722fSStella Laurenzo    message(STATUS "Found python libraries: ${Python3_LIBRARIES}")
333d92722fSStella Laurenzo    message(STATUS "Found numpy v${Python3_NumPy_VERSION}: ${Python3_NumPy_INCLUDE_DIRS}")
343d92722fSStella Laurenzo    mlir_detect_pybind11_install()
3556feea73SIngo Müller    find_package(pybind11 2.10 CONFIG REQUIRED)
363d92722fSStella Laurenzo    message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIR}")
373d92722fSStella Laurenzo    message(STATUS "Python prefix = '${PYTHON_MODULE_PREFIX}', "
383d92722fSStella Laurenzo                  "suffix = '${PYTHON_MODULE_SUFFIX}', "
393d92722fSStella Laurenzo                  "extension = '${PYTHON_MODULE_EXTENSION}")
40392622d0SMaksim Levental
41392622d0SMaksim Levental    mlir_detect_nanobind_install()
42b56d1ec6SPeter Hawkins    find_package(nanobind 2.4 CONFIG REQUIRED)
43392622d0SMaksim Levental    message(STATUS "Found nanobind v${nanobind_VERSION}: ${nanobind_INCLUDE_DIR}")
44392622d0SMaksim Levental    message(STATUS "Python prefix = '${PYTHON_MODULE_PREFIX}', "
45392622d0SMaksim Levental                  "suffix = '${PYTHON_MODULE_SUFFIX}', "
46392622d0SMaksim Levental                  "extension = '${PYTHON_MODULE_EXTENSION}")
4765339e4dSStella Laurenzo  endif()
483d92722fSStella Laurenzoendmacro()
493d92722fSStella Laurenzo
50f4f8a67aSStella Laurenzo# Detects a pybind11 package installed in the current python environment
51f4f8a67aSStella Laurenzo# and sets variables to allow it to be found. This allows pybind11 to be
52f4f8a67aSStella Laurenzo# installed via pip, which typically yields a much more recent version than
53f4f8a67aSStella Laurenzo# the OS install, which will be available otherwise.
54f4f8a67aSStella Laurenzofunction(mlir_detect_pybind11_install)
55f4f8a67aSStella Laurenzo  if(pybind11_DIR)
56f4f8a67aSStella Laurenzo    message(STATUS "Using explicit pybind11 cmake directory: ${pybind11_DIR} (-Dpybind11_DIR to change)")
57f4f8a67aSStella Laurenzo  else()
5821b346bdSAlex Zinenko    message(STATUS "Checking for pybind11 in python path...")
59f4f8a67aSStella Laurenzo    execute_process(
6015481bbaSStella Laurenzo      COMMAND "${Python3_EXECUTABLE}"
61f4f8a67aSStella Laurenzo      -c "import pybind11;print(pybind11.get_cmake_dir(), end='')"
62f4f8a67aSStella Laurenzo      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
63f4f8a67aSStella Laurenzo      RESULT_VARIABLE STATUS
64f4f8a67aSStella Laurenzo      OUTPUT_VARIABLE PACKAGE_DIR
65f4f8a67aSStella Laurenzo      ERROR_QUIET)
66f4f8a67aSStella Laurenzo    if(NOT STATUS EQUAL "0")
6721b346bdSAlex Zinenko      message(STATUS "not found (install via 'pip install pybind11' or set pybind11_DIR)")
68f4f8a67aSStella Laurenzo      return()
69f4f8a67aSStella Laurenzo    endif()
7021b346bdSAlex Zinenko    message(STATUS "found (${PACKAGE_DIR})")
71f4f8a67aSStella Laurenzo    set(pybind11_DIR "${PACKAGE_DIR}" PARENT_SCOPE)
72f4f8a67aSStella Laurenzo  endif()
73f4f8a67aSStella Laurenzoendfunction()
74392622d0SMaksim Levental
75392622d0SMaksim Levental
76392622d0SMaksim Levental# Detects a nanobind package installed in the current python environment
77392622d0SMaksim Levental# and sets variables to allow it to be found. This allows nanobind to be
78392622d0SMaksim Levental# installed via pip, which typically yields a much more recent version than
79392622d0SMaksim Levental# the OS install, which will be available otherwise.
80392622d0SMaksim Leventalfunction(mlir_detect_nanobind_install)
81392622d0SMaksim Levental  if(nanobind_DIR)
82392622d0SMaksim Levental    message(STATUS "Using explicit nanobind cmake directory: ${nanobind_DIR} (-Dnanobind_DIR to change)")
83392622d0SMaksim Levental  else()
84392622d0SMaksim Levental    message(STATUS "Checking for nanobind in python path...")
85392622d0SMaksim Levental    execute_process(
86392622d0SMaksim Levental      COMMAND "${Python3_EXECUTABLE}"
87392622d0SMaksim Levental      -c "import nanobind;print(nanobind.cmake_dir(), end='')"
88392622d0SMaksim Levental      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
89392622d0SMaksim Levental      RESULT_VARIABLE STATUS
90392622d0SMaksim Levental      OUTPUT_VARIABLE PACKAGE_DIR
91392622d0SMaksim Levental      ERROR_QUIET)
92392622d0SMaksim Levental    if(NOT STATUS EQUAL "0")
93392622d0SMaksim Levental      message(STATUS "not found (install via 'pip install nanobind' or set nanobind_DIR)")
94392622d0SMaksim Levental      return()
95392622d0SMaksim Levental    endif()
96392622d0SMaksim Levental    message(STATUS "found (${PACKAGE_DIR})")
97392622d0SMaksim Levental    set(nanobind_DIR "${PACKAGE_DIR}" PARENT_SCOPE)
98*5cd42747SPeter Hawkins    execute_process(
99*5cd42747SPeter Hawkins      COMMAND "${Python3_EXECUTABLE}"
100*5cd42747SPeter Hawkins      -c "import nanobind;print(nanobind.include_dir(), end='')"
101*5cd42747SPeter Hawkins      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
102*5cd42747SPeter Hawkins      RESULT_VARIABLE STATUS
103*5cd42747SPeter Hawkins      OUTPUT_VARIABLE PACKAGE_DIR
104*5cd42747SPeter Hawkins      ERROR_QUIET)
105*5cd42747SPeter Hawkins    if(NOT STATUS EQUAL "0")
106*5cd42747SPeter Hawkins      message(STATUS "not found (install via 'pip install nanobind' or set nanobind_DIR)")
107*5cd42747SPeter Hawkins      return()
108*5cd42747SPeter Hawkins    endif()
109*5cd42747SPeter Hawkins    set(nanobind_INCLUDE_DIR "${PACKAGE_DIR}" PARENT_SCOPE)
110392622d0SMaksim Levental  endif()
111392622d0SMaksim Leventalendfunction()
112