cmake_minimum_required(VERSION 3.24)
project(VANTAGE VERSION 0.2.0 LANGUAGES CXX)
option(VANTAGE_CUDA "Build CUDA backend" OFF)
option(VANTAGE_HIP "Build experimental HIP/hipSPARSE backend" OFF)
if(VANTAGE_CUDA AND VANTAGE_HIP)
 message(FATAL_ERROR "Choose CUDA or HIP in a build, not both")
endif()
option(VANTAGE_SPARSE_LU "Use vendored Eigen sparse numerical basis factorization" ON)
option(VANTAGE_OPENMP "Use OpenMP" ON)
option(VANTAGE_SANITIZE "Enable address and undefined behavior sanitizers" OFF)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_library(vantage src/model.cpp src/io.cpp src/verify.cpp src/preprocess.cpp src/cpu.cpp src/solver.cpp src/mip.cpp src/research.cpp src/simplex.cpp src/cuts.cpp src/barrier.cpp src/portfolio.cpp)
target_include_directories(vantage PUBLIC include PRIVATE third_party)
set_target_properties(vantage PROPERTIES POSITION_INDEPENDENT_CODE ON)
if(VANTAGE_SPARSE_LU)
 target_include_directories(vantage SYSTEM PRIVATE third_party/eigen)
 target_compile_definitions(vantage PRIVATE VANTAGE_SPARSE_LU EIGEN_DONT_PARALLELIZE)
endif()
find_package(Threads REQUIRED)
target_link_libraries(vantage PRIVATE Threads::Threads)
target_compile_options(vantage PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wall;-Wextra;-Wpedantic>)
if(VANTAGE_OPENMP)
 find_package(OpenMP)
 if(OpenMP_CXX_FOUND)
  target_link_libraries(vantage PUBLIC OpenMP::OpenMP_CXX)
 endif()
endif()
if(VANTAGE_CUDA)
 enable_language(CUDA)
 find_package(CUDAToolkit REQUIRED)
 target_sources(vantage PRIVATE src/cuda.cu)
 target_compile_definitions(vantage PUBLIC VANTAGE_HAS_CUDA)
 target_link_libraries(vantage PRIVATE CUDA::cudart CUDA::cusparse)
 set_target_properties(vantage PROPERTIES CUDA_STANDARD 17 CUDA_STANDARD_REQUIRED ON)
elseif(VANTAGE_HIP)
 enable_language(HIP)
 find_package(hip REQUIRED CONFIG)
 find_package(hipsparse REQUIRED CONFIG)
 set_source_files_properties(src/cuda.cu PROPERTIES LANGUAGE HIP)
 target_sources(vantage PRIVATE src/cuda.cu)
 target_compile_definitions(vantage PUBLIC VANTAGE_HAS_HIP)
 target_link_libraries(vantage PRIVATE hip::host roc::hipsparse)
 set_target_properties(vantage PROPERTIES HIP_STANDARD 17 HIP_STANDARD_REQUIRED ON)
else()
 target_sources(vantage PRIVATE src/cuda_stub.cpp)
endif()
if(VANTAGE_SANITIZE)
 target_compile_options(vantage PUBLIC -fsanitize=address,undefined -fno-omit-frame-pointer)
 target_link_options(vantage PUBLIC -fsanitize=address,undefined)
endif()
add_executable(vantage_cli app/main.cpp)
add_library(vantage_c SHARED src/c_api.cpp)
target_include_directories(vantage_c PRIVATE third_party)
target_link_libraries(vantage_c PRIVATE vantage)
set_target_properties(vantage_c PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
set_target_properties(vantage_cli PROPERTIES OUTPUT_NAME niryukti)
target_include_directories(vantage_cli PRIVATE third_party)
target_link_libraries(vantage_cli PRIVATE vantage)
# Keep existing developer scripts working while the installed CLI uses NIRYUKTI.
add_custom_command(TARGET vantage_cli POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
 $<TARGET_FILE:vantage_cli> ${CMAKE_CURRENT_BINARY_DIR}/vantage${CMAKE_EXECUTABLE_SUFFIX})
include(CTest)
if(BUILD_TESTING)
add_executable(vantage_tests tests/test_core.cpp)
target_link_libraries(vantage_tests PRIVATE vantage)
add_test(NAME core COMMAND vantage_tests)
add_executable(vantage_research_tests tests/test_research.cpp)
target_link_libraries(vantage_research_tests PRIVATE vantage)
add_test(NAME research COMMAND vantage_research_tests)
set_tests_properties(core research PROPERTIES WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
endif()
if(SKBUILD)
 install(TARGETS vantage_cli RUNTIME DESTINATION vantage/_native/bin)
 install(TARGETS vantage_c LIBRARY DESTINATION vantage/_native/lib RUNTIME DESTINATION vantage/_native/lib)
 install(FILES LICENSE NOTICE third_party/JSON-LICENSE.MIT third_party/eigen/COPYING.MPL2 third_party/eigen/COPYING.BSD third_party/eigen/COPYING.MINPACK third_party/eigen/COPYING.APACHE third_party/eigen/COPYING.README DESTINATION vantage/_native/licenses)
else()
install(TARGETS vantage vantage_cli vantage_c)
install(DIRECTORY include/vantage DESTINATION include)

endif()
