cmake_minimum_required(VERSION 3.20)
project(n3xd_ocp LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()

# Match the kernel's flags: -O2, no fast-math, no -march=native.  OCCT's
# version is a determinism input for assay's committed goldens, so the binding
# has no business introducing a different FP contract than the kernel it wraps.
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")

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

# The version scheme is enforced, not merely conventional: a wheel labelled
# 7.9.3.N must actually wrap OCCT 7.9.3.
set(_occt_ver "${OpenCASCADE_MAJOR_VERSION}.${OpenCASCADE_MINOR_VERSION}.${OpenCASCADE_MAINTENANCE_VERSION}")
if(DEFINED SKBUILD_PROJECT_VERSION)
  if(NOT SKBUILD_PROJECT_VERSION MATCHES "^${_occt_ver}\\.")
    message(FATAL_ERROR
      "Version '${SKBUILD_PROJECT_VERSION}' does not match the OCCT found "
      "(${_occt_ver}). The scheme is <occt-version>.N — see pyproject.toml.")
  endif()
endif()
message(STATUS "Building n3xd-ocp against OCCT ${_occt_ver}")

file(GLOB OCP_MODULE_SOURCES CONFIGURE_DEPENDS "src/modules/*.cpp")
file(GLOB OCP_EXT_SOURCES CONFIGURE_DEPENDS "src/ext/*.cpp")

nanobind_add_module(_OCP
  STABLE_ABI
  NB_STATIC
  src/core.cpp
  src/common/occt_module.cpp
  src/common/occt_exceptions.cpp
  ${OCP_MODULE_SOURCES}
  ${OCP_EXT_SOURCES}
)

target_include_directories(_OCP PRIVATE ${OpenCASCADE_INCLUDE_DIR})

# Only the toolkits the bound surface actually reaches.  Grows with each
# coverage increment; auditwheel bundles whatever the linker records.
target_link_libraries(_OCP PRIVATE
  TKernel
  TKMath
  TKG2d
  TKG3d
  TKGeomBase
  TKBRep
  TKTopAlgo
  # Inc 1
  TKGeomAlgo   # GeomAPI, GCPnts
  TKPrim       # BRepPrimAPI
  TKBO         # BRepAlgoAPI, BOPAlgo
  TKMesh       # BRepMesh
  # Inc 2
  TKFillet     # BRepFilletAPI
  TKOffset     # BRepOffsetAPI
  TKShHealing  # ShapeFix, ShapeAnalysis, ShapeUpgrade
  TKBool       # BRepAlgo helpers pulled in by the above
  # Inc 3
  TKXSBase     # XSControl, Interface, IFSelect
  TKDESTEP     # STEPControl
  TKDEIGES     # IGESControl, IGESData
  TKDESTL      # RWStl
  # Inc 4 — the BRep font/text builders.  OCCT 8.0 moved the StdPrs package
  # from TKService to TKV3d (Font_BRepFont is now the typedef of
  # StdPrs_BRepFont, not the other way round), so both are needed.  The builder
  # image asserts each links without libGL/libX11, so this costs the runtime
  # image nothing.
  TKService
  TKV3d
)

target_compile_definitions(_OCP PRIVATE
  N3XD_OCP_VERSION="${SKBUILD_PROJECT_VERSION}"
)

install(TARGETS _OCP LIBRARY DESTINATION OCP)
