# Copyright (C) 2018-2025 Intel Corporation # SPDX-License-Identifier: Apache-2.0 # if(WIN32) # 3.16: FindPython3.cmake can find Python via -DPython3_EXECUTABLE # 3.18: FindPython3.cmake can find Python automatically from virtualenv cmake_minimum_required(VERSION 3.16) else() # 3.13: default choice cmake_minimum_required(VERSION 3.13) endif() project(OpenVINOPython DESCRIPTION "OpenVINO Runtime Python bindings") # # Packages & settings # if(NOT DEFINED OpenVINO_SOURCE_DIR) find_package(OpenVINODeveloperPackage REQUIRED) # we assume that OpenVINODeveloperPackage is generated in OpenVINO build tree set(OpenVINO_BINARY_DIR "${OpenVINODeveloperPackage_DIR}") # but this can be invalid for cases of OpenVINODeveloperPackage relocatable installation # so, we need to disable wheen generation for this case if(NOT EXISTS "${OpenVINO_BINARY_DIR}/cmake_install.cmake") set(OpenVINODeveloperPackage_RELOCATABLE ON) endif() set(OpenVINO_SOURCE_DIR "${OpenVINOPython_SOURCE_DIR}/../../../") endif() if(NOT DEFINED OpenVINODeveloperPackage_RELOCATABLE) set(OpenVINODeveloperPackage_RELOCATABLE OFF) endif() # # Check python requirements # function(ov_check_python_build_conditions) # user explicitly specified ENABLE_PYTHON=ON if(ENABLE_PYTHON) set(find_package_mode REQUIRED) set(message_mode FATAL_ERROR) else() set(find_package_mode QUIET) set(message_mode WARNING) endif() ov_find_python3(${find_package_mode}) if(Python3_Development.Module_FOUND OR Python3_Development_FOUND) message(STATUS "Python3 executable: ${Python3_EXECUTABLE}") message(STATUS "Python3 version: ${Python3_VERSION}") if(Python3_PyPy_VERSION) message(STATUS "Python3 PyPy version: ${Python3_PyPy_VERSION}") endif() message(STATUS "Python3 interpreter ID: ${Python3_INTERPRETER_ID}") if(Python3_SOABI) message(STATUS "Python3 SOABI: ${Python3_SOABI}") endif() ov_detect_python_module_extension() if(PYTHON_MODULE_EXTENSION) set(PYTHON_MODULE_EXTENSION ${PYTHON_MODULE_EXTENSION} PARENT_SCOPE) message(STATUS "PYTHON_MODULE_EXTENSION: ${PYTHON_MODULE_EXTENSION}") endif() message(STATUS "Python3 include dirs: ${Python3_INCLUDE_DIRS}") message(STATUS "Python3 libraries: ${Python3_LIBRARIES}") else() message(${message_mode} "Python 3.x Interpreter and Development.Module components are not found. OpenVINO Python API will be turned off (ENABLE_PYTHON is OFF)") endif() if(NOT OV_GENERATOR_MULTI_CONFIG AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND CMAKE_DEBUG_POSTFIX) set(python_debug ON) message(${message_mode} "Building python bindings in debug configuration is not supported on your platform (ENABLE_PYTHON is OFF)") else() set(python_debug OFF) endif() set(is_compiler_supported ON) # Python bindings compiled with the 14.28 toolset (19.28 compiler) could not be imported by another Pybind module linked with OpenVINO if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.29) set(is_compiler_supported OFF) message(${message_mode} "MSVC toolset version 14.28 or lower (19.28 compiler) is not supported. Please update your toolset (${CMAKE_CXX_COMPILER_VERSION}).") endif() if((Python3_Development.Module_FOUND OR Python3_Development_FOUND) AND NOT python_debug AND is_compiler_supported) set(ENABLE_PYTHON_DEFAULT ON PARENT_SCOPE) else() set(ENABLE_PYTHON_DEFAULT OFF PARENT_SCOPE) endif() endfunction() ov_check_python_build_conditions() # check __init__.py files alignment function(ov_check_init_files_alignment init_files) # check the files in pairs list(LENGTH init_files init_files_count) math(EXPR file_loop_range "${init_files_count}-2") foreach(init_file_idx RANGE 0 ${file_loop_range}) math(EXPR init_file_idx_next "${init_file_idx}+1") list(GET init_files ${init_file_idx} file1) list(GET init_files ${init_file_idx_next} file2) execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files ${file1} ${file2} RESULT_VARIABLE compare_result ) if(compare_result EQUAL 1) message(FATAL_ERROR "The runtime __init__.py files are misaligned: ${file1} and ${file2}") endif() endforeach() endfunction() set(INIT_FILES_RUNTIME "${OpenVINOPython_SOURCE_DIR}/src/openvino/__init__.py" "${OpenVINO_SOURCE_DIR}/tools/ovc/openvino/__init__.py" "${OpenVINO_SOURCE_DIR}/tools/benchmark_tool/openvino/__init__.py") ov_check_init_files_alignment("${INIT_FILES_RUNTIME}") ov_option(ENABLE_PYTHON "Enables OpenVINO Python API build" ${ENABLE_PYTHON_DEFAULT}) ov_dependent_option (ENABLE_PYTHON_PACKAGING "Enables packaging of Python API in APT / YUM" OFF "ENABLE_PYTHON;LINUX" OFF) # # Check for wheel package # # user explicitly specified ENABLE_WHEEL=ON if(ENABLE_WHEEL) set(find_package_mode REQUIRED) set(message_mode FATAL_ERROR) else() set(find_package_mode QUIET) set(message_mode WARNING) endif() set(wheel_reqs "${OpenVINOPython_SOURCE_DIR}/wheel/requirements-dev.txt") ov_check_pip_packages(REQUIREMENTS_FILE "${OpenVINOPython_SOURCE_DIR}/wheel/requirements-dev.txt" RESULT_VAR ENABLE_WHEEL_DEFAULT MESSAGE_MODE WARNING) if(LINUX) find_host_program(patchelf_program NAMES patchelf DOC "Path to patchelf tool") if(NOT patchelf_program) set(ENABLE_WHEEL_DEFAULT OFF) message(${message_mode} "patchelf is not found. It is required to build OpenVINO Runtime wheel. Install via `pip install patchelf` or `apt install patchelf`.") endif() endif() if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) set(SETUP_PY_REQUIREMENTS_FOUND ON) else() message(${message_mode} "Cmake version 3.15 and higher is required to build 'openvino' wheel. Provided version ${CMAKE_VERSION}") set(SETUP_PY_REQUIREMENTS_FOUND OFF) endif() if(NOT SETUP_PY_REQUIREMENTS_FOUND) # setup.py requirements are importnant to build wheel set(ENABLE_WHEEL_DEFAULT OFF) endif() # this option should not be a part of OpenVINODeveloperPackage # since wheels can be built only together with main OV build ov_dependent_option(ENABLE_WHEEL "Build wheel packages for PyPI" ${ENABLE_WHEEL_DEFAULT} "ENABLE_PYTHON;NOT OpenVINODeveloperPackage_RELOCATABLE" OFF) if(NOT ENABLE_PYTHON) if(CMAKE_SOURCE_DIR STREQUAL OpenVINOPython_SOURCE_DIR) message(FATAL_ERROR "Python OpenVINO API build requirements are not satisfied.") else() return() endif() endif() if(NOT SETUP_PY_REQUIREMENTS_FOUND AND ENABLE_PYTHON_PACKAGING) message(FATAL_ERROR "Python cannot be packaged, because setup.py requirements are not satisfied (cmake version >= 3.15 is required, provided ${CMAKE_VERSION})") endif() # # Build the code # if(CMAKE_CROSSCOMPILING) set(pybind11_min_version 2.12.0) else() set(pybind11_min_version 2.12.0) endif() # search for FindPython3.cmake instead of legacy modules set(PYBIND11_FINDPYTHON ON) ov_find_python3(REQUIRED) find_package(pybind11 ${pybind11_min_version} QUIET) if(NOT pybind11_FOUND) add_subdirectory(thirdparty/pybind11 EXCLUDE_FROM_ALL) endif() add_subdirectory(src/pyopenvino) # # Packaging # macro(ov_define_setup_py_packaging_vars) # Python3_VERSION_MAJOR and Python3_VERSION_MINOR are defined inside pybind11 set(pyversion python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) # define version (syncronize with tools/openvino_dev/CMakeLists.txt) if(DEFINED ENV{CI_BUILD_DEV_TAG} AND NOT "$ENV{CI_BUILD_DEV_TAG}" STREQUAL "") set(WHEEL_VERSION "${OpenVINO_VERSION}.$ENV{CI_BUILD_DEV_TAG}" CACHE STRING "Version of this release" FORCE) set(wheel_pre_release ON) else() set(WHEEL_VERSION ${OpenVINO_VERSION} CACHE STRING "Version of this release" FORCE) endif() set(WHEEL_BUILD "${OpenVINO_VERSION_BUILD}" CACHE STRING "Build number of this release" FORCE) # Common vars used by setup.py set(PY_PACKAGES_DIR ${OV_CPACK_PYTHONDIR}) set(TBB_LIBS_DIR runtime/3rdparty/tbb/lib) if(WIN32) set(TBB_LIBS_DIR runtime/3rdparty/tbb/bin) endif() set(PUGIXML_LIBS_DIR runtime/3rdparty/pugixml/lib) if(USE_BUILD_TYPE_SUBFOLDER) set(build_type ${CMAKE_BUILD_TYPE}) else() set(build_type $) endif() # define setup.py running environment set(setup_py_env ${CMAKE_COMMAND} -E env # for cross-compilation SETUPTOOLS_EXT_SUFFIX=${PYTHON_MODULE_EXTENSION} # versions WHEEL_VERSION=${WHEEL_VERSION} WHEEL_BUILD=${WHEEL_BUILD} # build locations OPENVINO_SOURCE_DIR=${OpenVINO_SOURCE_DIR} OPENVINO_BINARY_DIR=${OpenVINO_BINARY_DIR} OPENVINO_PYTHON_BINARY_DIR=${OpenVINOPython_BINARY_DIR} # to create proper directories for BA, OVC tools CPACK_GENERATOR=${CPACK_GENERATOR} # propogate build type BUILD_TYPE=${build_type} # variables to reflect cpack locations OV_RUNTIME_LIBS_DIR=${OV_CPACK_RUNTIMEDIR} TBB_LIBS_DIR=${TBB_LIBS_DIR} PUGIXML_LIBS_DIR=${PUGIXML_LIBS_DIR} PY_PACKAGES_DIR=${PY_PACKAGES_DIR}) endmacro() macro(ov_define_setup_py_dependencies) foreach(_target # Python API dependencies pyopenvino py_ov_frontends # C API openvino_c # plugins ov_plugins # frontends ov_frontends) if(TARGET ${_target}) list(APPEND ov_setup_py_deps ${_target}) endif() endforeach() file(GLOB_RECURSE openvino_py_files ${OpenVINOPython_SOURCE_DIR}/src/openvino/*.py) file(GLOB_RECURSE openvino_pyi_files ${OpenVINOPython_SOURCE_DIR}/src/openvino/*.pyi) list(APPEND openvino_py_files ${openvino_pyi_files}) list(APPEND ov_setup_py_deps ${openvino_py_files} "${OpenVINO_SOURCE_DIR}/pyproject.toml" "${OpenVINO_SOURCE_DIR}/setup.py" "${OpenVINOPython_SOURCE_DIR}/requirements.txt" "${OpenVINOPython_SOURCE_DIR}/wheel/readme.txt" "${OpenVINO_SOURCE_DIR}/LICENSE" "${OpenVINO_SOURCE_DIR}/licensing/onednn_third-party-programs.txt" "${OpenVINO_SOURCE_DIR}/licensing/runtime-third-party-programs.txt" "${OpenVINO_SOURCE_DIR}/licensing/onetbb_third-party-programs.txt" "${OpenVINO_SOURCE_DIR}/docs/dev/pypi_publish/pypi-openvino-rt.md") if(wheel_pre_release) list(APPEND ov_setup_py_deps "${OpenVINO_SOURCE_DIR}/docs/dev/pypi_publish/pre-release-note.md") endif() endmacro() ov_define_setup_py_packaging_vars() ov_define_setup_py_dependencies() if(ENABLE_WHEEL) add_subdirectory(wheel) endif() # # Target, which creates python install tree for cases of DEB | RPM packages # if(ENABLE_PYTHON_PACKAGING) # site-packages depending on package type set(python_xy "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") if(CPACK_GENERATOR STREQUAL "DEB") set(python_versioned_folder "python${Python3_VERSION_MAJOR}") set(ov_site_packages "dist-packages") elseif(CPACK_GENERATOR STREQUAL "RPM") set(python_versioned_folder "python${python_xy}") set(ov_site_packages "site-packages") endif() # install OpenVINO Python API set(ov_python_package_prefix "${CMAKE_CURRENT_BINARY_DIR}/openvino/install_${pyversion}") set(ov_install_lib "${ov_python_package_prefix}/lib/${python_versioned_folder}/${ov_site_packages}") set(openvino_meta_info_subdir "openvino-${OpenVINO_VERSION}-py${python_xy}.egg-info") set(openvino_meta_info_file "${ov_install_lib}/${openvino_meta_info_subdir}/PKG-INFO") add_custom_command(OUTPUT ${openvino_meta_info_file} COMMAND ${CMAKE_COMMAND} -E remove_directory "${ov_python_package_prefix}" COMMAND ${setup_py_env} # variables to reflect options (extensions only or full wheel package) PYTHON_EXTENSIONS_ONLY=ON SKIP_RPATH=ON "${Python3_EXECUTABLE}" "${OpenVINO_SOURCE_DIR}/setup.py" --no-user-cfg --quiet build --executable "/usr/bin/python3" build_ext install --no-compile --prefix "${ov_python_package_prefix}" --install-lib "${ov_install_lib}" --install-scripts "${ov_python_package_prefix}/bin" --single-version-externally-managed --record=installed.txt WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" DEPENDS ${ov_setup_py_deps} COMMENT "Create python package with ${openvino_meta_info_subdir} folder") # Install OpenVINO Telemetry set(OpenVINO_Telemetry_SOURCE_DIR "${OpenVINO_SOURCE_DIR}/thirdparty/telemetry") file(GLOB_RECURSE telemetry_files ${OpenVINO_Telemetry_SOURCE_DIR}/*) set(telemetry_python_package_prefix "${CMAKE_CURRENT_BINARY_DIR}/telemetry/install_${pyversion}") set(telemetry_install_lib "${telemetry_python_package_prefix}/lib/${python_versioned_folder}/${ov_site_packages}") set(openvino_telemetry_meta_info_subdir "openvino-telemetry-${OpenVINO_VERSION}-py${python_xy}.egg-info") set(openvino_telemetry_meta_info_file "${telemetry_install_lib}/${openvino_telemetry_meta_info_subdir}/PKG-INFO") add_custom_command(OUTPUT ${openvino_telemetry_meta_info_file} COMMAND ${CMAKE_COMMAND} -E remove_directory "${telemetry_python_package_prefix}" COMMAND "${Python3_EXECUTABLE}" "${OpenVINO_Telemetry_SOURCE_DIR}/setup.py" --no-user-cfg --quiet build --executable "/usr/bin/python3" install --no-compile --prefix "${telemetry_python_package_prefix}" --install-lib "${telemetry_install_lib}" --install-scripts "${telemetry_python_package_prefix}/bin" --single-version-externally-managed --record=installed.txt WORKING_DIRECTORY "${OpenVINO_Telemetry_SOURCE_DIR}" DEPENDS ${telemetry_files} COMMENT "Create python package with ${openvino_telemetry_meta_info_subdir} folder") # create custom target add_custom_target(_python_api_package ALL DEPENDS ${openvino_meta_info_file} ${openvino_telemetry_meta_info_file}) # install python package, which will be later packed into DEB | RPM ov_cpack_add_component(${OV_CPACK_COMP_PYTHON_OPENVINO}_package_${pyversion} HIDDEN) install(DIRECTORY ${ov_python_package_prefix}/ ${telemetry_python_package_prefix}/ DESTINATION . COMPONENT ${OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE}_${pyversion} ${OV_CPACK_COMP_PYTHON_OPENVINO_PACKAGE_EXCLUDE_ALL} USE_SOURCE_PERMISSIONS) endif() # # Tests # if(ENABLE_TESTS) add_subdirectory(tests/mock/mock_py_frontend) add_subdirectory(tests/mock/pyngraph_fe_mock_api) install(FILES constraints.txt DESTINATION tests/bindings/python COMPONENT tests EXCLUDE_FROM_ALL) install(FILES requirements_test.txt DESTINATION tests/bindings/python COMPONENT tests EXCLUDE_FROM_ALL) install(FILES src/openvino/preprocess/torchvision/requirements.txt DESTINATION tests/python/preprocess/torchvision COMPONENT tests EXCLUDE_FROM_ALL) endif() if(OpenVINODeveloperPackage_FOUND) # provides a callback function to describe each component in repo include("${OpenVINO_SOURCE_DIR}/cmake/packaging/packaging.cmake") ov_cpack(${OV_CPACK_COMPONENTS_ALL}) endif()