cmake_minimum_required(VERSION 3.22)
project(cadunpack LANGUAGES CXX)

if(POLICY CMP0167)
  cmake_policy(SET CMP0167 NEW)
endif()

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

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

option(CADUNPACK_BUILD_PYTHON_MODULE "Build the Python extension module." ON)
option(CADUNPACK_BUILD_TESTS "Build native tests." OFF)

find_package(
  OpenCascade REQUIRED
  COMPONENTS
    TKernel
    TKMath
    TKG2d
    TKG3d
    TKCDF
    TKLCAF
    TKCAF
    TKGeomBase
    TKGeomAlgo
    TKTopAlgo
    TKBRep
    TKPrim
    TKMesh
    TKShHealing
    TKXSBase
    TKXCAF
    TKDESTEP
)
find_package(Boost REQUIRED)

add_library(
  cadunpack_core STATIC
  cpp/src/step/component_extractor.cpp
  cpp/src/step/step_reader.cpp
  cpp/src/step/step_unpacker.cpp
  cpp/src/unfold/sheetmetal_unfolder.cpp
)
set_target_properties(cadunpack_core PROPERTIES POSITION_INDEPENDENT_CODE ON)

target_include_directories(
  cadunpack_core
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/cpp/include>
    $<INSTALL_INTERFACE:include>
)

target_link_libraries(cadunpack_core PUBLIC OpenCascade::OpenCascade)
if(TARGET Boost::headers)
  target_link_libraries(cadunpack_core PUBLIC Boost::headers)
elseif(TARGET Boost::boost)
  target_link_libraries(cadunpack_core PUBLIC Boost::boost)
else()
  target_include_directories(cadunpack_core PUBLIC ${Boost_INCLUDE_DIRS})
endif()
target_compile_features(cadunpack_core PUBLIC cxx_std_20)

if(MSVC)
  target_compile_options(cadunpack_core PRIVATE /W4 /permissive-)
else()
  target_compile_options(cadunpack_core PRIVATE -Wall -Wextra -Wpedantic)
endif()

if(CADUNPACK_BUILD_PYTHON_MODULE)
  find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
  find_package(pybind11 CONFIG REQUIRED)

  pybind11_add_module(_cadunpack cpp/src/python/module.cpp)
  target_link_libraries(_cadunpack PRIVATE cadunpack_core)

  install(TARGETS _cadunpack LIBRARY DESTINATION cadunpack)

  if(APPLE)
    set(CADUNPACK_VENDOR_SEARCH_DIRS "")
    foreach(_cadunpack_library IN LISTS OpenCascade_LIBRARIES)
      get_filename_component(_cadunpack_library_dir "${_cadunpack_library}" DIRECTORY)
      list(APPEND CADUNPACK_VENDOR_SEARCH_DIRS "${_cadunpack_library_dir}")
    endforeach()
    list(REMOVE_DUPLICATES CADUNPACK_VENDOR_SEARCH_DIRS)

    configure_file(
      "${CMAKE_CURRENT_SOURCE_DIR}/cmake/VendorMacOSRuntime.cmake.in"
      "${CMAKE_CURRENT_BINARY_DIR}/VendorMacOSRuntime.cmake"
      @ONLY
    )
    install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/VendorMacOSRuntime.cmake")
  elseif(UNIX)
    find_program(PATCHELF_EXECUTABLE patchelf)
    if(PATCHELF_EXECUTABLE)
      configure_file(
        "${CMAKE_CURRENT_SOURCE_DIR}/cmake/VendorLinuxRuntime.cmake.in"
        "${CMAKE_CURRENT_BINARY_DIR}/VendorLinuxRuntime.cmake"
        @ONLY
      )
      install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/VendorLinuxRuntime.cmake")
    else()
      message(STATUS "patchelf not found; Linux runtime vendoring is disabled.")
    endif()
  endif()
endif()

install(DIRECTORY cpp/include/ DESTINATION include)
