# 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})

  # Compile options. keep these in sync with the root CMakeLists.txt and the
  # invoke options below.
  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_JAVA_BINDINGS "${IREE_${CONFIG_NAME}_BUILD_JAVA_BINDINGS}")
  iree_to_bool(_CONFIG_BUILD_EXPERIMENTAL "${IREE_${CONFIG_NAME}_BUILD_EXPERIMENTAL}")
  iree_to_bool(_CONFIG_BUILD_TENSORFLOW_COMPILER "${IREE_${CONFIG_NAME}_BUILD_TENSORFLOW_COMPILER}")

  # 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}")

  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}" "${CMAKE_CURRENT_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}"
        # Invoke options. Keep these in sync with the root CMakeLists.txt and
        # the compile options above
        -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_JAVA_BINDINGS=${_CONFIG_BUILD_JAVA_BINDINGS}
        -DIREE_BUILD_EXPERIMENTAL=${_CONFIG_BUILD_EXPERIMENTAL}
        -DIREE_BUILD_TENSORFLOW_COMPILER=${_CONFIG_BUILD_TENSORFLOW_COMPILER}

        -DIREE_HAL_DRIVERS_TO_BUILD="${_CONFIG_HAL_DRIVERS_TO_BUILD}"
        -DIREE_TARGET_BACKENDS_TO_BUILD="${_CONFIG_TARGET_BACKENDS_TO_BUILD}"
        -DIREE_ENABLE_ASAN=${IREE_ENABLE_ASAN}
        -DIREE_ENABLE_MSAN=${IREE_ENABLE_MSAN}
        -DIREE_ENABLE_TSAN=${IREE_ENABLE_TSAN}
        -DIREE_ENABLE_CCACHE=${IREE_ENABLE_CCACHE}
        -DLLVM_CCACHE_BUILD=${LLVM_CCACHE_BUILD}
        -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE}
    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_TARGET`.
#
# Parameters:
# EXECUTABLE_TARGET: the target for 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_TARGET)
  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_TARGET}" PARENT_SCOPE)
  else()
    set(${_RULE_CMDVAR}
        "${CMAKE_COMMAND}" --build ${_RULE_BINDIR}
                           --target ${EXECUTABLE_TARGET}
                           --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.
# EXECUTABLE_TARGET: the target name for the executable.
# BUILDONLY: only generates commands for building the target.
# DEPENDS: any additional dependencies for the target.
function(iree_declare_host_excutable EXECUTABLE EXECUTABLE_TARGET)
  cmake_parse_arguments(_RULE "BUILDONLY" "" "DEPENDS" ${ARGN})

  iree_get_executable_path(_OUTPUT_PATH ${EXECUTABLE})

  iree_get_build_command(${EXECUTABLE_TARGET}
    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()
