cmake_minimum_required(VERSION 3.30)

project(pyaeron LANGUAGES C CXX)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif ()

find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)

# Build Aeron's C client + C media driver only.
set(BUILD_AERON_DRIVER ON CACHE BOOL "" FORCE)
set(BUILD_AERON_ARCHIVE_API OFF CACHE BOOL "" FORCE)
set(AERON_TESTS OFF CACHE BOOL "" FORCE)
set(AERON_UNIT_TESTS OFF CACHE BOOL "" FORCE)
set(AERON_SYSTEM_TESTS OFF CACHE BOOL "" FORCE)
set(AERON_SLOW_SYSTEM_TESTS OFF CACHE BOOL "" FORCE)
set(AERON_BUILD_SAMPLES OFF CACHE BOOL "" FORCE)
set(AERON_BUILD_DOCUMENTATION OFF CACHE BOOL "" FORCE)
set(AERON_INSTALL_TARGETS OFF CACHE BOOL "" FORCE)

set(AERON_SRC "${CMAKE_CURRENT_SOURCE_DIR}/third_party/aeron")
if (NOT EXISTS "${AERON_SRC}/CMakeLists.txt")
    message(FATAL_ERROR
        "Aeron sources not found at ${AERON_SRC}. "
        "Clone https://github.com/aeron-io/aeron.git into third_party/aeron "
        "(git submodule update --init --recursive).")
endif ()

add_subdirectory("${AERON_SRC}" "${CMAKE_CURRENT_BINARY_DIR}/aeron" EXCLUDE_FROM_ALL)

python_add_library(_pyaeron MODULE
    src/_pyaeron/pyaeron.c
    src/_pyaeron/exceptions.c
    src/_pyaeron/offer.c
    src/_pyaeron/buffer.c
    src/_pyaeron/idle.c
    src/_pyaeron/util.c
    src/_pyaeron/context.c
    src/_pyaeron/driver.c
    src/_pyaeron/client.c
    src/_pyaeron/publication.c
    src/_pyaeron/subscription.c
    WITH_SOABI)

target_include_directories(_pyaeron PRIVATE
    "${CMAKE_CURRENT_SOURCE_DIR}/src/_pyaeron")

# aeron_driver_static already contains the C client sources and exports
# both aeronc.h and aeronmd.h include paths.
target_link_libraries(_pyaeron PRIVATE aeron_driver_static)

if (NOT MSVC)
    # Static Aeron loads idle-strategy symbols via dlsym.
    target_link_options(_pyaeron PRIVATE -rdynamic)
endif ()

if (UNIX AND NOT APPLE)
    target_link_libraries(_pyaeron PRIVATE m ${CMAKE_DL_LIBS})
endif ()

install(TARGETS _pyaeron DESTINATION pyaeron)

# Local RPC latency binary (not installed). Same Aeron static lib as the
# Python extension so C vs Python compares the same C client + driver.
add_executable(rpc_bench benchmarks/rpc_bench.c)
target_link_libraries(rpc_bench PRIVATE aeron_driver_static)
if (NOT MSVC)
    target_link_options(rpc_bench PRIVATE -rdynamic)
endif ()
if (UNIX AND NOT APPLE)
    target_link_libraries(rpc_bench PRIVATE m ${CMAKE_DL_LIBS})
endif ()
set_target_properties(rpc_bench PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
    OUTPUT_NAME rpc_bench)

