cmake_minimum_required(VERSION 3.26)
project(goblin_cpu_features LANGUAGES CXX)

if(NOT SKBUILD)
  message(
    WARNING
    "This project is intended to be built through scikit-build-core.\n"
    "Typical commands:\n"
    "  pip install .\n"
    "  pip install --no-build-isolation -ve .\n"
  )
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
find_package(nanobind CONFIG REQUIRED)

nanobind_add_module(
  _native
  src/cpp/module.cpp
  src/cpp/feature.cpp
  src/cpp/detect.cpp
  src/cpp/detect_x86.cpp
  src/cpp/detect_arm.cpp
  src/cpp/detect_loongarch.cpp
  src/cpp/detect_powerpc.cpp
  src/cpp/detect_riscv.cpp
  src/cpp/detect_sparc.cpp
)

target_include_directories(_native PRIVATE src/cpp)
target_compile_features(_native PRIVATE cxx_std_17)

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
  target_compile_options(_native PRIVATE -O2 -Wall -Wextra -Wpedantic)
endif()
if(MSVC)
  target_compile_options(_native PRIVATE /O2 /W4 /permissive-)
endif()

install(TARGETS _native LIBRARY DESTINATION goblin_cpu_features)

# Generate the Python type stub from features.def so it can't drift from the
# C++ X-macro list. Runs at configure time and again whenever features.def
# changes (handled by CONFIGURE_DEPENDS on the dependency).
set(_goblin_cpu_features_stub "${CMAKE_CURRENT_BINARY_DIR}/_native.pyi")
add_custom_command(
  OUTPUT "${_goblin_cpu_features_stub}"
  COMMAND "${Python_EXECUTABLE}"
          "${CMAKE_CURRENT_SOURCE_DIR}/tools/gen_stub.py"
          "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/features.def"
          "${_goblin_cpu_features_stub}"
  DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/features.def"
          "${CMAKE_CURRENT_SOURCE_DIR}/tools/gen_stub.py"
  VERBATIM
)
add_custom_target(goblin_cpu_features_stub ALL DEPENDS "${_goblin_cpu_features_stub}")
add_dependencies(_native goblin_cpu_features_stub)
install(FILES "${_goblin_cpu_features_stub}" DESTINATION goblin_cpu_features)
