cmake_minimum_required(VERSION 3.30)

# Opt into experimental C++ modules dyndep + `import std;` support.
# Required until CMake declares these stable; see CMake docs for the current UUID.
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
set(CMAKE_CXX_MODULE_STD ON)

project(cargoxx LANGUAGES CXX VERSION 0.1.0)

# Phase 0: hand-written CMakeLists.txt. Replaced by generated build/CMakeLists.txt
# at milestone M3 once cargoxx can build itself. See TECH_SPEC.md §15.

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

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

# TECH_SPEC.md §17: -Wall -Wextra -Wpedantic -Wconversion, -Werror in CI.
add_compile_options(-Wall -Wextra -Wpedantic -Wconversion)

option(CARGOXX_WERROR "Treat warnings as errors" OFF)
if(CARGOXX_WERROR)
    add_compile_options(-Werror)
endif()

find_package(SQLite3 REQUIRED)
find_package(reproc REQUIRED)

# ----- cargoxx library: module units + implementation units -----
add_library(cargoxx STATIC)
target_include_directories(cargoxx SYSTEM PRIVATE third_party)
target_sources(cargoxx
    PRIVATE
        src/util/error.cpp
        src/util/semver.cpp
        src/manifest/parser.cpp
        src/manifest/writer.cpp
        src/layout/layout.cpp
        src/lockfile/lockfile.cpp
        src/linkdb/database.cpp
        src/linkdb/overlay.cpp
        src/codegen/flake.cpp
        src/codegen/cmake.cpp
        src/exec/subprocess.cpp
        src/resolver/nixpkgs_probe.cpp
        src/resolver/nix_cmake_scan.cpp
        src/resolver/conan_probe.cpp
        src/resolver/vcpkg_probe.cpp
        src/resolver/verify_link.cpp
        src/resolver/discover.cpp
        src/resolver/search_devbox.cpp
        src/resolver/nixpkgs_git.cpp
        src/resolver/version_resolve.cpp
        src/cli/cmd_new.cpp
        src/cli/cmd_build.cpp
        src/cli/cmd_run.cpp
        src/cli/cmd_test.cpp
        src/cli/cmd_clean.cpp
        src/cli/cmd_add.cpp
        src/cli/cmd_remove.cpp
        src/cli/run.cpp
    PUBLIC
        FILE_SET CXX_MODULES FILES
            src/lib.cppm
            src/util/util.cppm
            src/exec/exec.cppm
            src/manifest/manifest.cppm
            src/lockfile/lockfile.cppm
            src/layout/layout.cppm
            src/linkdb/linkdb.cppm
            src/resolver/resolver.cppm
            src/codegen/codegen.cppm
            src/cli/cli.cppm
)

target_link_libraries(cargoxx PRIVATE SQLite::SQLite3 reproc)

# ----- cargoxx binary -----
add_executable(cargoxx_bin src/main.cpp)
set_target_properties(cargoxx_bin PROPERTIES OUTPUT_NAME cargoxx)
target_link_libraries(cargoxx_bin PRIVATE cargoxx)

# ----- tests -----
option(CARGOXX_BUILD_TESTS "Build cargoxx tests" ON)
if(CARGOXX_BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()
