cmake_minimum_required(VERSION 3.12)
set(CMAKE_CXX_STANDARD 14)

if(ENABLE_PREDICT_ARM64)
  set(TARGS "arm64")
elseif(ENABLE_PREDICT_ARM32)
  set(TARGS "arm32")
else()
  set(TARGS "x86")
endif()
message("TARGET is set to ${TARGS}")

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_SKIP_RPATH TRUE)

if(MSVC)
  message("not support MSVC")
else(MSVC)
  include(CheckCXXCompilerFlag)
  check_cxx_compiler_flag("-std=c++11"    SUPPORT_CXX11)
  if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
    message("Build in Debug mode")
    set(CMAKE_C_FLAGS "-O0 -g -Wall -Werror -fPIC [${CMAKE_C_FLAGS} -rdynamic")
    set(CMAKE_CXX_FLAGS "-O0 -g -Wall -Werror -fPIC -std=c++11 ${CMAKE_CXX_FLAGS} -rdynamic")
  else()
    set(CMAKE_C_FLAGS "-D_FORTIFY_SOURCE=2 -O2 -fno-rtti -fvisibility=hidden -Wall -Werror -fPIC -fstack-protector-strong ${CMAKE_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "-D_FORTIFY_SOURCE=2 -O2 -fno-rtti -fvisibility=hidden -Wall -Werror -fPIC -fstack-protector-strong -std=c++11 ${CMAKE_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,relro,-z,now -Wl,-z,noexecstack")
  endif ()
  if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND
      CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
    set(CMAKE_CXX_FLAGS "-Wall -Werror -faligned-new ${CMAKE_CXX_FLAGS}")
  endif()
  if (CODE_COVERAGE)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -fprofile-arcs -ftest-coverage -O0")
  endif()
endif(MSVC)


if("${TARGS}" STREQUAL "x86")
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__x86_64__ -fno-strict-aliasing")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__x86_64__ -fno-strict-aliasing")
endif()


set(PRJ_SRC_DIR "${PROJECT_SOURCE_DIR}")
set(PRJ_KLIB_DIR "${PROJECT_SOURCE_DIR}")
set(PRJ_LITE_DIR "${PROJECT_SOURCE_DIR}/lite")

# include directories
message("current PRJ DIR: ${PROJECT_SOURCE_DIR}")
message("current SUB_PRJ DIR: ${PRJ_SRC_DIR}")
message("current KLIB DIR: ${PRJ_KLIB_DIR}")
message("current PRJ_LITE_DIR: ${PRJ_LITE_DIR}")
message("CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}")
set(DMLC_CORE "${TVM_BUILD_SOURCE}/3rdparty/dmlc-core")
set(DLPACK "${TVM_BUILD_SOURCE}/3rdparty/dlpack")
set(PREDICT "${PRJ_SRC_DIR}/../../")
set(SECUREC "${PRJ_SRC_DIR}/../../../third_party/securec")
message("include dir: ${DLPACK}/include")
include_directories(${DLPACK}/include)
include_directories(${DMLC_CORE}/include)
include_directories(${TVM_BUILD_SOURCE}/include)
include_directories(${TVM_BUILD_SOURCE}/src/pass)
include_directories(${PRJ_LITE_DIR})
include_directories(${PRJ_LITE_DIR}/include)
include_directories(${PRJ_LITE_DIR}/../../..)
include_directories(${PRJ_LITE_DIR}/../../../include)
include_directories(${PRJ_LITE_DIR}/../../../src/runtime)
include_directories(${PRJ_LITE_DIR}/../../../common)
include_directories(${SECUREC})
message("SECUREC: " "${SECUREC}/build/src")
include_directories(${PREDICT})
include_directories(${PREDICT}/src)
include_directories(${PRJ_SRC_DIR}/../../../third_party/flatbuffers/include)
include_directories(${PRJ_SRC_DIR}/../../../third_party)
# Source file lists
file(GLOB_RECURSE TVM_KERNEL_SRC
    src/api/*.cc
    src/tflite/TFLite_Detection_PostProcess.cc)

set (TVM_RUNTIME_FLG $ENV{TVM_RUNTIME_ON})
if ("${TVM_RUNTIME_FLG}" STREQUAL "true")
  message("Using TVM runtime function")
  file(GLOB TVM_RUNTIME_SRCS
      ${TVM_ROOT}/apps/howto_deploy/tvm_runtime_pack.cc)
else()
  message("Using LITE runtime function")
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLITE_RUNTIME_ON -DTVM_RUNTIME_HEADER_ONLY -DLITE_THREAD_POOL_SHARED")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLITE_RUNTIME_ON -DTVM_RUNTIME_HEADER_ONLY -DLITE_THREAD_POOL_SHARED")
  file(GLOB_RECURSE TVM_RUNTIME_SRCS
       ${PREDICT}/src/runtime/*.cc)
endif()

if("${TARGS}" STREQUAL "arm32" OR "${TARGS}" STREQUAL "arm64")
    set(CMAKE_SKIP_BUILD_RPATH TRUE)
    set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
    set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif()

set(LIB_X86_PATH "${PRJ_KLIB_DIR}/build/lib_x86")
set(LIB_ARM64_PATH "${PRJ_KLIB_DIR}/build/lib_arm64")
set(LIB_ARM32_PATH "${PRJ_KLIB_DIR}/build/lib_arm32")
if("${TARGS}" STREQUAL "x86")
  set(KLIBS_PATH "${LIB_X86_PATH}")
elseif("${TARGS}" STREQUAL "arm64")
  set(KLIBS_PATH "${LIB_ARM64_PATH}")
elseif("${TARGS}" STREQUAL "arm32")
  set(KLIBS_PATH "${LIB_ARM32_PATH}")
else()
  message(ERROR " not suport ${TARGS}")
endif()

file(GLOB_RECURSE KERNEL_LIBS "${KLIBS_PATH}/*.o")
message("KERNEL_PATH= ${KLIBS_PATH}")

add_compile_options(-DTVM_CUDA_RUNTIM=0)
add_compile_options(-DTVM_METAL_RUNTIM=0)
add_compile_options(-DTVM_OPENCL_RUNTIM=0)

link_directories(${KLIBS_PATH})

add_library(tvm_runtime_pack STATIC ${TVM_RUNTIME_SRCS})
add_library(kernel_manager STATIC ${TVM_KERNEL_SRC})
add_library(tvm_kernel_static STATIC ${TVM_KERNEL_SRC} ${KERNEL_LIBS})
add_library(tvm_kernel SHARED ${TVM_KERNEL_SRC} ${KERNEL_LIBS})
set_target_properties(tvm_kernel PROPERTIES LINK_FLAGS "-Wl,-z,relro,-z,now -Wl,-z,noexecstack")

set(KERNEL_LD_LIB tvm_runtime_pack dl)

if("${TARGS}" STREQUAL "x86")
    set(KERNEL_LD_LIB ${KERNEL_LD_LIB} pthread)
else()
    set(ANDROID_ALLOW_UNDEFINED_SYMBOLS TRUE)
endif()

target_link_libraries(tvm_kernel ${KERNEL_LD_LIB} libsecurec.a)
target_link_libraries(tvm_kernel_static OBJECT tvm_runtime_pack libsecurec.a)

add_dependencies(tvm_kernel securec)
