# Copyright (c) 2024 MediaTek Inc.
#
# Licensed under the BSD License (the "License"); you may not use this file
# except in compliance with the License. See the license file in the root
# directory of this source tree for more details.

cmake_minimum_required(VERSION 3.19)
project(mediatek_example)

message(CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH})

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
endif()

# Source root directory for executorch.
if(NOT EXECUTORCH_ROOT)
  set(EXECUTORCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
endif()

include(${EXECUTORCH_ROOT}/tools/cmake/Utils.cmake)
include(${EXECUTORCH_ROOT}/tools/cmake/Codegen.cmake)

if(NOT PYTHON_EXECUTABLE)
  resolve_python_executable()
endif()

set(_common_compile_options -Wno-deprecated-declarations -fPIC)

# Let files say "include <executorch/path/to/header.h>".
set(_common_include_directories
    ${EXECUTORCH_ROOT}/.. ${EXECUTORCH_ROOT}/runtime/core/portable_type/c10
    ${EXECUTORCH_ROOT}/extension/llm/tokenizers/include
    ${EXECUTORCH_ROOT}/extension/llm/tokenizers/third-party/json/single_include
)

#
# The `_<target>_srcs` lists are defined by executorch_load_build_variables.
#
executorch_load_build_variables()

# Find prebuilt libraries. executorch package should contain portable_ops_lib,
# etdump, bundled_program.
find_package(executorch CONFIG REQUIRED)
target_compile_options(executorch INTERFACE -DET_EVENT_TRACER_ENABLED)
find_package(gflags REQUIRED)

link_directories(${EXECUTORCH_ROOT}/cmake-android-out/lib)

if(${ANDROID})
  message("Build MTK Android Examples")

  get_filename_component(
    EXECUTORCH_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE
  )
  set(_mtk_executor_runner__srcs ${_executor_runner__srcs})
  list(TRANSFORM _mtk_executor_runner__srcs PREPEND "${EXECUTORCH_SOURCE_DIR}/")
  list(FILTER _mtk_executor_runner__srcs EXCLUDE REGEX ".*executor_runner.cpp$")
  list(PREPEND _mtk_executor_runner__srcs
       ${CMAKE_CURRENT_LIST_DIR}/executor_runner/mtk_executor_runner.cpp
  )

  add_executable(mtk_executor_runner ${_mtk_executor_runner__srcs})

  target_include_directories(
    mtk_executor_runner
    PUBLIC ${_common_include_directories}
           ${EXECUTORCH_ROOT}/cmake-android-out/third-party/gflags/include
  )

  target_link_libraries(
    mtk_executor_runner
    ${_executor_runner_libs}
    executorch
    neuron_backend
    executorch_core
    extension_evalue_util
    extension_runner_util
    gflags
  )
  target_compile_options(mtk_executor_runner PUBLIC ${_common_compile_options})
  add_compile_definitions(C10_USING_CUSTOM_GENERATED_MACROS)

  set(_mtk_oss_executor_runner__srcs ${_executor_runner__srcs})
  list(TRANSFORM _mtk_oss_executor_runner__srcs
       PREPEND "${EXECUTORCH_SOURCE_DIR}/"
  )
  list(FILTER _mtk_oss_executor_runner__srcs EXCLUDE REGEX
       ".*executor_runner.cpp$"
  )
  list(PREPEND _mtk_oss_executor_runner__srcs
       ${CMAKE_CURRENT_LIST_DIR}/executor_runner/mtk_oss_executor_runner.cpp
  )

  add_executable(mtk_oss_executor_runner ${_mtk_oss_executor_runner__srcs})

  target_include_directories(
    mtk_oss_executor_runner
    PUBLIC ${_common_include_directories}
           ${EXECUTORCH_ROOT}/cmake-android-out/third-party/gflags/include
  )

  target_link_libraries(
    mtk_oss_executor_runner ${_executor_runner_libs} extension_module
    executorch neuron_backend gflags
  )
  target_compile_options(
    mtk_oss_executor_runner PUBLIC ${_common_compile_options}
  )

  set(_mtk_llama_executor_runner__srcs ${_mtk_executor_runner__srcs})
  list(FILTER _mtk_llama_executor_runner__srcs EXCLUDE REGEX
       ".*executor_runner.cpp$"
  )
  list(PREPEND _mtk_llama_executor_runner__srcs
       ${CMAKE_CURRENT_LIST_DIR}/executor_runner/mtk_llama_executor_runner.cpp
  )
  # Build tokenizers library
  set(SUPPORT_REGEX_LOOKAHEAD ON)
  add_subdirectory(
    ${EXECUTORCH_ROOT}/extension/llm/tokenizers
    ${CMAKE_CURRENT_BINARY_DIR}/tokenizers
  )

  # Include directory for neuron headers
  include_directories(
    BEFORE ${_common_include_directories}
    ${CMAKE_CURRENT_SOURCE_DIR}/../../backends/mediatek/runtime/include
  )

  # Build Llama Executor static library
  add_subdirectory(executor_runner/llama_runner)

  # Build Llama Executor Runner
  add_executable(mtk_llama_executor_runner ${_mtk_llama_executor_runner__srcs})

  target_link_libraries(
    mtk_llama_executor_runner ${_executor_runner_libs} neuron_backend gflags
    mtk_llama_executor_lib
  )
  target_sources(
    mtk_llama_executor_runner
    PRIVATE
      ${CMAKE_CURRENT_SOURCE_DIR}/../models/llama/tokenizer/llama_tiktoken.cpp
  )
  target_link_libraries(mtk_llama_executor_runner tokenizers)
  target_compile_options(
    mtk_llama_executor_runner PUBLIC ${_common_compile_options}
  )
endif()
