cmake_minimum_required(VERSION 3.16)

project(ikv VERSION 0.1.0 LANGUAGES C)

include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

option(IKV_BUILD_DEMOS "Build demo executables" ON)
option(IKV_BUILD_TESTS "Build unit tests" OFF)
option(IKV_INSTALL "Install library and CMake package files" ON)

set(IKV_PUBLIC_HEADERS
    include/ikv.h
)

set(IKV_SOURCES
    src/ikv.c
    src/loaders/ikv1.c
    src/loaders/ikv2.c
)

add_library(ikv_obj OBJECT ${IKV_SOURCES})
target_include_directories(ikv_obj
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)
target_compile_features(ikv_obj PUBLIC c_std_99)
set_target_properties(ikv_obj PROPERTIES
    POSITION_INDEPENDENT_CODE ON
)

add_library(ikv STATIC)
add_library(ikv::ikv ALIAS ikv)
target_sources(ikv PRIVATE $<TARGET_OBJECTS:ikv_obj>)
target_include_directories(ikv
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_features(ikv PUBLIC c_std_99)
set_target_properties(ikv PROPERTIES
    OUTPUT_NAME ikv
    PUBLIC_HEADER "${IKV_PUBLIC_HEADERS}"
)

if(IKV_BUILD_DEMOS)
    add_executable(ikv_demo demo/main.c)
    target_link_libraries(ikv_demo PRIVATE ikv)

    add_executable(ikv_unit_test demo/unit_test.c)
    target_link_libraries(ikv_unit_test PRIVATE ikv)
endif()

if(IKV_BUILD_TESTS)
    enable_testing()

    add_executable(ikv_tests
        demo/unit_test.c
        ${IKV_SOURCES}
    )
    target_compile_definitions(ikv_tests PRIVATE IKV_TESTING)
    target_include_directories(ikv_tests
        PRIVATE
            ${CMAKE_CURRENT_SOURCE_DIR}/include
            ${CMAKE_CURRENT_SOURCE_DIR}/src
    )
    target_compile_features(ikv_tests PRIVATE c_std_99)
    add_test(NAME ikv_tests COMMAND ikv_tests)
endif()

if(IKV_INSTALL)
    install(
        TARGETS ikv
        EXPORT ikvTargets
        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
        PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
    )

    install(
        EXPORT ikvTargets
        FILE ikvTargets.cmake
        NAMESPACE ikv::
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ikv
    )

    write_basic_package_version_file(
        "${CMAKE_CURRENT_BINARY_DIR}/ikvConfigVersion.cmake"
        VERSION ${PROJECT_VERSION}
        COMPATIBILITY SameMajorVersion
    )

    configure_package_config_file(
        "${CMAKE_CURRENT_SOURCE_DIR}/cmake/ikvConfig.cmake.in"
        "${CMAKE_CURRENT_BINARY_DIR}/ikvConfig.cmake"
        INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/ikv"
    )

    install(
        FILES
            "${CMAKE_CURRENT_BINARY_DIR}/ikvConfig.cmake"
            "${CMAKE_CURRENT_BINARY_DIR}/ikvConfigVersion.cmake"
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ikv
    )
endif()
