cmake_minimum_required(VERSION 3.5)

# Set extension name here
set(TARGET_NAME ducklake)

set(EXTENSION_NAME ${TARGET_NAME}_extension)
set(LOADABLE_EXTENSION_NAME ${TARGET_NAME}_loadable_extension)

project(${TARGET_NAME})

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include_directories(src/include)

# Roaring is installed via vcpkg and used for deletion vectors
find_package(roaring CONFIG REQUIRED)
if(TARGET roaring::roaring-headers)
  get_target_property(ROARING_INCLUDE_DIRS roaring::roaring-headers
                      INTERFACE_INCLUDE_DIRECTORIES)
else()
  get_target_property(ROARING_INCLUDE_DIRS roaring::roaring
                      INTERFACE_INCLUDE_DIRECTORIES)
endif()
if(NOT ROARING_INCLUDE_DIRS OR ROARING_INCLUDE_DIRS STREQUAL
                               "ROARING_INCLUDE_DIRS-NOTFOUND")
  set(ROARING_INCLUDE_DIRS "${roaring_DIR}/../../include")
endif()
include_directories(${ROARING_INCLUDE_DIRS})

# Warn when returning unique_ptr<Derived> as unique_ptr<Base> without std::move
# (Clang-specific; GCC does not need an explicit flag for this pattern)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wreturn-std-move)
endif()

# Instruments only the DuckLake sources, DuckDB itself is built as usual
option(DUCKLAKE_COVERAGE
       "Enable clang source-based code coverage instrumentation of DuckLake."
       FALSE)
if(DUCKLAKE_COVERAGE)
  if(NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang$")
    message(
      FATAL_ERROR "DUCKLAKE_COVERAGE=1 requires a clang-compatible compiler")
  endif()
  # Racing threads lose non-atomic increments, making counts negative
  add_compile_options(-fprofile-instr-generate -fcoverage-mapping
                      -fprofile-update=atomic)
endif()

add_subdirectory(src)
set(EXTENSION_SOURCES ${ALL_OBJECT_FILES})

build_static_extension(${TARGET_NAME} ${EXTENSION_SOURCES})
build_loadable_extension(${TARGET_NAME} " " ${EXTENSION_SOURCES})

if(DUCKLAKE_COVERAGE)
  # Every binary that links the instrumented objects needs the profile runtime
  target_link_options(${EXTENSION_NAME} INTERFACE -fprofile-instr-generate)
  target_link_options(${LOADABLE_EXTENSION_NAME} PRIVATE
                      -fprofile-instr-generate)
endif()

if(TARGET roaring::roaring-headers)
  target_link_libraries(${EXTENSION_NAME} roaring::roaring
                        roaring::roaring-headers roaring::roaring-headers-cpp)
  target_link_libraries(${TARGET_NAME}_loadable_extension roaring::roaring
                        roaring::roaring-headers roaring::roaring-headers-cpp)
else()
  target_link_libraries(${EXTENSION_NAME} roaring::roaring)
  target_link_libraries(${TARGET_NAME}_loadable_extension roaring::roaring)
endif()

install(
  TARGETS ${EXTENSION_NAME}
  EXPORT "${DUCKDB_EXPORT_SET}"
  LIBRARY DESTINATION "${INSTALL_LIB_DIR}"
  ARCHIVE DESTINATION "${INSTALL_LIB_DIR}")
