# ============================================================================
# mod_pace 编译入口（已整合 iot SDK 交叉编译）
#
# 本 Makefile 被两种方式解析：
#   第一遍：用户在 mod_pace 目录直接 `make`（此时 $(obj) 为空）。
#           先交叉编译 iot SDK -> libtc_iot_sdk.a（走 iotlib/build_iot_lib.sh），
#           再调用 Melis kbuild 编译 aitalk 并链接 pace.mod。
#   第二遍：Melis kbuild 通过 `make -C $(MELIS_BASE) M=<dir> modules` 把本文件当作
#           模块片段 include（此时 $(obj) 由 scripts/Makefile.build 设置为非空）。
#           使用下方 kbuild 变量（subdir-ccflags-y / pace-objs / usrlibs-y ...）。
# ============================================================================

ifeq ($(obj),)
# =========================== 第一遍：用户 make ===========================

MOD_PACE_DIR := $(CURDIR)
IOTLIB_DIR   := $(MOD_PACE_DIR)/iotlib
PREBUILT_SDK_DIR := $(abspath $(MELIS_BASE)/../../../tc_iot_sdk)
# aitalk/aitalk_demo.c/.h 随 mod_pace 交付，由 kbuild 编译进 pace.mod；
# libtc_iot_sdk.a 只提供底层 IoT API，不包含这份 demo 实现。
# 仓库内构建从 IOT_SRC 引用 iot_demo_config.h；交付包的 Makefile 则改为
# 从 tc_iot_sdk/include 引用该配置头。

ifeq ($(MELIS_BASE),)
$(error 请先在顶层 source 目录执行 `source melis-env.sh` 设置 MELIS_BASE 后再 make)
endif

JOBS := $(shell grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 1)

.PHONY: all iot_sdk_lib mods clean distclean

# 默认目标：先编 iot SDK 静态库，再编 aitalk + 链接 pace.mod
all: mods

# 1) 交叉编译 iot SDK -> 合并成自包含 libtc_iot_sdk.a（放到 aitalk/lib/）
iot_sdk_lib:
	@echo "== [1/2] 使用预编译 tc_iot_sdk -> libtc_iot_sdk.a =="
	@test -f "$(PREBUILT_SDK_DIR)/lib/libtc_iot_sdk.a" || \
		{ echo "ERROR: 找不到预编译 SDK: $(PREBUILT_SDK_DIR)/lib/libtc_iot_sdk.a" >&2; exit 1; }
	@mkdir -p "$(MOD_PACE_DIR)/aitalk/lib"
	@cp "$(PREBUILT_SDK_DIR)/lib/libtc_iot_sdk.a" "$(MOD_PACE_DIR)/aitalk/lib/libtc_iot_sdk.a"

# 2) 编译 aitalk + 链接 pace.mod（Melis kbuild；本文件此时以 $(obj) 非空重新进入）
mods: iot_sdk_lib
	@echo "== [2/2] 编译 aitalk + 链接 pace.mod =="
	$(MAKE) -C $(MELIS_BASE) M=$(MOD_PACE_DIR) modules -j$(JOBS)
	@echo "== 清理 iot SDK 的 cmake build 目录 =="
	@rm -rf iotlib/build

# 清理：模块产物 + iot SDK 的 cmake build 目录 + aitalk/lib
clean:
	$(MAKE) -C $(MELIS_BASE) M=$(MOD_PACE_DIR) clean
	@rm -rf aitalk/lib iotlib/build

distclean: clean

else
# ========================= 第二遍：kbuild 模块片段 =========================

subdir-ccflags-y :=	-I$(srctree)/include/melis/kernel/drivers  \
			-I$(srctree)/include/melis/arch/chip \
			-I$(srctree)/include/melis/module  \
			-I$(srctree)/include/melis/misc    \
			-I$(srctree)/ekernel/drivers/hal/include/hal     \
			-I$(srctree)/ekernel/drivers/rtos-hal/include/hal     \
			-I$(srctree)/include/melis/libs/libc  \
				 -I$(obj)/  \
				 -I$(obj)/lwip/   \
				 -I$(obj)/lwip/compat/posix   \
         \
         \
         -DEPDK_DEBUG_LEVEL=EPDK_DEBUG_LEVEL_LOG_ALL         \
         -DUSED_BY_INIT                      \
				 -fshort-enums                                               \
         $(SOLUTION_INCLUDE) 

# ======================= AITalk (iot) 集成 =======================
# iot SDK 源码根目录（.../iot/src）。本工程位于 iot/platform/f133/source 之下，
# 故相对 $(srctree)(=MELIS_BASE) 上溯三级到 iot/，再进入 src/。
IOT_SDK_DIR := $(srctree)/../../../tc_iot_sdk

# libtc_iot_sdk.a 由 iotlib/build_iot_lib.sh 交叉编译后放到这里（第一遍已生成）。
AITALK_LIB_DIR := $(obj)/aitalk/lib

