cmake_minimum_required(VERSION 3.15)
project(verda_ecc LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()

include(ExternalProject)

# ---- Vendored IT++ built static via its OWN CMake ----
# IT++'s 2018-era CMake assumes it is the top-level project (uses CMAKE_BINARY_DIR
# for generated config.h), so add_subdirectory() is fragile. Building it through
# ExternalProject mirrors the known-good recipe and yields a self-contained static
# libitpp_static.a (no external libitpp, no patchelf).
set(ITPP_INSTALL "${CMAKE_CURRENT_BINARY_DIR}/itpp-install")
set(ITPP_STATIC_LIB "${ITPP_INSTALL}/lib/libitpp_static.a")

ExternalProject_Add(itpp_ext
  SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/itpp"
  PREFIX     "${CMAKE_CURRENT_BINARY_DIR}/itpp-ep"
  CMAKE_ARGS
    -DCMAKE_INSTALL_PREFIX=${ITPP_INSTALL}
    -DITPP_SHARED_LIB=OFF
    -DHTML_DOCS=OFF
    -DOLD_TESTS=OFF
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON
    -DCMAKE_BUILD_TYPE=Release
    # IT++'s cmake_minimum_required predates 3.5; newer CMake (manylinux) needs this
    -DCMAKE_POLICY_VERSION_MINIMUM=3.5
  BUILD_BYPRODUCTS "${ITPP_STATIC_LIB}"
)
# ensure the include dir exists at configure time (populated by itpp_ext install)
file(MAKE_DIRECTORY "${ITPP_INSTALL}/include")

# ---- pybind11 ----
set(PYBIND11_FINDPYTHON ON)
find_package(pybind11 CONFIG REQUIRED)

# Transitive libs IT++ pulls in (from `itpp-config --libs`): FFTW3 + LAPACK + BLAS.
set(ITPP_DEPS fftw3 lapack blas)

function(add_ecc_module name)
  pybind11_add_module(${name} ${ARGN})
  add_dependencies(${name} itpp_ext)
  target_include_directories(${name} PRIVATE
    "${ITPP_INSTALL}/include" "${CMAKE_CURRENT_SOURCE_DIR}/src")
  # order matters: itpp static archive before the libs it references
  target_link_libraries(${name} PRIVATE "${ITPP_STATIC_LIB}" ${ITPP_DEPS})
  install(TARGETS ${name} LIBRARY DESTINATION verda_ecc)
endfunction()

add_ecc_module(reed_solomon src/ReedSolomonWrapper.cpp src/customCRC.cpp)
add_ecc_module(bch src/BCHWrapper.cpp)
add_ecc_module(conv_code src/ConvolutionCodesWrapper.cpp)
