# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

# ExecuTorch runtime as an ESP-IDF component.
#
# GENERATED by examples/espressif/build_idf_component.sh in the ExecuTorch repo
# -- do not edit this tree by hand. Source lists live in et_generated.cmake next
# to this file; the op profile is selected with CONFIG_ET_OP_PROFILE_* in
# Kconfig (no regeneration needed to switch).

include(${CMAKE_CURRENT_LIST_DIR}/et_generated.cmake)

set(_et_requires esp_hw_support esp_system esp_timer log heap)

if(NOT CONFIG_ET_ENABLE)
  # ESP-IDF links every component under components/ into the image, and this
  # component's WHOLE_ARCHIVE registration (below) is deliberately GC-proof. The
  # gate is off by default, so vendoring the component leaves a project's
  # firmware unchanged until CONFIG_ET_ENABLE is set or selected. ESP-IDF's
  # component-requirements scan runs this file before Kconfig is loaded, so it
  # only ever sees this branch; registering the same requirements here keeps
  # those components in the build when the component is enabled. No
  # INCLUDE_DIRS: including <et_model.h> while disabled fails at compile time
  # rather than at link time.
  idf_component_register(PRIV_REQUIRES ${_et_requires})
  return()
endif()

# Pick the Kconfig-selected profile (default: ET_DEFAULT_PROFILE).
set(_et_profile "${ET_DEFAULT_PROFILE}")
foreach(_p IN LISTS ET_PROFILES)
  string(TOUPPER "${_p}" _p_up)
  if(CONFIG_ET_OP_PROFILE_${_p_up})
    set(_et_profile "${_p}")
  endif()
endforeach()
string(TOUPPER "${_et_profile}" _ET_UP)

set(_et_vendored_srcs ${ET_CORE_SRCS} ${ET_PROFILE_SRCS_${_ET_UP}}
                      ${ET_KERNEL_SRCS_${_ET_UP}}
)

# WHOLE_ARCHIVE: kernel registration happens in static initializers in the
# profile's register_kernels.cpp; normal archive extraction would drop that
# translation unit (nothing references its symbols) and every operator would be
# missing at load time. --gc-sections still strips unused runtime and kernel
# code. src/platform/esp_pal.cpp is copied in by the generator from the shared
# examples/espressif/platform/esp_pal.cpp.
idf_component_register(
  SRCS
  ${_et_vendored_srcs}
  "src/et_model.cpp"
  "src/platform/esp_pal.cpp"
  INCLUDE_DIRS
  "include"
  PRIV_REQUIRES
  ${_et_requires}
  WHOLE_ARCHIVE
)

target_compile_features(${COMPONENT_LIB} PUBLIC cxx_std_17)

set(_et_max_kernel_num ${ET_MAX_KERNEL_NUM_${_ET_UP}})
if(CONFIG_ET_MAX_KERNEL_NUM)
  if(CONFIG_ET_MAX_KERNEL_NUM LESS _et_max_kernel_num)
    message(
      FATAL_ERROR
        "CONFIG_ET_MAX_KERNEL_NUM=${CONFIG_ET_MAX_KERNEL_NUM} is below the "
        "${_et_profile} profile's ${_et_max_kernel_num} kernels"
    )
  endif()
  set(_et_max_kernel_num ${CONFIG_ET_MAX_KERNEL_NUM})
endif()

if(CONFIG_ET_PROGRAM_VERIFICATION)
  set(_et_program_verification 1)
else()
  set(_et_program_verification 0)
endif()

# Consumers including <executorch/...> headers need the same c10 macro mode and
# flatbuffers alignment the runtime was built with. __FUNCTION__ instead of
# __builtin_FUNCTION() keeps log function names without full signatures.
target_compile_definitions(
  ${COMPONENT_LIB}
  PUBLIC C10_USING_CUSTOM_GENERATED_MACROS FLATBUFFERS_MAX_ALIGNMENT=1024
         ET_USE_BUILTIN_FUNCTION_NAME=0
  PRIVATE MAX_KERNEL_NUM=${_et_max_kernel_num}
          ET_ENABLE_PROGRAM_VERIFICATION=${_et_program_verification}
)

if(NOT CONFIG_ET_DEBUG_ASSERTS)
  target_compile_definitions(${COMPONENT_LIB} PRIVATE NDEBUG)
endif()

if(CONFIG_ET_OPTIMIZE_SIZE)
  target_compile_options(${COMPONENT_LIB} PRIVATE -Os)
endif()

if(NOT CONFIG_ET_ENABLE_LOGGING)
  target_compile_definitions(${COMPONENT_LIB} PUBLIC ET_LOG_ENABLED=0)
endif()

# ET_MIN_LOG_LEVEL compiles out ET_LOG calls below the floor; ET_ESP_LOG_LEVEL
# applies the same floor in esp_pal.cpp. ExecuTorch has no warning level, so
# WARN keeps only errors.
if(CONFIG_ET_LOG_LEVEL_ERROR)
  set(_et_min_log_level Error)
  set(_et_esp_log_level ESP_LOG_ERROR)
elseif(CONFIG_ET_LOG_LEVEL_WARN)
  set(_et_min_log_level Error)
  set(_et_esp_log_level ESP_LOG_WARN)
elseif(CONFIG_ET_LOG_LEVEL_DEBUG)
  set(_et_min_log_level Debug)
  set(_et_esp_log_level ESP_LOG_DEBUG)
else() # CONFIG_ET_LOG_LEVEL_INFO (default)
  set(_et_min_log_level Info)
  set(_et_esp_log_level ESP_LOG_INFO)
endif()
target_compile_definitions(
  ${COMPONENT_LIB}
  PUBLIC ET_MIN_LOG_LEVEL=${_et_min_log_level}
  PRIVATE ET_ESP_LOG_LEVEL=${_et_esp_log_level}
)

# ESP-IDF builds with warnings-as-errors; upstream ExecuTorch sources are not
# warning-clean under the IDF flag set, so demote for vendored sources only.
set_source_files_properties(
  ${_et_vendored_srcs}
  PROPERTIES
    COMPILE_OPTIONS
    "-Wno-error;-Wno-deprecated-declarations;-Wno-unused-parameter;-Wno-sign-compare;-Wno-unused-variable"
)