# tap3a 预编译库（aitalk/3A/lib/libtap3a.a）与 C 头（aitalk/3A/include）。
TAP3A_DIR := $(obj)/aitalk/3A

# 找到与本 ABI(-mabi=lp64d -march=rv64gcxthead)匹配的 newlib libm.a 全路径，
# 供 opus/mbedtls 的浮点数学符号使用（模块最终 ld 不自动带 -lm）。
IOT_CC   := $(srctree)/../toolchain/riscv64-elf-x86_64-20201104/bin/riscv64-unknown-elf-gcc
IOT_LIBM := $(shell $(IOT_CC) -mabi=lp64d -march=rv64gcxthead -print-file-name=libm.a)

subdir-ccflags-y += -I$(obj)/aitalk \
                    -I$(TAP3A_DIR)/include \
                    -I$(obj)/fdk-aac/libAACenc/include \
                    -I$(obj)/fdk-aac/libAACdec/include \
                    -I$(obj)/fdk-aac/libSYS/include \
                    -I$(IOT_SDK_DIR)/include \
                    -I$(srctree)/ekernel/components/avframework/eyesee-mpp/middleware/sun8iw19p1/media/include \
                    -I$(srctree)/ekernel/drivers \
                    -DPLATFORM_ALLWINNER=1 \
                    -DBUILD_OPUS=1 \
					-Wno-error=strict-prototypes

# 所有库放进同一个 --start-group，避免 iot <-> melis libc 相互引用的先后顺序问题。
usrlibs-y +=		-L$(srctree)/${elibrary-libs}/3rd  \
				-L$(obj)/../lib   \
				-L$(obj)/../libex   \
				-L$(AITALK_LIB_DIR)   \
				-L$(TAP3A_DIR)/lib \
				-L$(obj)   \
				--start-group \
				-ltc_iot_sdk \
				-lfdkaac \
				-ltap3a \
				-lsyscall -lminic -lpub0 \
				$(IOT_LIBM) \
				--end-group

MOD_NAME := pace
SUF_NAME := mod
PRJ_PATH := $(srctree)/projects/${TARGET_BOARD}/data/UDISK/mod/
TEMP_PATH := $(srctree)/emodules/bin

SRCCS=$(foreach dir,$(DIRS_ALL),$(wildcard $(dir)/*.c))
SRCSS=$(foreach dir,$(DIRS_ALL),$(wildcard $(dir)/*.s))

OBJSet=$(SRCCS:.c=.o) $(SRCSS:.s=.o)

OBJS = $(patsubst $(obj)/%.o, %.o, $(OBJSet))

$(MOD_NAME)-objs = magic.o
$(MOD_NAME)-objs += mod_pace.o
$(MOD_NAME)-objs += lib_pace.o
$(MOD_NAME)-objs += socket.o
# AITalk 集成源（全部位于 mod_pace/aitalk/ 内）
# 客户可修改此处的 aitalk_demo.c，重新编译模块后生效。
$(MOD_NAME)-objs += aitalk/aitalk_demo.o
# 沿用 F133 demo 的 Melis libc 编译环境，避免混用 newlib 头。
CFLAGS_aitalk_demo.o := -include $(obj)/Platform.h -D_SYS__PTHREADTYPES_H_
$(MOD_NAME)-objs += aitalk/pace_aitalk.o
# $(MOD_NAME)-objs += aitalk/audio_filestream_allwinner.o
$(MOD_NAME)-objs += aitalk/audio_device_allwinner.o
# libtap3a.a 按默认 int 宽 enum 编译；本 TU 的 TapAecConfig 等必须与库 ABI 一致。
# CFLAGS_audio_device_allwinner.o := -fno-short-enums

# audio_device_open 首行调用的 Tap3A WAV 离线测试及其读写依赖。
# $(MOD_NAME)-objs += aitalk/3A_test/tap_emulation_c_case.o
# $(MOD_NAME)-objs += aitalk/3A_test/wavreader.o
# $(MOD_NAME)-objs += aitalk/3A_test/wavwriter.o
# 测试同样传递 TapAecConfig/TapAnsConfig/TapAgcConfig，必须匹配库的 enum ABI。
# CFLAGS_tap_emulation_c_case.o := -fno-short-enums

# iot SDK 的模块 libc 垫片：统一内存到 eLIBs、补齐 newlib syscall、alsa 弱桩
$(MOD_NAME)-objs += aitalk/pace_iot_shim.o

# 仅覆盖当前编入模块的 aitalk 对象；kbuild 将单对象选项放在全局 -Os 后。
CFLAGS_pace_aitalk.o += -O3 -ffast-math
CFLAGS_audio_device_allwinner.o += -O3 -ffast-math
CFLAGS_pace_iot_shim.o += -O3 -ffast-math

# 允许 libsyscall.a 与 newlib libc.a 的 reentrant 实现(_close_r/_xxx_r)重复定义时取先者，
# 消除二者在完整链接下的 "multiple definition" 冲突。
lnkflags-y += --allow-multiple-definition

include $(MELIS_BASE)/scripts/Makefile.mods

endif
