# SPDX-License-Identifier: Apache-2.0
# kernwatch-sbom - free and open-source SBOM generator by Kernwatch (https://kernwatch.com/sbom-generator)
# Copyright 2026 Strandfors Oy (Kernwatch). Licensed under the Apache License 2.0 - see LICENSE.
# kernwatch-sbom - C++17 desktop CLI (mirrors the JavaScript reference in ../js). No third-party
# libraries. rules/rules.json is embedded at build time as a generated header.
#
#   cmake -S cpp -B build -G Ninja -DCMAKE_BUILD_TYPE=Release && ninja -C build
#   cross: -DCMAKE_TOOLCHAIN_FILE=cpp/cmake/zig-toolchain.cmake -DZIG_TARGET=x86_64-linux-musl
cmake_minimum_required(VERSION 3.16)
project(kernwatch_sbom LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE Release)
endif()

option(KWSBOM_STATIC "Link statically where the platform allows it (not on macOS)" ON)
option(KWSBOM_STRIP "Strip symbols from the executable (release packages)" OFF)
set(KWSBOM_SANITIZE "" CACHE STRING "Sanitizers to enable, e.g. address,undefined")

set(RULES_JSON "${CMAKE_CURRENT_SOURCE_DIR}/../rules/rules.json")
set(GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
add_custom_command(
  OUTPUT "${GEN_DIR}/rules_json.h"
  COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}"
  COMMAND ${CMAKE_COMMAND} -DINPUT=${RULES_JSON} -DOUTPUT=${GEN_DIR}/rules_json.h
          -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/embed_rules.cmake"
  DEPENDS "${RULES_JSON}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/embed_rules.cmake"
  COMMENT "Embedding rules/rules.json"
  VERBATIM)

add_executable(kernwatch-sbom
  src/main.cpp
  src/text.cpp
  src/json_writer.cpp
  src/ecosystems.cpp
  src/generate.cpp
  src/platform.cpp
  src/detect.cpp
  src/jsregex.cpp
  "${GEN_DIR}/rules_json.h")
target_include_directories(kernwatch-sbom PRIVATE src "${GEN_DIR}")

if(MSVC)
  target_compile_options(kernwatch-sbom PRIVATE /W4 /utf-8)
  target_link_options(kernwatch-sbom PRIVATE /STACK:16777216)
  if(KWSBOM_STATIC)
    set_property(TARGET kernwatch-sbom PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
  endif()
else()
  target_compile_options(kernwatch-sbom PRIVATE -Wall -Wextra)
  if(WIN32)
    target_link_options(kernwatch-sbom PRIVATE -Wl,--stack,16777216)
  endif()
  if(KWSBOM_STATIC AND NOT APPLE AND NOT KWSBOM_SANITIZE)
    target_link_options(kernwatch-sbom PRIVATE -static)
  endif()
  if(KWSBOM_SANITIZE)
    target_compile_options(kernwatch-sbom PRIVATE -fsanitize=${KWSBOM_SANITIZE} -fno-omit-frame-pointer -g)
    target_link_options(kernwatch-sbom PRIVATE -fsanitize=${KWSBOM_SANITIZE})
  endif()
endif()
if(KWSBOM_STRIP AND NOT MSVC)
  # zig (cmake/zig-toolchain.cmake) strips at link time for every target; a Linux host's strip cannot read Mach-O
  if(APPLE AND NOT ZIG_TARGET)
    add_custom_command(TARGET kernwatch-sbom POST_BUILD COMMAND strip $<TARGET_FILE:kernwatch-sbom> VERBATIM)
  else()
    target_link_options(kernwatch-sbom PRIVATE -s)
  endif()
endif()
if(WIN32)
  target_compile_definitions(kernwatch-sbom PRIVATE UNICODE _UNICODE WIN32_LEAN_AND_MEAN)
  target_link_libraries(kernwatch-sbom PRIVATE shell32)
endif()

install(TARGETS kernwatch-sbom RUNTIME DESTINATION bin)
