# Copyright Contributors to the OpenVDB Project
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.25 FATAL_ERROR)

# Set global download timeout to 600 seconds (10 minutes)
set(CMAKE_DOWNLOAD_TIMEOUT 600 CACHE STRING "Time allowed for downloads in seconds")

option(FVDB_STRIP_SYMBOLS "Strip symbols from the build" OFF)
message(STATUS "FVDB_STRIP_SYMBOLS: ${FVDB_STRIP_SYMBOLS}")

project(${SKBUILD_PROJECT_NAME} VERSION ${SKBUILD_PROJECT_VERSION} LANGUAGES CXX)

find_package(Python3 COMPONENTS Development Interpreter)

message(STATUS "CMAKE_BUILD_PARALLEL_LEVEL: $ENV{CMAKE_BUILD_PARALLEL_LEVEL}")
message(STATUS "NVCC_THREADS: $ENV{NVCC_THREADS}")

include(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/get_cpm.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/get_nvtx.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/get_torch.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/get_pybind11.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/get_nanovdb.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/configure_torch_pybind11.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/get_nanovdb_editor.cmake)

# Generate compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# configure libfvdb
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/)

# Source files
set(FVDB_BINDINGS_CPP_FILES
    src/python/Bindings.cpp
    src/python/FusedSSIMBinding.cpp
    src/python/GaussianSplatBinding.cpp
    src/python/GridBatchBinding.cpp
    src/python/JaggedTensorBinding.cpp
    src/python/ViewerBinding.cpp)

# Build library
Python3_add_library(_fvdb_cpp ${FVDB_BINDINGS_CPP_FILES} MODULE)
if (DEFINED TORCH_PYBIND11_INCLUDE_DIR)
    target_link_libraries(_fvdb_cpp PUBLIC torch_pybind11_headers)
else()
    target_link_libraries(_fvdb_cpp PUBLIC pybind11::headers)
endif()
set_target_properties(_fvdb_cpp PROPERTIES
    INTERPROCEDURAL_OPTIMIZATION ON
    CXX_VISIBILITY_PRESET hidden
    VISIBILITY_INLINES_HIDDEN ON)

target_link_options(_fvdb_cpp PRIVATE "-Wl,--no-as-needed")

set_target_properties(_fvdb_cpp PROPERTIES
    BUILD_RPATH "\$ORIGIN"
    INSTALL_RPATH "\$ORIGIN"
    INSTALL_RPATH_USE_LINK_PATH FALSE
    BUILD_WITH_INSTALL_RPATH TRUE
    CXX_STANDARD 20
    CXX_STANDARD_REQUIRED ON
    CXX_EXTENSIONS ON
    POSITION_INDEPENDENT_CODE ON
    INTERFACE_POSITION_INDEPENDENT_CODE ON)

target_include_directories(_fvdb_cpp PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/src
    ${TORCH_INCLUDE_DIRS}
    ${nanovdb_SOURCE_DIR}/nanovdb
    ${NANOVDB_EDITOR_INCLUDE_DIR})
target_link_libraries(_fvdb_cpp PRIVATE
    ${TORCH_PYTHON_LIBRARY}
    ${TORCH_LIBRARIES}
    fvdb)

target_compile_options(_fvdb_cpp PRIVATE
    $<$<COMPILE_LANGUAGE:CXX>:
    #"-Wno-unused-variable"
    "-fvisibility=hidden"
    "-fvisibility-inlines-hidden"
    "-Wall"
    "-Werror"
    "${TORCH_CXX_FLAGS}"
    >)

target_compile_definitions(_fvdb_cpp PRIVATE
    TORCH_EXTENSION_NAME=_fvdb_cpp
    TORCH_API_INCLUDE_EXTENSION_H)

# Configure the pybind11 module with PyTorch compatibility settings
configure_torch_pybind11(_fvdb_cpp)

# Add linker flags for Debug builds to preserve symbols
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
    target_link_options(_fvdb_cpp PRIVATE "-rdynamic")
endif()

# Strip symbols in non-Debug builds to reduce wheel size
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") AND FVDB_STRIP_SYMBOLS)
    target_link_options(_fvdb_cpp PRIVATE "-s")
endif()

# Only install the Python package artifacts; the core lib is installed as part of the Python module
install(TARGETS _fvdb_cpp fvdb
    LIBRARY DESTINATION fvdb COMPONENT PythonModule
    RUNTIME DESTINATION fvdb COMPONENT PythonModule)

# Capture the git short SHA for embedding in version.py
execute_process(
    COMMAND git rev-parse --short HEAD
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    OUTPUT_VARIABLE FVDB_GIT_SHA
    OUTPUT_STRIP_TRAILING_WHITESPACE
    ERROR_QUIET)
if(NOT FVDB_GIT_SHA)
    set(FVDB_GIT_SHA "Unknown")
endif()

set(VERSION_PY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/fvdb/version.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/fvdb/version.py.in" "${VERSION_PY_PATH}" @ONLY)

# Make sure version.py is included in the installation
install(FILES "${VERSION_PY_PATH}" DESTINATION fvdb COMPONENT PythonModule)
