# ============================================================================
# F133 iot SDK 交叉编译（整合进 mod_pace）。
#
# 关键：本工程 lwip 是按「melis 单一 libc（stdc.h 屏蔽 newlib）」环境改的，凡是
# 经 xc_log.h -> tc_hal_platform_inc.h 拉入 lwip 的 SDK 代码，只能在该环境编译，
# 否则 lwip 头会与 newlib 的 <sys/select.h>/<fcntl.h> 冲突（_types_fd_set / fcntl）。
#
# 因此按「是否碰 xc_log.h / lwip」拆成两个目标：
#   1) tc_iot_thirdparty —— 纯第三方库(mbedtls/cJSON/jansson/coreHTTP/coreMQTT/faac/
#      libhelix，cs=1 时含 libtcmov)，不碰 xc_log/lwip，用干净 newlib 环境编。
#   2) tc_iot_sdk        —— SDK 核心(base/hal/iot/trtc/xc_iot_mqtt)，强制 -include 真正的
#      mod_pace/Platform.h（-> Window.h -> stdc.h 抢先屏蔽 newlib，等同 pace.mod 环境）。
#   libopus 仍是 third_party.cmake 里的独立目标(newlib)，由 build_iot_lib.sh 一并合并。
# ============================================================================
cmake_minimum_required(VERSION 3.13)

set(TrtcSDK_TARGET "TrtcSDK" CACHE STRING "TrtcSDK target 名" FORCE)
set(ImSDK_TARGET   "ImSDK"   CACHE STRING "ImSDK target 名"   FORCE)

project(tc_iot_sdk_f133 C ASM)

if(NOT ROOT_DIR)
  get_filename_component(ROOT_DIR
      "${CMAKE_CURRENT_LIST_DIR}/../../../../../../../.." ABSOLUTE)
endif()

