1# Macros and functions related to detecting details of the Python environment.
2
3# Finds and configures python packages needed to build MLIR Python bindings.
4macro(mlir_configure_python_dev_packages)
5  if(CMAKE_VERSION VERSION_LESS "3.19.0")
6  message(SEND_ERROR
7      "Building MLIR Python bindings is known to rely on CMake features "
8      "that require at least version 3.19. Recommend upgrading to 3.19+ "
9      "for full support. Detected current version: ${CMAKE_VERSION}")
10  endif()
11
12  if(MLIR_DETECT_PYTHON_ENV_PRIME_SEARCH)
13    # Prime the search for python to see if there is a full development
14    # package. This seems to work around cmake bugs searching only for
15    # Development.Module in some environments. However, in other environments
16    # it may interfere with the subsequent search for Development.Module.
17    find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION}
18      COMPONENTS Interpreter Development)
19  endif()
20
21  # After CMake 3.18, we are able to limit the scope of the search to just
22  # Development.Module. Searching for Development will fail in situations where
23  # the Python libraries are not available. When possible, limit to just
24  # Development.Module.
25  # See https://pybind11.readthedocs.io/en/stable/compiling.html#findpython-mode
26  set(_python_development_component Development.Module)
27
28  find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION}
29    COMPONENTS Interpreter ${_python_development_component} NumPy REQUIRED)
30  unset(_python_development_component)
31  message(STATUS "Found python include dirs: ${Python3_INCLUDE_DIRS}")
32  message(STATUS "Found python libraries: ${Python3_LIBRARIES}")
33  message(STATUS "Found numpy v${Python3_NumPy_VERSION}: ${Python3_NumPy_INCLUDE_DIRS}")
34  mlir_detect_pybind11_install()
35  find_package(pybind11 2.8 CONFIG REQUIRED)
36  message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIR}")
37  message(STATUS "Python prefix = '${PYTHON_MODULE_PREFIX}', "
38                 "suffix = '${PYTHON_MODULE_SUFFIX}', "
39                 "extension = '${PYTHON_MODULE_EXTENSION}")
40endmacro()
41
42# Detects a pybind11 package installed in the current python environment
43# and sets variables to allow it to be found. This allows pybind11 to be
44# installed via pip, which typically yields a much more recent version than
45# the OS install, which will be available otherwise.
46function(mlir_detect_pybind11_install)
47  if(pybind11_DIR)
48    message(STATUS "Using explicit pybind11 cmake directory: ${pybind11_DIR} (-Dpybind11_DIR to change)")
49  else()
50    message(STATUS "Checking for pybind11 in python path...")
51    execute_process(
52      COMMAND "${Python3_EXECUTABLE}"
53      -c "import pybind11;print(pybind11.get_cmake_dir(), end='')"
54      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
55      RESULT_VARIABLE STATUS
56      OUTPUT_VARIABLE PACKAGE_DIR
57      ERROR_QUIET)
58    if(NOT STATUS EQUAL "0")
59      message(STATUS "not found (install via 'pip install pybind11' or set pybind11_DIR)")
60      return()
61    endif()
62    message(STATUS "found (${PACKAGE_DIR})")
63    set(pybind11_DIR "${PACKAGE_DIR}" PARENT_SCOPE)
64  endif()
65endfunction()
66