| # Copyright 2020 The IREE Authors |
| # |
| # Licensed under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| include(CMakeParseArguments) |
| |
| ############################################################################### |
| # Package detection |
| ############################################################################### |
| |
| # Checks whether the PyYAML package is available. Sets IREE_PYYAML_FOUND to |
| # ON if so. |
| function(iree_detect_pyyaml) |
| execute_process( |
| COMMAND ${Python3_EXECUTABLE} -c "import yaml" |
| RESULT_VARIABLE EXIT_CODE |
| OUTPUT_QUIET |
| ERROR_QUIET |
| ) |
| if(EXIT_CODE) |
| message(STATUS "Looking for PyYAML - not found (some features may not be available: install with 'python -m pip install PyYAML' or equiv for your system)") |
| set(IREE_PYYAML_FOUND OFF PARENT_SCOPE) |
| else() |
| message(STATUS "Looking for PyYAML - found") |
| set(IREE_PYYAML_FOUND ON PARENT_SCOPE) |
| endif() |
| endfunction() |
| |
| |
| ############################################################################### |
| # Main user rules |
| ############################################################################### |
| |
| # iree_pyext_module() |
| # |
| # Builds a native python module (.so/.dylib/.pyd). |
| # |
| # Parameters: |
| # NAME: name of target |
| # MODULE_NAME: Base-name of the module. |
| # SRCS: List of source files for the library |
| # DEPS: List of other targets the test python libraries require |
| # COPTS: List of private compile options |
| # DEFINES: List of public defines |
| # INCLUDES: Include directories to add to dependencies |
| function(iree_pyext_module) |
| cmake_parse_arguments(ARG |
| "" |
| "NAME;MODULE_NAME;UNIX_LINKER_SCRIPT" |
| "SRCS;DEPS;COPTS;DEFINES;INCLUDES" |
| ${ARGN}) |
| |
| iree_package_ns(_PACKAGE_NS) |
| # Replace dependencies passed by ::name with ::iree::package::name |
| list(TRANSFORM ARG_DEPS REPLACE "^::" "${_PACKAGE_NS}::") |
| list(TRANSFORM ARG_PYEXT_DEPS REPLACE "^::" "${_PACKAGE_NS}::") |
| # Prefix the library with the package name, so we get: iree_package_name. |
| iree_package_name(_PACKAGE_NAME) |
| set(_NAME "${_PACKAGE_NAME}_${ARG_NAME}") |
| |
| pybind11_add_module( |
| ${_NAME} |
| ${ARG_SRCS} |
| ) |
| |
| # Alias the iree_package_name library to iree::package::name so that we can |
| # refer to this target with the namespaced format. |
| add_library(${_PACKAGE_NS}::${ARG_NAME} ALIAS ${_NAME}) |
| |
| target_link_libraries( |
| ${_NAME} |
| PRIVATE ${ARG_DEPS} |
| ) |
| |
| set_target_properties( |
| ${_NAME} PROPERTIES |
| OUTPUT_NAME "${ARG_MODULE_NAME}" |
| ) |
| |
| target_include_directories(${_NAME} |
| PUBLIC |
| "$<BUILD_INTERFACE:${ARG_INCLUDES}>" |
| ) |
| |
| # pybind11 requires both RTTI and Exceptions, and it does not know that |
| # we have disabled them globally, so turn them back on. Since this is |
| # *the only* place in the codebase where we do this, just inline here. |
| # Note that this is playing with fire and the extension code is structured |
| # so as not to cause problems with RTTI cross-module issues. |
| iree_select_compiler_opts(_RTTI_AND_EXCEPTION_COPTS |
| CLANG_OR_GCC |
| "-frtti" |
| "-fexceptions" |
| MSVC_OR_CLANG_CL |
| # Configure exception handling for standard C++ behavior. |
| # - /EHs enables C++ catch-style exceptions |
| # - /EHc breaks unwinding across extern C boundaries, dramatically reducing |
| # unwind table size and associated exception handling overhead as the |
| # compiler can assume no exception will ever be thrown within any function |
| # annotated with extern "C". |
| # https://docs.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model |
| "/EHsc" |
| # Configure RTTI generation. |
| # - /GR - Enable generation of RTTI (default) |
| # - /GR- - Disables generation of RTTI |
| # https://docs.microsoft.com/en-us/cpp/build/reference/gr-enable-run-time-type-information?view=msvc-160 |
| "/GR" |
| ) |
| |
| set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD 17) |
| set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) |
| |
| target_compile_options( |
| ${_NAME} PRIVATE |
| ${ARG_COPTS} |
| ${IREE_DEFAULT_COPTS} |
| ${_RTTI_AND_EXCEPTION_COPTS} |
| ) |
| |
| target_compile_definitions( |
| ${_NAME} PUBLIC |
| ${ARG_DEFINES} |
| ) |
| |
| # Link flags. |
| if(UNIX AND NOT APPLE) # Apple does not support linker scripts. |
| if(ARG_UNIX_LINKER_SCRIPT) |
| set_target_properties(${_NAME} PROPERTIES LINK_FLAGS |
| "-Wl,--version-script=\"${CMAKE_CURRENT_SOURCE_DIR}/${ARG_UNIX_LINKER_SCRIPT}\"") |
| endif() |
| endif() |
| endfunction() |
| |
| # iree_py_library() |
| # |
| # CMake function to imitate Bazel's iree_py_library rule. |
| # |
| # Parameters: |
| # NAME: name of target |
| # SRCS: List of source files for the library |
| # DEPS: List of other targets the test python libraries require |
| # PYEXT_DEPS: List of deps of extensions built with iree_pyext_module |
| function(iree_py_library) |
| cmake_parse_arguments( |
| _RULE |
| "" |
| "NAME" |
| "SRCS;DEPS;PYEXT_DEPS" |
| ${ARGN} |
| ) |
| |
| iree_package_ns(_PACKAGE_NS) |
| # Replace dependencies passed by ::name with ::iree::package::name |
| list(TRANSFORM _RULE_DEPS REPLACE "^::" "${_PACKAGE_NS}::") |
| |
| iree_package_name(_PACKAGE_NAME) |
| set(_NAME "${_PACKAGE_NAME}_${_RULE_NAME}") |
| |
| add_custom_target(${_NAME} ALL |
| DEPENDS ${_RULE_DEPS} |
| ) |
| |
| # Symlink each file as its own target. |
| foreach(_SRC_FILE ${_RULE_SRCS}) |
| # _SRC_FILE could have other path components in it, so we need to make a |
| # directory for it. Ninja does this automatically, but make doesn't. See |
| # https://github.com/openxla/iree/issues/6801 |
| set(_SRC_BIN_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_SRC_FILE}") |
| get_filename_component(_SRC_BIN_DIR "${_SRC_BIN_PATH}" DIRECTORY) |
| add_custom_command( |
| TARGET ${_NAME} |
| COMMAND |
| ${CMAKE_COMMAND} -E make_directory "${_SRC_BIN_DIR}" |
| COMMAND ${CMAKE_COMMAND} -E create_symlink |
| "${CMAKE_CURRENT_SOURCE_DIR}/${_SRC_FILE}" "${_SRC_BIN_PATH}" |
| BYPRODUCTS "${_SRC_BIN_PATH}" |
| ) |
| endforeach() |
| |
| # Add PYEXT_DEPS if any. |
| if(_RULE_PYEXT_DEPS) |
| list(TRANSFORM _RULE_PYEXT_DEPS REPLACE "^::" "${_PACKAGE_NS}::") |
| add_dependencies(${_NAME} ${_RULE_PYEXT_DEPS}) |
| endif() |
| endfunction() |
| |
| # iree_local_py_test() |
| # |
| # CMake function to run python test with provided python package paths. |
| # |
| # Parameters: |
| # NAME: name of test |
| # SRC: Test source file |
| # ARGS: Command line arguments to the Python source file. |
| # LABELS: Additional labels to apply to the test. The package path is added |
| # automatically. |
| # GENERATED_IN_BINARY_DIR: If present, indicates that the srcs have been |
| # in the CMAKE_CURRENT_BINARY_DIR. |
| # PACKAGE_DIRS: Python package paths to be added to PYTHONPATH. |
| function(iree_local_py_test) |
| if(NOT IREE_BUILD_TESTS OR ANDROID OR EMSCRIPTEN) |
| return() |
| endif() |
| |
| cmake_parse_arguments( |
| _RULE |
| "GENERATED_IN_BINARY_DIR" |
| "NAME;SRC" |
| "ARGS;LABELS;PACKAGE_DIRS;TIMEOUT" |
| ${ARGN} |
| ) |
| |
| # Switch between source and generated tests. |
| set(_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}") |
| if(_RULE_GENERATED_IN_BINARY_DIR) |
| set(_SRC_DIR "${CMAKE_CURRENT_BINARY_DIR}") |
| endif() |
| |
| iree_package_name(_PACKAGE_NAME) |
| set(_NAME "${_PACKAGE_NAME}_${_RULE_NAME}") |
| |
| iree_package_ns(_PACKAGE_NS) |
| string(REPLACE "::" "/" _PACKAGE_PATH ${_PACKAGE_NS}) |
| set(_NAME_PATH "${_PACKAGE_PATH}/${_RULE_NAME}") |
| list(APPEND _RULE_LABELS "${_PACKAGE_PATH}") |
| |
| add_test( |
| NAME ${_NAME_PATH} |
| COMMAND |
| "${Python3_EXECUTABLE}" |
| "${CMAKE_CURRENT_SOURCE_DIR}/${_RULE_SRC}" |
| ${_RULE_ARGS} |
| ) |
| |
| set_property(TEST ${_NAME_PATH} PROPERTY LABELS "${_RULE_LABELS}") |
| set_property(TEST ${_NAME_PATH} PROPERTY TIMEOUT ${_RULE_ARGS}) |
| |
| # Extend the PYTHONPATH environment variable with _RULE_PACKAGE_DIRS. |
| list(APPEND _RULE_PACKAGE_DIRS "$ENV{PYTHONPATH}") |
| if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") |
| # Windows uses semi-colon delimiters, but so does CMake, so escape them. |
| list(JOIN _RULE_PACKAGE_DIRS "\\;" _PYTHONPATH) |
| else() |
| list(JOIN _RULE_PACKAGE_DIRS ":" _PYTHONPATH) |
| endif() |
| set_property(TEST ${_NAME_PATH} PROPERTY ENVIRONMENT |
| "PYTHONPATH=${_PYTHONPATH}" |
| ) |
| |
| if (NOT DEFINED _RULE_TIMEOUT) |
| set(_RULE_TIMEOUT 60) |
| endif() |
| |
| iree_configure_test(${_NAME_PATH}) |
| |
| # TODO(marbre): Find out how to add deps to tests. |
| # Similar to _RULE_DATA in iree_lit_test(). |
| endfunction() |
| |
| # iree_py_test() |
| # |
| # CMake function to imitate Bazel's iree_py_test rule. |
| # |
| # Parameters: |
| # NAME: name of test |
| # SRCS: Test source file (single file only, despite name) |
| # ARGS: Command line arguments to the Python source file. |
| # LABELS: Additional labels to apply to the test. The package path is added |
| # automatically. |
| # GENERATED_IN_BINARY_DIR: If present, indicates that the srcs have been |
| # in the CMAKE_CURRENT_BINARY_DIR. |
| function(iree_py_test) |
| cmake_parse_arguments( |
| _RULE |
| "GENERATED_IN_BINARY_DIR" |
| "NAME;SRCS" |
| "ARGS;LABELS;TIMEOUT" |
| ${ARGN} |
| ) |
| if(NOT IREE_BUILD_PYTHON_BINDINGS) |
| return() |
| endif() |
| |
| iree_local_py_test( |
| NAME |
| "${_RULE_NAME}" |
| SRC |
| "${_RULE_SRCS}" |
| ARGS |
| ${_RULE_ARGS} |
| LABELS |
| ${_RULE_LABELS} |
| PACKAGE_DIRS |
| "${IREE_BINARY_DIR}/compiler/bindings/python" |
| "${IREE_BINARY_DIR}/runtime/bindings/python" |
| GENERATED_IN_BINARY_DIR |
| "${_RULE_GENERATED_IN_BINARY_DIR}" |
| TIMEOUT |
| ${_RULE_TIMEOUT} |
| ) |
| endfunction() |
| |
| # iree_build_tools_py_test() |
| # |
| # CMake function to test with build_tools python modules. |
| # |
| # Parameters: |
| # NAME: name of test |
| # SRC: Test source file |
| # ARGS: Command line arguments to the Python source file. |
| # LABELS: Additional labels to apply to the test. The package path is added |
| # automatically. |
| # PACKAGE_DIRS: Additional python module paths. |
| function(iree_build_tools_py_test) |
| cmake_parse_arguments( |
| _RULE |
| "" |
| "NAME;SRC" |
| "ARGS;LABELS;PACKAGE_DIRS" |
| ${ARGN} |
| ) |
| |
| iree_local_py_test( |
| NAME |
| "${_RULE_NAME}" |
| SRC |
| "${_RULE_SRC}" |
| ARGS |
| ${_RULE_ARGS} |
| LABELS |
| ${_RULE_LABELS} |
| PACKAGE_DIRS |
| ${_RULE_PACKAGE_DIRS} |
| "${IREE_ROOT_DIR}/build_tools/python" |
| ) |
| endfunction() |