# Copyright 2019 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

#-------------------------------------------------------------------------------
# Missing CMake Variables
#-------------------------------------------------------------------------------

if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
  set(IREE_HOST_SCRIPT_EXT "bat")
  # https://gitlab.kitware.com/cmake/cmake/-/issues/17553
  set(IREE_HOST_EXECUTABLE_SUFFIX ".exe")
else()
  set(IREE_HOST_SCRIPT_EXT "sh")
  set(IREE_HOST_EXECUTABLE_SUFFIX "")
endif()

#-------------------------------------------------------------------------------
# IREE_ARCH: identifies the target CPU architecture. May be empty when this is
# ill-defined, such as multi-architecture builds.
# This should be kept consistent with the C preprocessor token IREE_ARCH defined
# in target_platform.h.
#-------------------------------------------------------------------------------

# First, get the raw CMake architecture name, not yet normalized. Even that is
# non-trivial: it usually is CMAKE_SYSTEM_PROCESSOR, but on some platforms, we
# have to read other variables instead.
if(CMAKE_OSX_ARCHITECTURES)
  # Borrowing from:
  # https://boringssl.googlesource.com/boringssl/+/c5f0e58e653d2d9afa8facc090ce09f8aaa3fa0d/CMakeLists.txt#43
  # https://github.com/google/XNNPACK/blob/2eb43787bfad4a99bdb613111cea8bc5a82f390d/CMakeLists.txt#L40
  list(LENGTH CMAKE_OSX_ARCHITECTURES NUM_ARCHES)
  if(${NUM_ARCHES} EQUAL 1)
    # Only one arch in CMAKE_OSX_ARCHITECTURES, use that.
    set(_IREE_UNNORMALIZED_ARCH "${CMAKE_OSX_ARCHITECTURES}")
  endif()
  # Leaving _IREE_UNNORMALIZED_ARCH empty disables arch code paths. We will
  # issue a performance warning about that below.
elseif(CMAKE_GENERATOR MATCHES "^Visual Studio " AND CMAKE_GENERATOR_PLATFORM)
  # Borrowing from:
  # https://github.com/google/XNNPACK/blob/2eb43787bfad4a99bdb613111cea8bc5a82f390d/CMakeLists.txt#L50
  set(_IREE_UNNORMALIZED_ARCH "${CMAKE_GENERATOR_PLATFORM}")
else()
  set(_IREE_UNNORMALIZED_ARCH "${CMAKE_SYSTEM_PROCESSOR}")
endif()

string(TOLOWER "${_IREE_UNNORMALIZED_ARCH}" _IREE_UNNORMALIZED_ARCH_LOWERCASE)

# Normalize _IREE_UNNORMALIZED_ARCH into IREE_ARCH.
if(EMSCRIPTEN)
  # TODO: figure what to do about the wasm target, which masquerades as x86.
  # This is the one case where the IREE_ARCH CMake variable is currently
  # inconsistent with the IREE_ARCH C preprocessor token.
  set(IREE_ARCH "")