if(NOT MOD_PACE_DIR)
  get_filename_component(MOD_PACE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
endif()

message(STATUS "[f133] ROOT_DIR      = ${ROOT_DIR}")
message(STATUS "[f133] MELIS_BASE    = ${MELIS_BASE}")
message(STATUS "[f133] MOD_PACE_DIR  = ${MOD_PACE_DIR}")

# ---- SDK 功能默认值（可由 build_iot_lib.sh 的 -D 参数覆盖）----
set(USE_TRTC_C ON  CACHE BOOL "" FORCE)   # 纯 C 版 TRTC，无需 liteav .so
set(BUILD_IOT              1 CACHE STRING "")
set(BUILD_IOT_AITALK       1 CACHE STRING "")
set(BUILD_IOT_AV           0 CACHE STRING "")
set(BUILD_IOT_CLOUD_STORAGE 0 CACHE STRING "")
set(BUILD_OPUS             1 CACHE STRING "")
set(BUILD_IM               0 CACHE STRING "" FORCE)
if(NOT DEFINED FILE_SYSTEM_DISABLED)
  set(FILE_SYSTEM_DISABLED 0 CACHE STRING "" FORCE)   # F133 有 DFS 文件系统
endif()
if(NOT DEFINED KVSTORE_IO_INTERVAL)
  set(KVSTORE_IO_INTERVAL 0 CACHE STRING "" FORCE)
endif()

include(${ROOT_DIR}/config.cmake)
include(${ROOT_DIR}/src/base/base.cmake)
include(${ROOT_DIR}/src/third_party/third_party.cmake)
include(${ROOT_DIR}/src/iot/iot.cmake)
# AITalk includes TRTC sources itself, but AV without AITalk also needs trtc_*.
if((BUILD_TRTC AND USE_TRTC_C) OR NOT BUILD_IOT)
  include(${ROOT_DIR}/src/trtc/trtc.cmake)
endif()

# ---------------------------------------------------------------------------
# 第三方 include：SDK 核心只要公开 API 头；PRIVATE 路径（尤其 opus/src/silk）
# 绝不能进 tc_iot_sdk —— silk/typedef.h 会盖住 Melis 的 <typedef.h>，
# stdc.h -> libc.h 随即因 size_t / __u8 / __size 未定义而整片报错。
# ---------------------------------------------------------------------------
set(IOT_SDK_THIRDPARTY_INCLUDES
    ${ROOT_DIR}
    ${ROOT_DIR}/src/third_party/cJSON
    ${ROOT_DIR}/src/third_party/jansson/src
    ${ROOT_DIR}/src/third_party/jansson/private_include
    ${ROOT_DIR}/src/third_party/coreHTTP/source/include
    ${ROOT_DIR}/src/third_party/coreHTTP/source/interface
    ${ROOT_DIR}/src/third_party/coreHTTP/source/dependency/3rdparty/llhttp/include
    ${ROOT_DIR}/src/third_party/coreMQTT/source/include
    ${ROOT_DIR}/src/third_party/coreMQTT/source/interface
    ${ROOT_DIR}/src/third_party/mbedtls/include
    ${ROOT_DIR}/src/third_party/opus/src/include
    ${ROOT_DIR}/src/third_party/opus          # opus_rename_defines.h（勿加 src/silk，会盖 Melis typedef.h）
    ${ROOT_DIR}/src/third_party/faac/include
    ${ROOT_DIR}/src/third_party/arduino-libhelix/src/
    ${ROOT_DIR}/src/third_party/nanopb
    ${ROOT_DIR}/src/third_party/sonic
    ${ROOT_DIR}/src/third_party/g722
)
if(OPUS_INCLUDE_DIRS_PUBLIC)
  list(APPEND IOT_SDK_THIRDPARTY_INCLUDES ${OPUS_INCLUDE_DIRS_PUBLIC})
endif()

# thirdparty 目标仍用完整路径（含 opus PRIVATE / faac 内部），它不 -include Platform.h。
set(IOT_THIRDPARTY_INCLUDES
    ${IOT_SDK_THIRDPARTY_INCLUDES}
    ${ROOT_DIR}/src/third_party/opus
    ${ROOT_DIR}/src/third_party/opus/src
    ${ROOT_DIR}/src/third_party/faac/libfaac
    ${ROOT_DIR}/src/third_party/arduino-libhelix/src/libhelix-aac
    ${THIRD_PARTY_INC}
)

set(IOT_SDK_INCLUDES
    ${ROOT_DIR}
    ${ROOT_DIR}/src/api/iot
    ${ROOT_DIR}/src/base
    ${ROOT_DIR}/src/base/hal
    ${ROOT_DIR}/src/api/trtc
)

# ===========================================================================
# 目标 1：第三方库（纯 newlib 干净环境，不 -include Platform.h、不加 mod_pace 根）
# ===========================================================================
set(TC_IOT_THIRDPARTY_SRC
    ${THIRD_PARTY_SRC}
    ${ROOT_DIR}/src/third_party/cJSON/cJSON.c
    ${FAAC_SRC}
    ${LIBHELIX_SRC}
)
add_library(tc_iot_thirdparty STATIC ${TC_IOT_THIRDPARTY_SRC})
target_include_directories(tc_iot_thirdparty PRIVATE ${IOT_THIRDPARTY_INCLUDES})
target_compile_definitions(tc_iot_thirdparty PRIVATE
    MQTT_DO_NOT_USE_CUSTOM_CONFIG HTTP_DO_NOT_USE_CUSTOM_CONFIG
    FILE_SYSTEM_DISABLED=${FILE_SYSTEM_DISABLED} KVSTORE_IO_INTERVAL=${KVSTORE_IO_INTERVAL}
    ${LIBHELIX_COMPILE_DEFS}
    ${LIBTCMOV_DEFS}
)

# ===========================================================================
# 目标 2：SDK 核心（melis libc 环境，等同 pace.mod）
#   - 强制 -include 真正的 mod_pace/Platform.h：它经 Window.h -> stdc.h 抢先
#     #define _STDIO_H_/_SYS_FCNTL_H_ 等，屏蔽 newlib 头，从根上消除 lwip <-> newlib
#     的 _types_fd_set / fcntl 冲突（与 socket.c 编过的机制完全一致）。
#   - 加入 mod_pace 根目录（提供 Platform.h/Window.h/stdc.h）与 iotlib/shim
#     （补 newlib 与工程 lwip 都没有的 <netinet/tcp.h>/<sys/ioctl.h>，转发到 lwip）。
# ===========================================================================
if(BUILD_IOT)
  set(TC_IOT_SDK_SRC ${BASE_SRC} ${XC_IOT_MQTT_SRC} ${TC_IOT_SDK_SRC})
  if(BUILD_TRTC AND USE_TRTC_C)
    list(APPEND TC_IOT_SDK_SRC ${TRTC_SDK_SRC})
  endif()
else()
  # Standalone TRTC delivery must not pull any IoT MQTT / data-model objects.
  set(TC_IOT_SDK_SRC ${TRTC_SDK_SRC})
endif()
# AITalk 生命周期封装由 mod_pace/aitalk/aitalk_demo.c 编译进 pace.mod，
# 不放入 SDK 静态库，客户修改该源码后重编模块即可生效。
# TRTC/aitalk 的 TRTC_SDK_SRC 里夹带了 ${THIRD_PARTY_SRC}(jansson/mbedtls/nanopb/sonic/zlib/g722)。
# 第三方库必须只在干净 newlib 的 tc_iot_thirdparty 目标编译；本 SDK 目标是 -include Platform.h
# 的 melis-libc 屏蔽环境，若编 jansson 会因 <stdio.h> 被屏蔽而缺 EOF/fgetc/ssize_t 等报错。
# 故从 SDK 源清单中剔除第三方源（它们的符号由 tc_iot_thirdparty 提供，最终 ar 合并为一个 .a）。
# 注：mbedtls/library/net_sockets.c 经 mqtt.cmake 单独加入 XC_IOT_MQTT_SRC，不在 THIRD_PARTY_SRC 中，
# 不会被误删，仍在 SDK 目标编译（用 lwip socket，可在屏蔽环境编）。
if(THIRD_PARTY_SRC)
  list(REMOVE_ITEM TC_IOT_SDK_SRC ${THIRD_PARTY_SRC})
endif()
list(REMOVE_DUPLICATES TC_IOT_SDK_SRC)   # 去掉 BASE_SRC 被 TRTC_SDK_SRC 重复带入的项
add_library(tc_iot_sdk STATIC ${TC_IOT_SDK_SRC})
target_include_directories(tc_iot_sdk PRIVATE
    ${MELIS_BASE}/include/melis           # <typedef.h> 必须先于任何第三方同名头
    ${MOD_PACE_DIR}                       # Platform.h / Window.h / stdc.h
    ${MOD_PACE_DIR}/fdk-aac/libAACenc/include
    ${MOD_PACE_DIR}/fdk-aac/libAACdec/include
    ${MOD_PACE_DIR}/fdk-aac/libSYS/include
    ${CMAKE_CURRENT_LIST_DIR}/shim        # netinet/tcp.h、sys/ioctl.h -> lwip/sockets.h
    ${ROOT_DIR}/src/demo/iot_aitalk_demo  # AITalk 共享头目录
    ${IOT_SDK_INCLUDES}
    ${IOT_SDK_THIRDPARTY_INCLUDES}        # 仅公开 API 头，不含 opus silk/
)
# 强制先包含真正的 Platform.h（-> stdc.h 屏蔽 newlib），必须早于任何 <stdio.h>。
# 必须用 "SHELL:" 前缀把 `-include <path>` 当作不可拆分、不被去重的整体，否则会与
# 工具链里 kconfig.h 的 `-include` 撞车被 CMake 去重，导致 Platform.h 变成裸输入文件
# （gcc 报 "cannot specify -o with -c ... with multiple files"）。
target_compile_options(tc_iot_sdk PRIVATE
    "SHELL:-include ${MOD_PACE_DIR}/Platform.h"
    -ffast-math
)
target_compile_definitions(tc_iot_sdk PRIVATE
    PLATFORM_ALLWINNER
    F133_USE_FDK_AAC=1
    MQTT_DO_NOT_USE_CUSTOM_CONFIG HTTP_DO_NOT_USE_CUSTOM_CONFIG
    FILE_SYSTEM_DISABLED=${FILE_SYSTEM_DISABLED} KVSTORE_IO_INTERVAL=${KVSTORE_IO_INTERVAL}
    EPDK_DEBUG_LEVEL=EPDK_DEBUG_LEVEL_LOG_ALL USED_BY_INIT
    ${LIBHELIX_COMPILE_DEFS}
    ${LIBTCMOV_DEFS}
)
