# 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

include(CMakeParseArguments)

# iree_cc_library()
#
# CMake function to imitate Bazel's cc_library rule.
#
# Parameters:
# PACKAGE: Name of the package (overrides actual path)
# NAME: name of target (see Note)
# HDRS: List of public header files for the library
# TEXTUAL_HDRS: List of public header files that cannot be compiled on their own
# SRCS: List of source files for the library
# DATA: List of other targets and files required for this binary
# DEPS: List of other libraries to be linked in to the binary targets
# COPTS: List of private compile options
# DEFINES: List of public defines
# INCLUDES: Include directories to add to dependencies
# LINKOPTS: List of link options
# PUBLIC: Add this so that this library will be exported under iree::
# Also in IDE, target will appear in IREE folder while non PUBLIC will be in IREE/internal.
# TESTONLY: When added, this target will only be built if user passes -DIREE_BUILD_TESTS=ON to CMake.
# SHARED: If set, will compile to a shared object.
# WINDOWS_DEF_FILE: If set, will add a windows .def file to a shared library link
# Note:
# By default, iree_cc_library will always create a library named iree_${NAME},
# and alias target iree::${NAME}. The iree:: form should always be used.
# This is to reduce namespace pollution.
#
# iree_cc_library(
#   NAME
#     awesome
#   HDRS
#     "a.h"
#   SRCS
#     "a.cc"
# )
# iree_cc_library(
#   NAME
#     fantastic_lib
#   SRCS
#     "b.cc"
#   DEPS
#     iree::package::awesome # not "awesome" !
#   PUBLIC
# )
#
# iree_cc_library(
#   NAME
#     main_lib
#   ...
#   DEPS
#     iree::package::fantastic_lib
# )

