# ============================================================================
#  libradar-tunnel.so  —  radar-app 自有隧道内核
#
#  上游:  hev-socks5-tunnel  (heiher/hev-socks5-tunnel, MIT)
#         + hev-socks5-core / hev-task-system / lwip / yaml  (vendored 源码)
#  JNI :  radar_tunnel_jni.c  ->  com.xay.radar.core.NativeTunnel
#
#  APK 里不再有任何预编译的 libhev-socks5-tunnel.so；
#  所有第三方源码都在 app/src/main/cpp/vendor/ 下直接参与编译。
#
#  源文件清单由 tools/gen_sources.py 生成到 generated_sources.cmake，
#  改成显式列表就不用 GLOB（Windows 反斜杠路径下 list(FILTER REGEX)
#  会静默失效，而且同名文件容易被重复编进来）。
# ============================================================================
cmake_minimum_required(VERSION 3.18.1)

project(radar-tunnel C)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

set(CPP_DIR    ${CMAKE_CURRENT_LIST_DIR})
set(VENDOR_DIR ${CPP_DIR}/vendor)

set(HEV_DIR    ${VENDOR_DIR}/hev-socks5-tunnel)
set(TASK_DIR   ${VENDOR_DIR}/hev-task-system)
set(LWIP_DIR   ${VENDOR_DIR}/lwip)
set(YAML_DIR   ${VENDOR_DIR}/yaml)

# ------------------------------------------------------------- 编译/link 参数
set(RADAR_COMMON_FLAGS ${CMAKE_C_FLAGS})
set(RADAR_COMMON_FLAGS "${RADAR_COMMON_FLAGS} -fPIC -Wall -Wno-unused-function -Wno-unused-variable")
set(RADAR_COMMON_FLAGS "${RADAR_COMMON_FLAGS} -DCOMMIT_ID=\\\"radar-tunnel\\\"")
set(RADAR_COMMON_FLAGS "${RADAR_COMMON_FLAGS} -DFD_SET_DEFINED -DSOCKLEN_T_DEFINED")

if(ANDROID_ABI STREQUAL "armeabi-v7a")
    set(RADAR_COMMON_FLAGS "${RADAR_COMMON_FLAGS} -mfpu=neon -mfloat-abi=softfp")
endif()

# 上游 Android.mk 的 -Wl,-z,max-page-size=16384 / -Wl,-z,common-page-size=16384。
# 必须写成独立的列表元素：写成 "a b" 一个字符串时 CMake 会把它们拼成一个参数
# （末尾多出一个裸 "-Wl"），ld.lld 会报 "invalid max-page-size"。
set(RADAR_LINK_FLAGS
    "-Wl,-z,max-page-size=16384"
    "-Wl,-z,common-page-size=16384")

set(CMAKE_C_FLAGS ${RADAR_COMMON_FLAGS})
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")

# ------------------------------------------------------------- 源文件清单
include(${CPP_DIR}/generated_sources.cmake)

# hev-task-system 的上下文切换是汇编实现的（src/kern/task/hev-task-execute.S，
# 内部按 __aarch64__ / __arm__ / __x86_64__ 等宏 include 对应的 .s）。
# 只 project(... C) 的话 CMake 不认 .S，会静默丢掉这个文件，
# 链接期就变成 undefined symbol: hev_task_execute。这里显式开 ASM 语言。
enable_language(ASM)
set_source_files_properties(
    "${CPP_DIR}/vendor/hev-task-system/src/kern/task/hev-task-execute.S"
    PROPERTIES LANGUAGE ASM)

# ------------------------------------------------------------------ 目标
add_library(radar-tunnel SHARED
    radar_tunnel_jni.c
    ${RADAR_SRC_CORE}
    ${RADAR_SRC_TUNNEL}
    ${RADAR_SRC_TASK}
    ${RADAR_SRC_LWIP}
    ${RADAR_SRC_YAML}
)

target_include_directories(radar-tunnel PRIVATE
    ${CPP_DIR}
    # 桥接头：把 <hev-memory-allocator.h> 指到 mem/api 那一份，
    # 见 hev-shim/hev-memory-allocator.h 里的说明
    ${CPP_DIR}/hev-shim
    ${HEV_DIR}/include
    ${HEV_DIR}/src
    ${HEV_DIR}/src/misc
    ${HEV_DIR}/src/core/include
    ${HEV_DIR}/src/core/src
    ${TASK_DIR}/include
    ${TASK_DIR}/src
    # hev-socks5-core / hev-task-system 内部会互相包含对方的私有头
    # （例如 hev-task-io.h、hev-object-atomic.h），所以把 src 下相关子目录
    # 也摊平加进来。上游 Android.mk 只列了 src/include，那套是给 ndk-build
    # 分模块编译用的；这里按实际 include 关系补全。
    ${TASK_DIR}/src/arch
    ${TASK_DIR}/src/kern/aide
    ${TASK_DIR}/src/kern/core
    ${TASK_DIR}/src/kern/io
    ${TASK_DIR}/src/kern/itc
    ${TASK_DIR}/src/kern/sync
    ${TASK_DIR}/src/kern/task
    ${TASK_DIR}/src/kern/time
    ${TASK_DIR}/src/lib/dns
    ${TASK_DIR}/src/lib/io/basic
    ${TASK_DIR}/src/lib/io/buffer
    ${TASK_DIR}/src/lib/io/pipe
    ${TASK_DIR}/src/lib/io/poll
    ${TASK_DIR}/src/lib/io/socket
    ${TASK_DIR}/src/lib/list
    ${TASK_DIR}/src/lib/misc
    ${TASK_DIR}/src/lib/object
    ${TASK_DIR}/src/lib/rbtree
    ${TASK_DIR}/src/mem/api
    ${TASK_DIR}/src/mem/base
    ${TASK_DIR}/src/mem/simple
    ${TASK_DIR}/src/mem/slice
    ${YAML_DIR}/include
    ${YAML_DIR}/src
    ${LWIP_DIR}/src/include
    ${LWIP_DIR}/src/ports/include
)

target_compile_definitions(radar-tunnel PRIVATE
    ENABLE_LIBRARY
    # ---- yaml (configs.mk) ----
    YAML_VERSION_MAJOR=0
    YAML_VERSION_MINOR=2
    YAML_VERSION_PATCH=5
    YAML_VERSION_STRING="0.2.5"
    # ---- hev-task-system (configs.mk) ----
    ENABLE_STACK_OVERFLOW_DETECTION
    ENABLE_MEMALLOC_SLICE
    ENABLE_IO_SPLICE_SYSCALL
    CONFIG_STACK_BACKEND=STACK_MMAP
    CONFIG_STACK_OVERFLOW_DETECTION=1
    CONFIG_MEMALLOC_SLICE_ALIGN=16
    CONFIG_MEMALLOC_SLICE_MAX_SIZE=4096
    CONFIG_MEMALLOC_SLICE_MAX_COUNT=1000
    CONFIG_SCHED_CLOCK=CLOCK_NONE
)

set_target_properties(radar-tunnel PROPERTIES
    C_VISIBILITY_PRESET default
    POSITION_INDEPENDENT_CODE ON
    OUTPUT_NAME "radar-tunnel"
    PREFIX "lib"
)

target_link_options(radar-tunnel PRIVATE ${RADAR_LINK_FLAGS})
target_link_libraries(radar-tunnel PRIVATE log)

install(TARGETS radar-tunnel LIBRARY DESTINATION lib/${ANDROID_ABI})
