
cmake_minimum_required(VERSION 3.21)
project(EdgeTX)

set(VERSION_MAJOR "3")
set(VERSION_MINOR "0")
set(VERSION_REVISION "0")
set(CODENAME "dev")
string(TIMESTAMP BUILD_YEAR "%Y")

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")

if(MINGW OR WIN32)
  set(CMAKE_OBJECT_PATH_MAX 200)
endif()

if(DEFINED ENV{EDGETX_VERSION_TAG})
  set(VERSION_TAG "$ENV{EDGETX_VERSION_TAG}")
else()
  if(DEFINED ENV{EDGETX_VERSION_PREFIX})
    set(VERSION_PREFIX "$ENV{EDGETX_VERSION_PREFIX}-")
  else()
    set(VERSION_PREFIX "pre-") # Default prefix for when not tagged
  endif()
  if(DEFINED ENV{EDGETX_VERSION_SUFFIX})
    set(VERSION_SUFFIX "-$ENV{EDGETX_VERSION_SUFFIX}")
  else()
    set(VERSION_SUFFIX "-selfbuild") # Default suffix for when not in automated build environments
  endif()
endif()

set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})

option(EdgeTX_SUPERBUILD "Cross-compile EdgeTX for each toolchain" ON)
include(ExternalProject)

# Cache FetchContent downloads in a shared directory so that multiple build
# directories (and rebuilds after a clean) reuse already-fetched dependencies.
# Priority: -D flag > $ENV{FETCHCONTENT_BASE_DIR} > default (.cache/fetchcontent)
if(NOT FETCHCONTENT_BASE_DIR)
  if(DEFINED ENV{FETCHCONTENT_BASE_DIR})
    set(FETCHCONTENT_BASE_DIR "$ENV{FETCHCONTENT_BASE_DIR}" CACHE PATH
        "Shared cache for FetchContent downloads" FORCE)
  else()
    set(FETCHCONTENT_BASE_DIR "${CMAKE_SOURCE_DIR}/.cache/fetchcontent" CACHE PATH
        "Shared cache for FetchContent downloads" FORCE)
  endif()
endif()

if(EdgeTX_SUPERBUILD)
  include(Macros)
  CollectCommandLineArgs(CMAKE_ARGS)
  message("-- CMAKE_ARGS: ${CMAKE_ARGS}")
  message("-- CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")

  # Add explicit targets for triggering cmake in the external projects
  set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure clean)

  # Native targets
  ExternalProject_Add(native
    SOURCE_DIR ${CMAKE_SOURCE_DIR}
    BINARY_DIR ${CMAKE_BINARY_DIR}/native
    LIST_SEPARATOR |
    CMAKE_ARGS ${CMAKE_ARGS} -Wno-dev -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
    CMAKE_CACHE_ARGS
      -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_SOURCE_DIR}/cmake/toolchain/native.cmake
      -DEdgeTX_SUPERBUILD:BOOL=0
      -DNATIVE_BUILD:BOOL=1
      -DFETCHCONTENT_BASE_DIR:PATH=${FETCHCONTENT_BASE_DIR}
    INSTALL_COMMAND  ""
    EXCLUDE_FROM_ALL TRUE
    )

  # ARM targets
  ExternalProject_Add(arm-none-eabi
    SOURCE_DIR ${CMAKE_SOURCE_DIR}
    BINARY_DIR ${CMAKE_BINARY_DIR}/arm-none-eabi
    LIST_SEPARATOR |
    CMAKE_ARGS ${CMAKE_ARGS} -Wno-dev -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
    CMAKE_CACHE_ARGS
      -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_SOURCE_DIR}/cmake/toolchain/arm-none-eabi.cmake
      -DEdgeTX_SUPERBUILD:BOOL=0
      -DNATIVE_BUILD:BOOL=0
      -DFETCHCONTENT_BASE_DIR:PATH=${FETCHCONTENT_BASE_DIR}
    INSTALL_COMMAND  ""
    EXCLUDE_FROM_ALL TRUE
  )

  # Webasm targets — deferred to a separate CMake project so that
  # the WASI SDK is only fetched when wasi-module is actually built.

  add_custom_target(configure
    DEPENDS native-configure arm-none-eabi-configure)

  add_custom_target(simulator
    COMMAND ${CMAKE_COMMAND} --build native --target simulator
    DEPENDS native-configure
  )

  add_custom_target(simu
    COMMAND ${CMAKE_COMMAND} --build native --target simu
    DEPENDS native-configure
  )

  add_custom_target(wasi-module
    COMMAND ${CMAKE_COMMAND}
      -S ${CMAKE_SOURCE_DIR}/cmake/wasm
      -B ${CMAKE_BINARY_DIR}/wasm
      -DEDGETX_SOURCE_DIR=${CMAKE_SOURCE_DIR}
      -DEDGETX_BUILD_TYPE=${CMAKE_BUILD_TYPE}
      -DFETCHCONTENT_BASE_DIR=${FETCHCONTENT_BASE_DIR}
      ${CMAKE_ARGS}
    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/wasm
  )

  add_custom_target(companion
    COMMAND ${CMAKE_COMMAND} --build native --target companion
    DEPENDS native-configure
  )

  add_custom_target(gtests-radio
    COMMAND ${CMAKE_COMMAND} --build native --target gtests-radio
    DEPENDS native-configure
  )

  add_custom_target(tests-radio
    COMMAND ${CMAKE_COMMAND} --build native --target tests-radio
    DEPENDS native-configure
  )

  add_custom_target(bootloader
    COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target bootloader
    DEPENDS arm-none-eabi-configure
  )

  add_custom_target(firmware
    COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target firmware
    DEPENDS arm-none-eabi-configure
  )

  add_custom_target(firmware-size
    COMMAND ${CMAKE_COMMAND} --build arm-none-eabi --target firmware-size
    DEPENDS arm-none-eabi-configure
  )

  # Quit cmake at this point
  return()
endif()

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
include(GenericDefinitions)

if (VERSION_TAG)
  message(STATUS "EdgeTX ${VERSION_TAG} @ ${GIT_STR}")
else()
  message(STATUS "EdgeTX ${VERSION_PREFIX}${VERSION}${VERSION_SUFFIX} @ ${GIT_STR}")
endif()

if(NATIVE_BUILD AND NOT WASI)
  include(NativeTargets)
else()
  # Prevent CMake warnings
  set(IGNORE "${LIBUSB1_ROOT_DIR}" "${OPENSSL_ROOT_DIR}")
endif()

add_subdirectory(${RADIO_SRC_DIR})