elseif((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "aarch64") OR
        (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64") OR
        (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64e") OR
        (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64ec"))
  set(IREE_ARCH "arm_64")
elseif((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm") OR
        (_IREE_UNNORMALIZED_ARCH_LOWERCASE MATCHES "^armv[5-8]"))
  set(IREE_ARCH "arm_32")
elseif((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x86_64") OR
        (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "amd64") OR
        (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x64"))
  set(IREE_ARCH "x86_64")
elseif((_IREE_UNNORMALIZED_ARCH_LOWERCASE MATCHES "^i[3-7]86$") OR
        (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x86") OR
        (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "win32"))
  set(IREE_ARCH "x86_32")
elseif(_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "riscv64")
  set(IREE_ARCH "riscv_64")
elseif(_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "riscv32")
  set(IREE_ARCH "riscv_32")
elseif(_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "")
  set(IREE_ARCH "")
  message(WARNING "Performance advisory: architecture-specific code paths "
    "disabled because no target architecture was specified or we didn't know "
    "which CMake variable to read. Some relevant CMake variables:\n"
    "CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}\n"
    "CMAKE_GENERATOR=${CMAKE_GENERATOR}\n"
    "CMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}\n"
    "CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}\n"
    )
else()
  set(IREE_ARCH "")
  message(SEND_ERROR "Unrecognized target architecture ${_IREE_UNNORMALIZED_ARCH_LOWERCASE}")
endif()

# iree_arch_to_llvm_arch()
#
# Helper mapping an architecture in IREE's naming scheme (as in IREE_ARCH)
# to an architecture in LLVM's naming scheme (as in LLVM target triples).
function(iree_arch_to_llvm_arch DST_LLVM_ARCH_VARIABLE SRC_ARCH)
  if("${SRC_ARCH}" STREQUAL "arm_64")
    set(${DST_LLVM_ARCH_VARIABLE} "aarch64" PARENT_SCOPE)
  elseif("${SRC_ARCH}" STREQUAL "arm_32")
    set(${DST_LLVM_ARCH_VARIABLE} "arm" PARENT_SCOPE)
  elseif("${SRC_ARCH}" STREQUAL "x86_64")
    set(${DST_LLVM_ARCH_VARIABLE} "x86_64" PARENT_SCOPE)
  elseif("${SRC_ARCH}" STREQUAL "x86_32")
    set(${DST_LLVM_ARCH_VARIABLE} "i386" PARENT_SCOPE)
  elseif("${SRC_ARCH}" STREQUAL "riscv_64")
    set(${DST_LLVM_ARCH_VARIABLE} "riscv64" PARENT_SCOPE)
  elseif("${SRC_ARCH}" STREQUAL "riscv_32")
    set(${DST_LLVM_ARCH_VARIABLE} "riscv32" PARENT_SCOPE)
  elseif("${SRC_ARCH}" STREQUAL "wasm_64")
    set(${DST_LLVM_ARCH_VARIABLE} "wasm64" PARENT_SCOPE)
  elseif("${SRC_ARCH}" STREQUAL "wasm_32")
    set(${DST_LLVM_ARCH_VARIABLE} "wasm32" PARENT_SCOPE)
  else()
    message(SEND_ERROR "What is the LLVM name of the architecture that we call ${SRC_ARCH} ?")
    set(${DST_LLVM_ARCH_VARIABLE} "unknown" PARENT_SCOPE)
  endif()
endfunction()

# iree_arch_to_llvm_target()
#
# Helper mapping an architecture in IREE's naming scheme (as in IREE_ARCH)
# to a LLVM CPU target (as in LLVM_TARGETS_TO_BUILD, the CMake variable).
function(iree_arch_to_llvm_target DST_LLVM_TARGET_VARIABLE SRC_ARCH)
  if("${SRC_ARCH}" STREQUAL "arm_64")
    set(${DST_LLVM_TARGET_VARIABLE} "AArch64" PARENT_SCOPE)
  elseif("${SRC_ARCH}" STREQUAL "arm_32")
    set(${DST_LLVM_TARGET_VARIABLE} "ARM" PARENT_SCOPE)
  elseif("${SRC_ARCH}" MATCHES "^x86_")
    set(${DST_LLVM_TARGET_VARIABLE} "X86" PARENT_SCOPE)
  elseif("${SRC_ARCH}" MATCHES "^riscv_")
    set(${DST_LLVM_TARGET_VARIABLE} "RISCV" PARENT_SCOPE)
  elseif("${SRC_ARCH}" MATCHES "^wasm_")
    set(${DST_LLVM_TARGET_VARIABLE} "WebAssembly" PARENT_SCOPE)
  else()
    message(SEND_ERROR "What is the LLVM target handling of the architecture that we call ${SRC_ARCH} ?")
    set(${DST_LLVM_TARGET_VARIABLE} "" PARENT_SCOPE)
  endif()
endfunction()

# iree_compiler_targeting_iree_arch
#
# Helper returning true if we are building the IREE compiler with the llvm-cpu
# backend enabled and with the LLVM target supporting the CPU architecture
# give in IREE's naming scheme (as in IREE_ARCH).
function(iree_compiler_targeting_iree_arch DST_VAR SRC_ARCH)
  if (NOT IREE_BUILD_COMPILER OR NOT IREE_TARGET_BACKEND_LLVM_CPU)
    set(${DST_VAR} OFF PARENT_SCOPE)
    return()
  endif()

  iree_arch_to_llvm_target(_LLVM_TARGET "${SRC_ARCH}")
  # WebAssembly is unconditionally enabled, and not enumerated in LLVM_TARGETS_TO_BUILD.
  if (_LLVM_TARGET IN_LIST LLVM_TARGETS_TO_BUILD OR _LLVM_TARGET STREQUAL "WebAssembly")
    set(${DST_VAR} ON PARENT_SCOPE)
  else()
    set(${DST_VAR} OFF PARENT_SCOPE)
  endif()
endfunction()

#-------------------------------------------------------------------------------
# General utilities
#-------------------------------------------------------------------------------

# iree_to_bool
#
# Sets `variable` to `ON` if `value` is true and `OFF` otherwise.
function(iree_to_bool VARIABLE VALUE)
  if(VALUE)
    set(${VARIABLE} "ON" PARENT_SCOPE)
  else()
    set(${VARIABLE} "OFF" PARENT_SCOPE)
  endif()
endfunction()

# iree_append_list_to_string
#
# Joins ${ARGN} together as a string separated by " " and appends it to
# ${VARIABLE}.
function(iree_append_list_to_string VARIABLE)
  if(NOT "${ARGN}" STREQUAL "")
    string(JOIN " " _ARGN_STR ${ARGN})
    set(${VARIABLE} "${${VARIABLE}} ${_ARGN_STR}" PARENT_SCOPE)
  endif()
endfunction()


#-------------------------------------------------------------------------------
# Packages and Paths
#-------------------------------------------------------------------------------

# Performs a variety of setup tasks for a directory that forms the root
# of a C source tree. Many of our build macros use directory-scoped CMake
# variables to drive default behavior, and this sets those up in a consolidated
# way.
# Arguments:
# DEFAULT_EXPORT_SET:
#   The export set to use by default. If linking any static libraries
#   that are to be installed as dev libraries, then this is mandatory
#   (or each target must specify it). Typically this must be set in
#   runtime directories.
# DEFAULT_INSTALL_COMPONENT:
#   The default install component for libraries.
# IMPLICIT_DEFS_TARGET:
#   A new target to create and export/install which includes the current
#   source and binary directory as an include dir. It will be added to
#   every cc library created after this in this directory tree.
# IMPLICIT_DEFS_INSTALL_COMPONENT:
#   Install component for *just* the implicit defs target.
# IMPLICIT_DEFS_EXPORT_SET:
#   Export set for *just* the implicit defs target.
# PACKAGE_ROOT_PREFIX:
#   Explicitly set the package root prefix (as something like "iree::foobar").
#   Default is empty.
# See runtime/src/CMakeLists.txt for typical usage in a directory tree
# that installs static dev libraries.
#
# See compiler/src/CMakeLists.txt for typical usage that does not install
# static dev libraries.
function(iree_setup_c_src_root)
  cmake_parse_arguments(
    _RULE
    ""
    "PACKAGE_ROOT_PREFIX;DEFAULT_EXPORT_SET;DEFAULT_INSTALL_COMPONENT;IMPLICIT_DEFS_TARGET;IMPLICIT_DEFS_INSTALL_COMPONENT;IMPLICIT_DEFS_EXPORT_SET"
    ""
    ${ARGN}
  )

  # Make C++ library package names start here unless if told not to.
  set(IREE_PACKAGE_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE)
  set(IREE_PACKAGE_ROOT_PREFIX "${_RULE_PACKAGE_ROOT_PREFIX}" PARENT_SCOPE)

  # Instruct install support that headers are installable from this root
  # directory.
  set(IREE_HDRS_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE)

  # Export and install by default.
  if(_RULE_DEFAULT_EXPORT_SET)
    set(IREE_INSTALL_LIBRARY_TARGETS_DEFAULT_EXPORT_SET
      "${_RULE_DEFAULT_EXPORT_SET}"
      PARENT_SCOPE)
  endif()
  if(_RULE_DEFAULT_INSTALL_COMPONENT)
    set(IREE_INSTALL_LIBRARY_TARGETS_DEFAULT_COMPONENT
      "${_RULE_DEFAULT_INSTALL_COMPONENT}"
      PARENT_SCOPE)
  endif()

  # Tell tablegen to include from here.
  set(IREE_COMPILER_TABLEGEN_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE)

  # Create an implicit defs target that adds this include directory.
  if(_RULE_IMPLICIT_DEFS_TARGET)
    add_library(${_RULE_IMPLICIT_DEFS_TARGET} INTERFACE)
    target_include_directories(${_RULE_IMPLICIT_DEFS_TARGET}
      INTERFACE
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
      $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
    )
    if(NOT _RULE_IMPLICIT_DEFS_INSTALL_COMPONENT)
      set(_RULE_IMPLICIT_DEFS_INSTALL_COMPONENT ${_RULE_DEFAULT_INSTALL_COMPONENT})
    endif()
    if(NOT _RULE_IMPLICIT_DEFS_EXPORT_SET)
      set(_RULE_IMPLICIT_DEFS_EXPORT_SET ${_RULE_DEFAULT_EXPORT_SET})
    endif()
    iree_install_targets(
      TARGETS ${_RULE_IMPLICIT_DEFS_TARGET}
      COMPONENT "${_RULE_IMPLICIT_DEFS_INSTALL_COMPONENT}"
      EXPORT_SET "${_RULE_IMPLICIT_DEFS_EXPORT_SET}"
    )

    # Include this target in all cc_libraries.
    set(IREE_IMPLICIT_DEFS_CC_DEPS ${_RULE_IMPLICIT_DEFS_TARGET} PARENT_SCOPE)
  endif()
endfunction()

# Sets ${PACKAGE_NS} to the IREE-root relative package name in C++ namespace
# format (::).
#
# Examples:
#   compiler/src/iree/compiler/Utils/CMakeLists.txt -> iree::compiler::Utils
#   runtime/src/iree/base/CMakeLists.txt -> iree::base
#   tests/e2e/CMakeLists.txt -> iree::tests::e2e
function(iree_package_ns PACKAGE_NS)
  if(DEFINED IREE_PACKAGE_ROOT_DIR)
    # If an enclosing package root dir is set, then the package is just the
    # relative part after that.
    cmake_path(RELATIVE_PATH CMAKE_CURRENT_LIST_DIR
      BASE_DIRECTORY "${IREE_PACKAGE_ROOT_DIR}"
      OUTPUT_VARIABLE _PACKAGE)
    if(_PACKAGE STREQUAL ".")
      set(_PACKAGE "")
    endif()
    if(IREE_PACKAGE_ROOT_PREFIX)
      if("${_PACKAGE}" STREQUAL "")
        set(_PACKAGE "${IREE_PACKAGE_ROOT_PREFIX}")
      else()
        set(_PACKAGE "${IREE_PACKAGE_ROOT_PREFIX}/${_PACKAGE}")
      endif()
    endif()
  else()
    # Get the relative path of the current dir (i.e. runtime/src/iree/vm).
    string(REPLACE ${IREE_ROOT_DIR} "" _IREE_RELATIVE_PATH ${CMAKE_CURRENT_LIST_DIR})
    string(SUBSTRING ${_IREE_RELATIVE_PATH} 1 -1 _IREE_RELATIVE_PATH)

    if(NOT ${CMAKE_CURRENT_LIST_DIR} MATCHES "^${IREE_ROOT_DIR}/.*")
      # Function is being called from outside IREE. Use the source-relative path.
      # Please check the README.md to see the potential risk.
      string(REPLACE ${PROJECT_SOURCE_DIR} "" _SOURCE_RELATIVE_PATH ${CMAKE_CURRENT_LIST_DIR})
      string(SUBSTRING ${_SOURCE_RELATIVE_PATH} 1 -1 _SOURCE_RELATIVE_PATH)
      set(_PACKAGE "${_SOURCE_RELATIVE_PATH}")

    # If changing the directory/package mapping rules, please also implement
    # the corresponding rule in:
    #   build_tools/bazel_to_cmake/bazel_to_cmake_targets.py
    # Some sub-trees form their own roots for package purposes. Rewrite them.
    else()
      message(SEND_ERROR "iree_package_ns(): Could not determine package for ${CMAKE_CURRENT_LIST_DIR}")
      set(_PACKAGE "iree/unknown")
    endif()
  endif()

  string(REPLACE "/" "::" _PACKAGE_NS "${_PACKAGE}")

  if(_DEBUG_IREE_PACKAGE_NAME)
    message(STATUS "iree_package_ns(): map ${CMAKE_CURRENT_LIST_DIR} -> ${_PACKAGE_NS}")
  endif()

  set(${PACKAGE_NS} ${_PACKAGE_NS} PARENT_SCOPE)
endfunction()

# Sets ${PACKAGE_NAME} to the IREE-root relative package name.
#
# Example when called from iree/base/CMakeLists.txt:
#   iree_base
function(iree_package_name PACKAGE_NAME)
  iree_package_ns(_PACKAGE_NS)
  string(REPLACE "::" "_" _PACKAGE_NAME "${_PACKAGE_NS}")
  set(${PACKAGE_NAME} ${_PACKAGE_NAME} PARENT_SCOPE)
endfunction()

# Sets ${PACKAGE_PATH} to the IREE-root relative package path.
#
# Example when called from iree/base/CMakeLists.txt:
#   iree/base
function(iree_package_path PACKAGE_PATH)
  iree_package_ns(_PACKAGE_NS)
  string(REPLACE "::" "/" _PACKAGE_PATH ${_PACKAGE_NS})
  set(${PACKAGE_PATH} ${_PACKAGE_PATH} PARENT_SCOPE)
endfunction()

# Sets ${PACKAGE_DIR} to the directory name of the current package.
#
# Example when called from iree/base/CMakeLists.txt:
#   base
function(iree_package_dir PACKAGE_DIR)
  iree_package_ns(_PACKAGE_NS)
  string(FIND "${_PACKAGE_NS}" "::" _END_OFFSET REVERSE)
  math(EXPR _END_OFFSET "${_END_OFFSET} + 2")
  string(SUBSTRING ${_PACKAGE_NS} ${_END_OFFSET} -1 _PACKAGE_DIR)
  set(${PACKAGE_DIR} ${_PACKAGE_DIR} PARENT_SCOPE)
endfunction()

#-------------------------------------------------------------------------------
# select()-like Evaluation
#-------------------------------------------------------------------------------

# Appends ${OPTS} with a list of values based on the current compiler.
#
# Example:
#   iree_select_compiler_opts(COPTS
#     CLANG
#       "-Wno-foo"
#       "-Wno-bar"
#     CLANG_CL
#       "/W3"
#     GCC
#       "-Wsome-old-flag"
#     MSVC
#       "/W3"
#   )
#
# Note that variables are allowed, making it possible to share options between
# different compiler targets.
function(iree_select_compiler_opts OPTS)
  cmake_parse_arguments(
    PARSE_ARGV 1
    _IREE_SELECTS
    ""
    ""
    "ALL;CLANG;CLANG_GTE_10;CLANG_GTE_12;CLANG_CL;MSVC;GCC;GCC_GTE_13;CLANG_OR_GCC;MSVC_OR_CLANG_CL"
  )
  # OPTS is a variable containing the *name* of the variable being populated, so
  # we need to dereference it twice.
  set(_OPTS "${${OPTS}}")
  list(APPEND _OPTS "${_IREE_SELECTS_ALL}")
  if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
    list(APPEND _OPTS "${_IREE_SELECTS_GCC}")
    list(APPEND _OPTS "${_IREE_SELECTS_CLANG_OR_GCC}")
    if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13)
      list(APPEND _OPTS ${_IREE_SELECTS_GCC_GTE_13})
    endif()
  elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    if(MSVC)
      list(APPEND _OPTS ${_IREE_SELECTS_CLANG_CL})
      list(APPEND _OPTS ${_IREE_SELECTS_MSVC_OR_CLANG_CL})
    else()
      list(APPEND _OPTS ${_IREE_SELECTS_CLANG})
      if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
        list(APPEND _OPTS ${_IREE_SELECTS_CLANG_GTE_10})
      endif()
      if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
        list(APPEND _OPTS ${_IREE_SELECTS_CLANG_GTE_12})
      endif()
      list(APPEND _OPTS ${_IREE_SELECTS_CLANG_OR_GCC})
    endif()
  elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
    list(APPEND _OPTS ${_IREE_SELECTS_MSVC})
    list(APPEND _OPTS ${_IREE_SELECTS_MSVC_OR_CLANG_CL})
  else()
    message(ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER}")
    list(APPEND _OPTS "")
  endif()
  set(${OPTS} ${_OPTS} PARENT_SCOPE)
endfunction()

#-------------------------------------------------------------------------------
# Data dependencies
#-------------------------------------------------------------------------------

# Adds 'data' dependencies to a target.
#
# Parameters:
# NAME: name of the target to add data dependencies to
# DATA: List of targets and/or files in the source tree (relative to the
# project root).
function(iree_add_data_dependencies)
  cmake_parse_arguments(
    _RULE
    ""
    "NAME"
    "DATA"
    ${ARGN}
  )

  if(NOT _RULE_DATA)
    return()
  endif()

  foreach(_DATA_LABEL ${_RULE_DATA})
    if(TARGET ${_DATA_LABEL})
      add_dependencies(${_RULE_NAME} ${_DATA_LABEL})
    else()
      # Not a target, assume to be a file instead.
      set(_FILE_PATH ${_DATA_LABEL})

      # Create a target which copies the data file into the build directory.
      # If this file is included in multiple rules, only create the target once.
      string(REPLACE "::" "_" _DATA_TARGET ${_DATA_LABEL})
      string(REPLACE "/" "_" _DATA_TARGET ${_DATA_TARGET})
      if(NOT TARGET ${_DATA_TARGET})
        set(_INPUT_PATH "${PROJECT_SOURCE_DIR}/${_FILE_PATH}")
        set(_OUTPUT_PATH "${PROJECT_BINARY_DIR}/${_FILE_PATH}")
        add_custom_target(${_DATA_TARGET}
          COMMAND ${CMAKE_COMMAND} -E copy ${_INPUT_PATH} ${_OUTPUT_PATH}
        )
      endif()

      add_dependencies(${_RULE_NAME} ${_DATA_TARGET})
    endif()
  endforeach()
endfunction()

#-------------------------------------------------------------------------------
# iree_make_empty_file
#-------------------------------------------------------------------------------

# Creates an empty file by copying an in-tree empty file. Unlike `file(WRITE)`
# or `file(TOUCH)`, this does not update the timestamp every time CMake is run,
# avoiding unnecessary rebuilds when the empty file is used as a rule input.
function(iree_make_empty_file _FILENAME)
  configure_file("${PROJECT_SOURCE_DIR}/build_tools/cmake/empty_file" "${_FILENAME}" COPYONLY)
endfunction()

#-------------------------------------------------------------------------------
# Emscripten
#-------------------------------------------------------------------------------

# A global counter to guarantee unique names for js library files.
set(_LINK_JS_COUNTER 1)

# Links a JavaScript library to a target using --js-library=file.js.
#
# This function is only supported when running under Emscripten (emcmake).
# This implementation is forked from `em_add_tracked_link_flag()` in
# https://github.com/emscripten-core/emscripten/blob/main/cmake/Modules/Platform/Emscripten.cmake
# with changes to be compatible with IREE project style and CMake conventions.
#
# Parameters:
# TARGET: Name of the target to link against
# SRCS: List of JavaScript source files to link
function(iree_link_js_library)
  cmake_parse_arguments(
    _RULE
    ""
    "TARGET"
    "SRCS"
    ${ARGN}
  )

  # Convert from aliased, possibly package-relative, names to target names.
  iree_package_ns(_PACKAGE_NS)
  string(REGEX REPLACE "^::" "${_PACKAGE_NS}::" _RULE_TARGET ${_RULE_TARGET})
  string(REPLACE "::" "_" _RULE_TARGET ${_RULE_TARGET})

  foreach(_SRC_FILE ${_RULE_SRCS})
    # If the JS file is changed, we want to relink dependent binaries, but
    # unfortunately it is not possible to make a link step depend directly on a
    # source file. Instead, we must make a dummy no-op build target on that
    # source file, and make the original target depend on that dummy target.

    # Sanitate the source .js filename to a good dummy filename.
    get_filename_component(_JS_NAME "${_SRC_FILE}" NAME)
    string(REGEX REPLACE "[/:\\\\.\ ]" "_" _DUMMY_JS_TARGET ${_JS_NAME})
    set(_DUMMY_LIB_NAME ${_RULE_TARGET}_${_LINK_JS_COUNTER}_${_DUMMY_JS_TARGET})
    set(_DUMMY_C_NAME "${CMAKE_BINARY_DIR}/${_DUMMY_JS_TARGET}_tracker.c")

    # Create a new static library target that with a single dummy .c file.
    add_library(${_DUMMY_LIB_NAME} STATIC ${_DUMMY_C_NAME})
    # Make the dummy .c file depend on the .js file we are linking, so that if
    # the .js file is edited, the dummy .c file, and hence the static library
    # will be rebuild (no-op). This causes the main application to be
    # relinked, which is what we want. This approach was recommended by
    # http://www.cmake.org/pipermail/cmake/2010-May/037206.html
    add_custom_command(
      OUTPUT ${_DUMMY_C_NAME}
      COMMAND ${CMAKE_COMMAND} -E touch ${_DUMMY_C_NAME}
      DEPENDS ${_SRC_FILE}
    )
    target_link_libraries(${_RULE_TARGET}
      PUBLIC
        ${_DUMMY_LIB_NAME}
    )

    iree_install_targets(
      TARGETS ${_DUMMY_LIB_NAME}
    )

    # Link the js-library to the target.
    # When a linked library starts with a "-" cmake will just add it to the
    # linker command line as it is. The advantage of doing it this way is
    # that the js-library will also be automatically linked to targets that
    # depend on this target.
    get_filename_component(_SRC_ABSOLUTE_PATH "${_SRC_FILE}" ABSOLUTE)
    target_link_libraries(${_RULE_TARGET}
      PUBLIC
        "--js-library \"${_SRC_ABSOLUTE_PATH}\""
    )

    math(EXPR _LINK_JS_COUNTER "${_LINK_JS_COUNTER} + 1")
  endforeach()
endfunction()

#-------------------------------------------------------------------------------
# Tool symlinks
#-------------------------------------------------------------------------------

# iree_symlink_tool
#
# Adds a command to TARGET which symlinks a tool from elsewhere
# (FROM_TOOL_TARGET_NAME) to a local file name (TO_EXE_NAME) in the current
# binary directory.
#
# Parameters:
#   TARGET: Local target to which to add the symlink command (i.e. an
#     iree_py_library, etc).
#   FROM_TOOL_TARGET: Target of the tool executable that is the source of the
#     link.
#   TO_EXE_NAME: The executable name to output in the current binary dir.
function(iree_symlink_tool)
  cmake_parse_arguments(
    _RULE
    ""
    "TARGET;FROM_TOOL_TARGET;TO_EXE_NAME"
    ""
    ${ARGN}
  )

  # Transform TARGET
  iree_package_ns(_PACKAGE_NS)
  iree_package_name(_PACKAGE_NAME)
  set(_TARGET "${_PACKAGE_NAME}_${_RULE_TARGET}")
  set(_FROM_TOOL_TARGET ${_RULE_FROM_TOOL_TARGET})
  set(_TO_TOOL_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_RULE_TO_EXE_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
  get_filename_component(_TO_TOOL_DIR "${_TO_TOOL_PATH}" DIRECTORY)

  add_custom_command(
    TARGET "${_TARGET}"
    POST_BUILD
    BYPRODUCTS
      "${CMAKE_CURRENT_BINARY_DIR}/${_RULE_TO_EXE_NAME}${CMAKE_EXECUTABLE_SUFFIX}"
    COMMAND
      ${CMAKE_COMMAND} -E make_directory "${_TO_TOOL_DIR}"
    COMMAND
      ${CMAKE_COMMAND} -E create_symlink
        "$<TARGET_FILE:${_FROM_TOOL_TARGET}>"
        "${_TO_TOOL_PATH}"
  )
endfunction()


#-------------------------------------------------------------------------------
# Tests
#-------------------------------------------------------------------------------

# iree_check_defined
#
# A lightweight way to check that all the given variables are defined. Useful
# in cases like checking that a function has been passed all required arguments.
# Doesn't give usage-specific error messages, but still significantly better
# than no error checking.
# Variable names should be passed directly without quoting or dereferencing.
# Example:
#   iree_check_defined(_SOME_VAR _AND_ANOTHER_VAR)
macro(iree_check_defined)
  foreach(_VAR ${ARGN})
    if(NOT DEFINED "${_VAR}")
      message(SEND_ERROR "${_VAR} is not defined")
    endif()
  endforeach()
endmacro()

# iree_validate_required_arguments
#
# Validates that no arguments went unparsed or were given no values and that all
# required arguments have values. Expects to be called after
# cmake_parse_arguments and verifies that the variables it creates have been
# populated as appropriate.
function(iree_validate_required_arguments
         PREFIX
         REQUIRED_ONE_VALUE_KEYWORDS
         REQUIRED_MULTI_VALUE_KEYWORDS)
  if(DEFINED ${PREFIX}_UNPARSED_ARGUMENTS)
    message(SEND_ERROR "Unparsed argument(s): '${${PREFIX}_UNPARSED_ARGUMENTS}'")
  endif()
  if(DEFINED ${PREFIX}_KEYWORDS_MISSING_VALUES)
    message(SEND_ERROR
            "No values for field(s) '${${PREFIX}_KEYWORDS_MISSING_VALUES}'")
  endif()

  foreach(_KEYWORD IN LISTS REQUIRED_ONE_VALUE_KEYWORDS REQUIRED_MULTI_VALUE_KEYWORDS)
    if(NOT DEFINED ${PREFIX}_${_KEYWORD})
      message(SEND_ERROR "Missing required argument ${_KEYWORD}")
    endif()
  endforeach()
endfunction()

# iree_compile_flags_for_patform
#
# Helper function to add necessary compile flags based on platform-specific
# configurations. Note the flags are added for cpu backends only.
function(iree_compile_flags_for_platform OUT_FLAGS IN_FLAGS)
  if(NOT (IN_FLAGS MATCHES "iree-hal-target-backends=llvm-cpu" OR
          IN_FLAGS MATCHES "iree-hal-target-backends=vmvx"))
    set(${OUT_FLAGS} "" PARENT_SCOPE)
    return()
  endif()

  if(ANDROID AND NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
    # Android's CMake toolchain defines some variables that we can use to infer
    # the appropriate target triple from the configured settings:
    # https://developer.android.com/ndk/guides/cmake#android_platform
    #
    # In typical CMake fashion, the various strings are pretty fuzzy and can
    # have multiple values like "latest", "android-25"/"25"/"android-N-MR1".
    #
    # From looking at the toolchain file, ANDROID_PLATFORM_LEVEL seems like it
    # should pretty consistently be just a number we can use for target triple.
    set(_TARGET_TRIPLE "aarch64-none-linux-android${ANDROID_PLATFORM_LEVEL}")
    list(APPEND _FLAGS "--iree-llvmcpu-target-triple=${_TARGET_TRIPLE}")
  endif()

  if(IREE_ARCH STREQUAL "riscv_64" AND
     CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
     NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
    # RV64 Linux crosscompile toolchain can support iree-compile with
    # specific CPU flags. Add the llvm flags to support RV64 RVV codegen if
    # llvm-target-triple is not specified.
    list(APPEND _FLAGS ${RISCV64_TEST_DEFAULT_LLVM_FLAGS})
  elseif(IREE_ARCH STREQUAL "riscv_32" AND
         CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
         NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
    # RV32 Linux crosscompile toolchain can support iree-compile with
    # specific CPU flags. Add the llvm flags to support RV32 RVV codegen if
    # llvm-target-triple is not specified.
    list(APPEND _FLAGS ${RISCV32_TEST_DEFAULT_LLVM_FLAGS})
  endif()

  if(EMSCRIPTEN AND NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
    set(_EMSCRIPTEN_TEST_DEFAULT_FLAGS
      "--iree-llvmcpu-target-triple=wasm32-unknown-emscripten"
    )
    list(APPEND _FLAGS ${_EMSCRIPTEN_TEST_DEFAULT_FLAGS})
  endif()

  set(${OUT_FLAGS} "${_FLAGS}" PARENT_SCOPE)
endfunction()