function(iree_cc_library)
  cmake_parse_arguments(
    _RULE
    "PUBLIC;TESTONLY;SHARED"
    "PACKAGE;NAME;WINDOWS_DEF_FILE"
    "HDRS;TEXTUAL_HDRS;SRCS;COPTS;DEFINES;LINKOPTS;DATA;DEPS;INCLUDES"
    ${ARGN}
  )

  if(_RULE_TESTONLY AND NOT IREE_BUILD_TESTS)
    return()
  endif()

  # Prefix the library with the package name, so we get: iree_package_name.
  if(_RULE_PACKAGE)
    set(_PACKAGE_NS "${_RULE_PACKAGE}")
    string(REPLACE "::" "_" _PACKAGE_NAME ${_RULE_PACKAGE})
  else()
    iree_package_ns(_PACKAGE_NS)
    iree_package_name(_PACKAGE_NAME)
  endif()
  set(_NAME "${_PACKAGE_NAME}_${_RULE_NAME}")
  set(_OBJECTS_NAME ${_NAME}.objects)

  # Replace dependencies passed by ::name with iree::package::name
  list(TRANSFORM _RULE_DEPS REPLACE "^::" "${_PACKAGE_NS}::")

  # Check if this is a header-only library.
  # Note that as of February 2019, many popular OS's (for example, Ubuntu
  # 16.04 LTS) only come with cmake 3.5 by default.  For this reason, we can't
  # use list(FILTER...)
  set(_CC_SRCS "${_RULE_SRCS}")
  foreach(_SRC_FILE IN LISTS _CC_SRCS)
    if(${_SRC_FILE} MATCHES ".*\\.(h|inc)")
      list(REMOVE_ITEM _CC_SRCS "${_SRC_FILE}")
    endif()
  endforeach()
  if("${_CC_SRCS}" STREQUAL "")
    set(_RULE_IS_INTERFACE 1)
  else()
    set(_RULE_IS_INTERFACE 0)
  endif()

  # Wrap user specified INCLUDES in the $<BUILD_INTERFACE:>
  # generator.
  list(TRANSFORM _RULE_INCLUDES PREPEND "$<BUILD_INTERFACE:")
  list(TRANSFORM _RULE_INCLUDES APPEND ">")

  # Implicit deps.
  if(IREE_IMPLICIT_DEFS_CC_DEPS)
    list(APPEND _RULE_DEPS ${IREE_IMPLICIT_DEFS_CC_DEPS})
  endif()

  if(NOT _RULE_IS_INTERFACE)
    add_library(${_OBJECTS_NAME} OBJECT)
    if(_RULE_SHARED)
      add_library(${_NAME} SHARED "$<TARGET_OBJECTS:${_OBJECTS_NAME}>")
      if(_RULE_WINDOWS_DEF_FILE AND WIN32)
        target_sources(${_NAME} PRIVATE "${_RULE_WINDOWS_DEF_FILE}")
      endif()
    else()
      add_library(${_NAME} STATIC "$<TARGET_OBJECTS:${_OBJECTS_NAME}>")
      if(_RULE_WINDOWS_DEF_FILE AND WIN32)
        message(SEND_ERROR "If specifying a .def file library must be shared")
      endif()
    endif()

    # Sources get added to the object library.
    target_sources(${_OBJECTS_NAME}
      PRIVATE
        ${_RULE_SRCS}
        ${_RULE_TEXTUAL_HDRS}
        ${_RULE_HDRS}
    )

    # Keep track of objects transitively in our special property.
    set_property(TARGET ${_NAME} PROPERTY
      INTERFACE_IREE_TRANSITIVE_OBJECTS "$<TARGET_OBJECTS:${_OBJECTS_NAME}>")
    _iree_cc_library_add_object_deps(${_NAME} ${_RULE_DEPS})

    # We define everything else on the regular rule. However, the object
    # library needs compiler definition related properties, so we forward them.
    # We also forward link libraries -- not because the OBJECT libraries do
    # linking but because they get transitive compile definitions from them.
    # Yes. This is state of the art.
    # Note that SYSTEM scope matches here, in the property name and in the
    # include directories below on the main rule. If ever removing this,
    # remove it from all places.
    target_include_directories(${_OBJECTS_NAME} SYSTEM
      PUBLIC
        $<TARGET_PROPERTY:${_NAME},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
    )
    target_include_directories(${_OBJECTS_NAME}
      PUBLIC
        $<TARGET_PROPERTY:${_NAME},INTERFACE_INCLUDE_DIRECTORIES>
    )
    target_compile_options(${_OBJECTS_NAME}
      PRIVATE
        $<TARGET_PROPERTY:${_NAME},COMPILE_OPTIONS>
    )
    target_compile_definitions(${_OBJECTS_NAME}
      PUBLIC
        $<TARGET_PROPERTY:${_NAME},INTERFACE_COMPILE_DEFINITIONS>
    )
    target_link_libraries(${_OBJECTS_NAME}
      PUBLIC
        $<TARGET_PROPERTY:${_NAME},INTERFACE_LINK_LIBRARIES>
    )

    target_include_directories(${_NAME} SYSTEM
      PUBLIC
        "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>"
        "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>"
    )
    target_include_directories(${_NAME}
      PUBLIC
        ${_RULE_INCLUDES}
    )
    target_compile_options(${_NAME}
      PRIVATE
        ${IREE_DEFAULT_COPTS}
        ${_RULE_COPTS}
    )
    target_link_options(${_NAME}
      PRIVATE
        ${IREE_DEFAULT_LINKOPTS}
        ${_RULE_LINKOPTS}
    )
    target_link_libraries(${_NAME}
      PUBLIC
        ${_RULE_DEPS}
    )

    iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA})
    target_compile_definitions(${_NAME}
      PUBLIC
        ${_RULE_DEFINES}
    )

    # Add all IREE targets to a folder in the IDE for organization.
    if(_RULE_PUBLIC)
      set_property(TARGET ${_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER})
      set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER})
    elseif(_RULE_TESTONLY)
      set_property(TARGET ${_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/test)
      set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/test)
    else()
      set_property(TARGET ${_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/internal)
      set_property(TARGET ${_OBJECTS_NAME} PROPERTY FOLDER ${IREE_IDE_FOLDER}/internal)
    endif()

    # INTERFACE libraries can't have the CXX_STANDARD property set so only
    # set here.
    set_property(TARGET ${_OBJECTS_NAME} PROPERTY CXX_STANDARD ${IREE_CXX_STANDARD})
    set_property(TARGET ${_OBJECTS_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
  else()
    # Generating header-only library.
    add_library(${_NAME} INTERFACE)
    target_include_directories(${_NAME} SYSTEM
      INTERFACE
        "$<BUILD_INTERFACE:${IREE_SOURCE_DIR}>"
        "$<BUILD_INTERFACE:${IREE_BINARY_DIR}>"
        ${_RULE_INCLUDES}
    )
    target_link_options(${_NAME}
      INTERFACE
        ${IREE_DEFAULT_LINKOPTS}
        ${_RULE_LINKOPTS}
    )
    target_link_libraries(${_NAME}
      INTERFACE
        ${_RULE_DEPS}
    )
    _iree_cc_library_add_object_deps(${_NAME} ${_RULE_DEPS})
    iree_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA})
    target_compile_definitions(${_NAME}
      INTERFACE
        ${_RULE_DEFINES}
    )
  endif()

  # Alias the iree_package_name library to iree::package::name.
  # This lets us more clearly map to Bazel and makes it possible to
  # disambiguate the underscores in paths vs. the separators.
  add_library(${_PACKAGE_NS}::${_RULE_NAME} ALIAS ${_NAME})

  if(NOT "${_PACKAGE_NS}" STREQUAL "")
    # If the library name matches the final component of the package then treat
    # it as a default. For example, foo/bar/ library 'bar' would end up as
    # 'foo::bar'.
    iree_package_dir(_PACKAGE_DIR)
    if(${_RULE_NAME} STREQUAL ${_PACKAGE_DIR})
      add_library(${_PACKAGE_NS} ALIAS ${_NAME})
    endif()
  endif()
endfunction()

# _iree_cc_library_add_object_deps()
#
# Helper to add deps to an iree_cc_library. This only operates on the unaliased
# raw name (i.e. 'iree_vm_vm'), not aliased names (i.e. 'iree::vm').
#
# This appends to two properties:
#   INTERFACE_IREE_TRANSITIVE_OBJECTS: Transitive list of all objects from
#     this library and all "iree::" prefixed dependent libraries. This will
#     allow you to create mondo objects for any transtive libraries that are
#     part of IREE, but it will not contain outside.
#   INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS: Transitive list of any dependency
#     targets that are not under teh "iree::" namespace but are encountered
#     in the dependency dag.
function(_iree_cc_library_add_object_deps name)
  foreach(_DEP_TARGET ${ARGN})
    if(_DEP_TARGET MATCHES "^iree::")
      set_property(TARGET ${name} APPEND PROPERTY
        INTERFACE_IREE_TRANSITIVE_OBJECTS
        "$<GENEX_EVAL:$<TARGET_PROPERTY:${_DEP_TARGET},INTERFACE_IREE_TRANSITIVE_OBJECTS>>"
      )
      set_property(TARGET ${name} APPEND PROPERTY
      INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS
        "$<GENEX_EVAL:$<TARGET_PROPERTY:${_DEP_TARGET},INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS>>"
      )
    else()
      set_property(TARGET ${name} APPEND PROPERTY
        INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS
        ${_DEP_TARGET}
      )
    endif()
  endforeach()
endfunction()

# iree_cc_unified_library()
#
# Creates a unified library out of the iree:: namespaced transitive deps+self
# of some ROOT library. The resulting library will contain the union of all
# objects from all transitive library-deps in the iree:: namespace. Such
# libraries are typically the only libraries that we install for outside use
# and they must only be used by leaf demos or out of tree libraries/executables.
# Commingling with any regular libraries will result in duplicate symbols.
#
# Note that the resulting library will not contain any libraries outside of the
# iree:: namespace but will be configured to link to them. For external use
# it is expected that they will be installed and used separately as needed.
#
# Compile and link options are forwarded from the ROOT target non-transitively.
# Ensure that this target directly references all definitions that need to
# be exported to end consumers.
#
# Parameters:
# NAME: name of target
# ROOT: Root target library to extract objects and deps from.
function(iree_cc_unified_library)
  cmake_parse_arguments(
    _RULE
    "SHARED"
    "NAME;ROOT"
    ""
    ${ARGN}
  )

  # Replace dependencies passed by ::name with iree::package::name
  iree_package_ns(_PACKAGE_NS)
  list(TRANSFORM _RULE_ROOT 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}_${_RULE_NAME}")

  # Evaluate the object and libs.
  set(_OBJECTS "$<REMOVE_DUPLICATES:$<GENEX_EVAL:$<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_IREE_TRANSITIVE_OBJECTS>>>")
  set(_LIBS "$<REMOVE_DUPLICATES:$<GENEX_EVAL:$<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_IREE_TRANSITIVE_OBJECT_LIBS>>>")

  # For debugging, write out evaluated objects to a file.
  # This cannot be enabled for Xcode given that Xcode does not support
  # per-configuration sources.
  if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
    file(GENERATE OUTPUT "${_RULE_NAME}.$<CONFIG>.contents.txt" CONTENT
      "OBJECTS:\n${_OBJECTS}\n\nLIBS:\n${_LIBS}\n")
  endif()
  if(_RULE_SHARED)
    add_library(${_NAME} SHARED ${_OBJECTS})
  else()
    add_library(${_NAME} STATIC ${_OBJECTS})
  endif()

  target_link_libraries(${_NAME}
    PUBLIC
      ${_LIBS}
  )

  # Forward compile usage requirements from the root library.
  # Note that SYSTEM scope matches here, in the property name and in the
  # include directories below on the main rule. If ever removing this,
  # remove it from all places.
  target_include_directories(${_NAME} SYSTEM
    PUBLIC
      $<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
  )
  target_include_directories(${_NAME}
    PUBLIC
      $<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_INCLUDE_DIRECTORIES>
  )
  target_compile_options(${_NAME}
    PRIVATE
      $<TARGET_PROPERTY:${_RULE_ROOT},COMPILE_OPTIONS>
  )
  target_compile_definitions(${_NAME}
    PUBLIC
      $<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_COMPILE_DEFINITIONS>
  )
  target_link_libraries(${_NAME}
    PUBLIC
      $<TARGET_PROPERTY:${_RULE_ROOT},INTERFACE_LINK_LIBRARIES>
  )

  # Alias the iree_package_name library to iree::package::name.
  # This lets us more clearly map to Bazel and makes it possible to
  # disambiguate the underscores in paths vs. the separators.
  add_library(${_PACKAGE_NS}::${_RULE_NAME} ALIAS ${_NAME})

  # If the library name matches the final component of the package then treat
  # it as a default. For example, foo/bar/ library 'bar' would end up as
  # 'foo::bar'.
  iree_package_dir(_PACKAGE_DIR)
  if(${_RULE_NAME} STREQUAL ${_PACKAGE_DIR})
    add_library(${_PACKAGE_NS} ALIAS ${_NAME})
  endif()
endfunction()
