|  | # Copyright 2020 Google LLC | 
|  | # | 
|  | # Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | # you may not use this file except in compliance with the License. | 
|  | # You may obtain a copy of the License at | 
|  | # | 
|  | #      https://www.apache.org/licenses/LICENSE-2.0 | 
|  | # | 
|  | # Unless required by applicable law or agreed to in writing, software | 
|  | # distributed under the License is distributed on an "AS IS" BASIS, | 
|  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | # See the License for the specific language governing permissions and | 
|  | # limitations under the License. | 
|  |  | 
|  | include(iree_macros) | 
|  |  | 
|  | # iree_create_configuration | 
|  | # | 
|  | # Creates custom commands and targets for an IREE configuration. An IREE | 
|  | # configuration means a new IREE CMake invocation with its own set of | 
|  | # parameters. | 
|  | # | 
|  | # This function defines a custom target, `iree_configure_${CONFIG_NAME}`, | 
|  | # to drive the generation of a new IREE configuration's `CMakeCache.txt` | 
|  | # file. Callers can then depend on either the `CMakeCache.txt` file or the | 
|  | # `iree_configure_${CONFIG_NAME}` target to make sure the configuration | 
|  | # is invoked as a dependency. | 
|  | # | 
|  | # This function is typically useful when cross-compiling towards another | 
|  | # architecture. For example, when cross-compiling towards Android, we need | 
|  | # to have certain tools first compiled on the host so that we can use them | 
|  | # to programmatically generate some source code to be compiled together | 
|  | # with other checked-in source code. Those host tools will be generated | 
|  | # by another CMake invocation configured by this function. | 
|  | # | 
|  | # Supported CMake options: | 
|  | # - IREE_<CONFIG_NAME>_BINARY_ROOT: the root directory for containing IREE build | 
|  | #   artifacts for the given `CONFIG_NAME`. If not specified in caller, this is | 
|  | #   set to a directory named as `CONFIG_NAME` under the current CMake binary | 
|  | #   directory. | 
|  | # - IREE_<CONFIG_NAME>_C_COMPILER: C compiler for the given `CONFIG_NAME`. | 
|  | #   This must be defined by the caller. | 
|  | # - IREE_<CONFIG_NAME>_CXX_COMPILER: C++ compiler for the given `CONFIG_NAME`. | 
|  | #   This must be defined by the caller. | 
|  | # - IREE_<CONFIG_NAME>_<option>: switch for the given `option` specifically for | 
|  | #   `CONFIG_NAME`. If missing, default to OFF for bool options; default to | 
|  | #   IREE_<option> for non-bool variables. | 
|  | function(iree_create_configuration CONFIG_NAME) | 
|  | # Set IREE_${CONFIG_NAME}_BINARY_ROOT if missing. | 
|  | if(NOT DEFINED IREE_${CONFIG_NAME}_BINARY_ROOT) | 
|  | set(IREE_${CONFIG_NAME}_BINARY_ROOT "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}") | 
|  | set(IREE_${CONFIG_NAME}_BINARY_ROOT ${IREE_${CONFIG_NAME}_BINARY_ROOT} PARENT_SCOPE) | 
|  | message(STATUS "Setting ${CONFIG_NAME} build directory to ${IREE_${CONFIG_NAME}_BINARY_ROOT}") | 
|  | endif() | 
|  |  | 
|  | set(_CONFIG_BINARY_ROOT ${IREE_${CONFIG_NAME}_BINARY_ROOT}) | 
|  |  | 
|  | set(_CONFIG_C_COMPILER ${IREE_${CONFIG_NAME}_C_COMPILER}) | 
|  | set(_CONFIG_CXX_COMPILER ${IREE_${CONFIG_NAME}_CXX_COMPILER}) | 
|  |  | 
|  | # Check the compilers are specified in the caller. | 
|  | if("${_CONFIG_C_COMPILER}" STREQUAL "") | 
|  | message(FATAL_ERROR "Must define IREE_${CONFIG_NAME}_C_COMPILER for \"${CONFIG_NAME}\" configuration build") | 
|  | endif() | 
|  | if("${_CONFIG_CXX_COMPILER}" STREQUAL "") | 
|  | message(FATAL_ERROR "Must define IREE_${CONFIG_NAME}_CXX_COMPILER for \"${CONFIG_NAME}\" configuration build") | 
|  | endif() | 
|  |  | 
|  | add_custom_command(OUTPUT ${_CONFIG_BINARY_ROOT} | 
|  | COMMAND ${CMAKE_COMMAND} -E make_directory ${_CONFIG_BINARY_ROOT} | 
|  | COMMENT "Creating ${_CONFIG_BINARY_ROOT}...") | 
|  |  | 
|  | # Give it a custom target so we can drive the generation manually | 
|  | # when useful. | 
|  | add_custom_target(iree_prepare_${CONFIG_NAME}_dir DEPENDS ${_CONFIG_BINARY_ROOT}) | 
|  |  | 
|  | # LINT.IfChange(iree_cross_compile_options) | 
|  | iree_to_bool(_CONFIG_ENABLE_RUNTIME_TRACING "${IREE_${CONFIG_NAME}_ENABLE_RUNTIME_TRACING}") | 
|  | iree_to_bool(_CONFIG_ENABLE_MLIR "${IREE_${CONFIG_NAME}_ENABLE_MLIR}") | 
|  | iree_to_bool(_CONFIG_ENABLE_EMITC "${IREE_${CONFIG_NAME}_ENABLE_EMITC}") | 
|  |  | 
|  | iree_to_bool(_CONFIG_BUILD_COMPILER "${IREE_${CONFIG_NAME}_BUILD_COMPILER}") | 
|  | iree_to_bool(_CONFIG_BUILD_TESTS "${IREE_${CONFIG_NAME}_BUILD_TESTS}") | 
|  | iree_to_bool(_CONFIG_BUILD_DOCS "${IREE_${CONFIG_NAME}_BUILD_DOCS}") | 
|  | iree_to_bool(_CONFIG_BUILD_SAMPLES "${IREE_${CONFIG_NAME}_BUILD_SAMPLES}") | 
|  | iree_to_bool(_CONFIG_BUILD_DEBUGGER "${IREE_${CONFIG_NAME}_BUILD_DEBUGGER}") | 
|  | iree_to_bool(_CONFIG_BUILD_PYTHON_BINDINGS "${IREE_${CONFIG_NAME}_BUILD_PYTHON_BINDINGS}") | 
|  | iree_to_bool(_CONFIG_BUILD_EXPERIMENTAL "${IREE_${CONFIG_NAME}_BUILD_EXPERIMENTAL}") | 
|  |  | 
|  | # Escape semicolons in the targets list so that CMake doesn't expand them to | 
|  | # spaces. | 
|  | string(REPLACE ";" "$<SEMICOLON>" _CONFIG_HAL_DRIVERS_TO_BUILD "${IREE_HAL_DRIVERS_TO_BUILD}") | 
|  | string(REPLACE ";" "$<SEMICOLON>" _CONFIG_TARGET_BACKENDS_TO_BUILD "${IREE_TARGET_BACKENDS_TO_BUILD}") | 
|  | # LINT.ThenChange( | 
|  | #   https://github.com/google/iree/tree/main/CMakeLists.txt:iree_options, | 
|  | #   https://github.com/google/iree/tree/main/build_tools/cmake/iree_cross_compile.cmake:iree_cross_compile_invoke | 
|  | # ) | 
|  |  | 
|  | message(STATUS "C compiler for ${CONFIG_NAME} build: ${_CONFIG_C_COMPILER}") | 
|  | message(STATUS "C++ compiler for ${CONFIG_NAME} build: ${_CONFIG_CXX_COMPILER}") | 
|  |  | 
|  | add_custom_command(OUTPUT ${IREE_${CONFIG_NAME}_BINARY_ROOT}/CMakeCache.txt | 
|  | COMMAND "${CMAKE_COMMAND}" "${PROJECT_SOURCE_DIR}" -G "${CMAKE_GENERATOR}" | 
|  | -DCMAKE_MAKE_PROGRAM="${CMAKE_MAKE_PROGRAM}" | 
|  | -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" | 
|  | -DCMAKE_C_COMPILER="${_CONFIG_C_COMPILER}" | 
|  | -DCMAKE_CXX_COMPILER="${_CONFIG_CXX_COMPILER}" | 
|  | # LINT.IfChange(iree_cross_compile_invoke) | 
|  | -DIREE_ENABLE_RUNTIME_TRACING=${_CONFIG_ENABLE_RUNTIME_TRACING} | 
|  | -DIREE_ENABLE_MLIR=${_CONFIG_ENABLE_MLIR} | 
|  | -DIREE_ENABLE_EMITC=${_CONFIG_ENABLE_EMITC} | 
|  | -DIREE_BUILD_COMPILER=${_CONFIG_BUILD_COMPILER} | 
|  | -DIREE_BUILD_TESTS=${_CONFIG_BUILD_TESTS} | 
|  | -DIREE_BUILD_DOCS=${_CONFIG_BUILD_DOCS} | 
|  | -DIREE_BUILD_SAMPLES=${_CONFIG_BUILD_SAMPLES} | 
|  | -DIREE_BUILD_DEBUGGER=${_CONFIG_BUILD_DEBUGGER} | 
|  | -DIREE_BUILD_PYTHON_BINDINGS=${_CONFIG_BUILD_PYTHON_BINDINGS} | 
|  | -DIREE_BUILD_EXPERIMENTAL=${_CONFIG_BUILD_EXPERIMENTAL} | 
|  | # LINT.ThenChange( | 
|  | #   https://github.com/google/iree/tree/main/CMakeLists.txt:iree_options, | 
|  | #   https://github.com/google/iree/tree/main/build_tools/cmake/iree_cross_compile.cmake:iree_cross_compile_options, | 
|  | # ) | 
|  | -DIREE_HAL_DRIVERS_TO_BUILD="${_CONFIG_HAL_DRIVERS_TO_BUILD}" | 
|  | -DIREE_TARGET_BACKENDS_TO_BUILD="${_CONFIG_TARGET_BACKENDS_TO_BUILD}" | 
|  | WORKING_DIRECTORY ${_CONFIG_BINARY_ROOT} | 
|  | DEPENDS iree_prepare_${CONFIG_NAME}_dir | 
|  | COMMENT "Configuring IREE for ${CONFIG_NAME} build...") | 
|  |  | 
|  | add_custom_target(iree_configure_${CONFIG_NAME} DEPENDS ${_CONFIG_BINARY_ROOT}/CMakeCache.txt) | 
|  | endfunction() | 
|  |  | 
|  | # iree_get_build_command | 
|  | # | 
|  | # Gets the CMake build command for the given `EXECUTABLE`. | 
|  | # | 
|  | # Parameters: | 
|  | # EXECUTABLE: the executable to build. | 
|  | # BINDIR: root binary directory containing CMakeCache.txt. | 
|  | # CMDVAR: variable name for receiving the build command. | 
|  | function(iree_get_build_command EXECUTABLE) | 
|  | cmake_parse_arguments(_RULE "" "BINDIR;CMDVAR;CONFIG" "" ${ARGN}) | 
|  | if(NOT _RULE_CONFIG) | 
|  | set(_RULE_CONFIG "$<CONFIG>") | 
|  | endif() | 
|  | if (CMAKE_GENERATOR MATCHES "Make") | 
|  | # Use special command for Makefiles to support parallelism. | 
|  | set(${_RULE_CMDVAR} | 
|  | "$(MAKE)" "-C" "${_RULE_BINDIR}" "${EXECUTABLE}" PARENT_SCOPE) | 
|  | else() | 
|  | set(${_RULE_CMDVAR} | 
|  | "${CMAKE_COMMAND}" --build ${_RULE_BINDIR} | 
|  | --target ${EXECUTABLE}${IREE_HOST_EXECUTABLE_SUFFIX} | 
|  | --config ${_RULE_CONFIG} PARENT_SCOPE) | 
|  | endif() | 
|  | endfunction() | 
|  |  | 
|  | # iree_host_install | 
|  | # | 
|  | # Defines custom commands and targets for installing the given `EXECUTABLE` | 
|  | # under host configuration. The custom target for install will be named as | 
|  | # `iree_host_install_${EXECUTABLE}`. | 
|  | # | 
|  | # Precondition: | 
|  | # iree_create_configuration(HOST) is invoked previously. | 
|  | # | 
|  | # Parameters: | 
|  | # EXECUTABLE: the executable to install. | 
|  | # COMPONENT: installation component; used for filtering installation targets. | 
|  | # PREFIX: the root installation path prefix. | 
|  | # DEPENDS: addtional dependencies for the installation. | 
|  | function(iree_host_install EXECUTABLE) | 
|  | cmake_parse_arguments(_RULE "" "COMPONENT;PREFIX" "DEPENDS" ${ARGN}) | 
|  | if(_RULE_COMPONENT) | 
|  | set(_COMPONENT_OPTION -DCMAKE_INSTALL_COMPONENT="${_RULE_COMPONENT}") | 
|  | endif() | 
|  | if(_RULE_PREFIX) | 
|  | set(_PREFIX_OPTION -DCMAKE_INSTALL_PREFIX="${_RULE_PREFIX}") | 
|  | endif() | 
|  |  | 
|  | iree_get_executable_path(_OUTPUT_PATH ${EXECUTABLE}) | 
|  |  | 
|  | add_custom_command( | 
|  | OUTPUT ${_OUTPUT_PATH} | 
|  | DEPENDS ${_RULE_DEPENDS} | 
|  | COMMAND "${CMAKE_COMMAND}" ${_COMPONENT_OPTION} ${_PREFIX_OPTION} | 
|  | -P "${IREE_HOST_BINARY_ROOT}/cmake_install.cmake" | 
|  | USES_TERMINAL) | 
|  |  | 
|  | # Give it a custom target so we can drive the generation manually | 
|  | # when useful. | 
|  | add_custom_target(iree_host_install_${EXECUTABLE} DEPENDS ${_OUTPUT_PATH}) | 
|  | endfunction() | 
|  |  | 
|  | # iree_declare_host_excutable | 
|  | # | 
|  | # Generates custom commands and targets for building and installing a tool on | 
|  | # host for cross-compilation. | 
|  | # | 
|  | # Precondition: | 
|  | # iree_create_configuration(HOST) is invoked previously. | 
|  | # | 
|  | # Parameters: | 
|  | # EXECUTABLE: the executable to build on host. | 
|  | # BUILDONLY: only generates commands for building the target. | 
|  | # DEPENDS: any additional dependencies for the target. | 
|  | function(iree_declare_host_excutable EXECUTABLE) | 
|  | cmake_parse_arguments(_RULE "BUILDONLY" "" "DEPENDS" ${ARGN}) | 
|  |  | 
|  | iree_get_executable_path(_OUTPUT_PATH ${EXECUTABLE}) | 
|  |  | 
|  | iree_get_build_command(${EXECUTABLE} | 
|  | BINDIR ${IREE_HOST_BINARY_ROOT} | 
|  | CMDVAR build_cmd) | 
|  |  | 
|  | add_custom_target(iree_host_build_${EXECUTABLE} | 
|  | COMMAND ${build_cmd} | 
|  | DEPENDS iree_configure_HOST ${_RULE_DEPENDS} | 
|  | WORKING_DIRECTORY "${IREE_HOST_BINARY_ROOT}" | 
|  | COMMENT "Building host ${EXECUTABLE}..." | 
|  | USES_TERMINAL) | 
|  |  | 
|  | if(_RULE_BUILDONLY) | 
|  | return() | 
|  | endif() | 
|  |  | 
|  | iree_host_install(${EXECUTABLE} | 
|  | COMPONENT ${EXECUTABLE} | 
|  | PREFIX ${IREE_HOST_BINARY_ROOT} | 
|  | DEPENDS iree_host_build_${EXECUTABLE}) | 
|  |  | 
|  | # Note that this is not enabled when BUILDONLY so we can define | 
|  | # iree_host_${EXECUTABLE} to point to another installation path to | 
|  | # allow flexibility. | 
|  | add_custom_target(iree_host_${EXECUTABLE} DEPENDS "${_OUTPUT_PATH}") | 
|  | endfunction() |