# 3.22 = apt cmake на Ubuntu 22.04 (Jetson/JetPack); фич новее здесь нет.
cmake_minimum_required(VERSION 3.22)
project(gpr_cpp LANGUAGES CXX)   # CXX-only: CUDA компилируется в рантайме через NVRTC

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_FLAGS_RELEASE "-O3")

# bindings/pymodule.cpp не вендорен в radar_system — включение потребует вернуть его из VNA_AlGo
option(GPR_BUILD_PYTHON "Build pybind11 module" OFF)
option(GPR_BUILD_TESTS  "Build C++ parity tests" OFF)
option(GPR_BUILD_EXAMPLES "Build standalone C++ example" ON)

# Python окружение (venv) — источник pybind11 и pip CUDA-библиотек (nvrtc, cudart).
if(NOT DEFINED PYTHON_EXECUTABLE)
  set(PYTHON_EXECUTABLE python3)
endif()

# CUDA include/lib из pip-пакетов nvidia-*; задаются -DGPR_CUDA_INC / -DGPR_CUDA_LIB
# (детект делает build_cmake.sh). Заголовки: nvrtc.h, cuda.h (Driver API).
# GPR_CUDA_INC может быть СПИСКОМ каталогов (через ';'): в раздельных pip-пакетах
# (Jetson: cuda_nvrtc + cuda_runtime) nvrtc.h и cuda.h лежат в разных include/.
if(NOT DEFINED GPR_CUDA_INC OR NOT DEFINED GPR_CUDA_LIB)
  message(FATAL_ERROR "Задайте -DGPR_CUDA_INC=<dir(ы) с nvrtc.h,cuda.h; ';'-список> и -DGPR_CUDA_LIB=<dir с libnvrtc.so*>")
endif()

# libcuda (драйвер) — системный
find_library(CUDA_DRIVER_LIB cuda PATHS /usr/lib/x86_64-linux-gnu /usr/lib/aarch64-linux-gnu
             /usr/lib REQUIRED)
# libnvrtc из pip
find_library(NVRTC_LIB NAMES nvrtc libnvrtc.so.13 libnvrtc.so.12 nvrtc.so
             PATHS ${GPR_CUDA_LIB} REQUIRED NO_DEFAULT_PATH)

# PocketFFT (header-only, vendored)
add_library(pocketfft INTERFACE)
target_include_directories(pocketfft INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/pocketfft)

# --- ядро библиотеки (usable без Python) ---
add_library(gpr_core_cpp STATIC
  src/geometry.cpp
  src/ascan.cpp
  src/device.cpp
  src/nvrtc_kernel.cpp
  src/sar3d.cpp)
target_include_directories(gpr_core_cpp PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/include
  ${GPR_CUDA_INC})
target_link_libraries(gpr_core_cpp PUBLIC pocketfft ${NVRTC_LIB} ${CUDA_DRIVER_LIB})
# rpath на каталог pip libnvrtc — чтобы бинарник/модуль грузились без LD_LIBRARY_PATH
set_target_properties(gpr_core_cpp PROPERTIES POSITION_INDEPENDENT_CODE ON
  BUILD_RPATH "${GPR_CUDA_LIB}" INSTALL_RPATH "${GPR_CUDA_LIB}")

if(GPR_BUILD_PYTHON)
  execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pybind11 --cmakedir
                  OUTPUT_VARIABLE PB11_DIR OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE PB11_RC)
  if(PB11_RC EQUAL 0)
    find_package(pybind11 CONFIG REQUIRED HINTS ${PB11_DIR})
  else()
    find_package(pybind11 CONFIG REQUIRED)
  endif()
  pybind11_add_module(_gpr_cpp bindings/pymodule.cpp)
  target_link_libraries(_gpr_cpp PRIVATE gpr_core_cpp)
  set_target_properties(_gpr_cpp PROPERTIES BUILD_RPATH "${GPR_CUDA_LIB}" INSTALL_RPATH "${GPR_CUDA_LIB}")
endif()

if(GPR_BUILD_TESTS)
  add_executable(gpr_test_parity tests/cpp/test_parity.cpp)
  target_link_libraries(gpr_test_parity PRIVATE gpr_core_cpp)
endif()

if(GPR_BUILD_EXAMPLES)
  add_executable(standalone_bp examples/standalone_bp.cpp)
  target_link_libraries(standalone_bp PRIVATE gpr_core_cpp)
  set_target_properties(standalone_bp PROPERTIES BUILD_RPATH "${GPR_CUDA_LIB}" INSTALL_RPATH "${GPR_CUDA_LIB}")
endif()
