# Die eingelesene Version in das Projekt setzen
if(DEFINED VERSION_NUMBER_OCPBASIC)
    set(PROJECT_VERSION ${VERSION_NUMBER_OCPBASIC})
else()
    message(FATAL_ERROR "VERSION_NUMBER_OCPBASIC is not defined in versionNumbers.cmake")
endif()

add_library(OCPbasic SHARED
    problem.cpp
    solution.cpp
    Discretization/DiscreteDimension.cpp
    Discretization/Discretization.cpp
    Discretization/trapez.cpp
    Optimizer/InteriorPointMethod.cpp
    Optimizer/InteriorPointMethod/ip_nlp.cpp
    Optimizer/InteriorPointMethod/ip_solver.cpp
    OCP_Timings.cpp
    linalg/collectormatrix.cpp
    linalg/sparsematrix.cpp
    linalg/OCPbasic.cpp
    linalg/OCPbasic_SymEigenValues.cpp
    linalg/BandedLU.cpp
    linalg/DenseLU.cpp
    linalg/LapackKKTSolver.cpp
    linalg/SymmetricCyclicReductionKKTSolver.cpp
)

target_include_directories(OCPbasic PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/linalg
    ${PROJECT_SOURCE_DIR}/src/
    ${ADD_INCLUDE_PATHS}
)

# Set backend according to selected option
if(${LAPACK_WRAPPER_USE_BACKEND} STREQUAL "LAPACK_WRAPPER_USE_MKL")
    target_compile_definitions(OCPbasic PRIVATE LAPACK_WRAPPER_USE_MKL)
    target_include_directories(OCPbasic PRIVATE ${MKL_INCLUDE_PATH})
    target_link_libraries(OCPbasic PRIVATE ${MKL_PATH_LIBS})
elseif(${LAPACK_WRAPPER_USE_BACKEND} STREQUAL "LAPACK_WRAPPER_USE_OPENBLAS")
    target_compile_definitions(OCPbasic PRIVATE LAPACK_WRAPPER_USE_OPENBLAS)
    target_include_directories(OCPbasic PRIVATE ${OPENBLAS_INCLUDE_PATH})
    target_link_libraries(OCPbasic PRIVATE ${OPENBLAS_PATH_LIBS})
elseif(${LAPACK_WRAPPER_USE_BACKEND} STREQUAL "LAPACK_WRAPPER_USE_LAPACK")
    target_compile_definitions(OCPbasic PRIVATE LAPACK_WRAPPER_USE_LAPACK)
    target_include_directories(OCPbasic PRIVATE ${LAPACK_INCLUDE_PATH} ${BLAS_INCLUDE_PATH})
    target_link_libraries(OCPbasic PRIVATE ${LAPACK_PATH_LIBS} ${BLAS_PATH_LIBS})
endif()

target_link_libraries(OCPbasic PRIVATE
    IPbasic
    lapack_wrapper
)

if(IPBASIC_USE_HSL)
    target_compile_definitions(OCPbasic PRIVATE IPBASIC_USE_HSL)
    target_link_libraries(OCPbasic PRIVATE ${HSL_PATH_LIBS})
endif()

if(OCPBASIC_ADD_LINKED_LIBS)
    target_link_libraries(OCPbasic PRIVATE ${ADD_LINKED_LIBS})
endif()

# Set backend according to selected option
if(${OCPBASIC_EIGENVAL_BACKEND} STREQUAL "OCPBASIC_USE_EIGENVAL_LAPACK_WRAPPER")
    target_compile_definitions(OCPbasic PRIVATE OCPBASIC_USE_EIGENVAL_LAPACK_WRAPPER)
elseif(${OCPBASIC_EIGENVAL_BACKEND} STREQUAL "OCPBASIC_USE_EIGENVAL_SYM")
    target_compile_definitions(OCPbasic PRIVATE OCPBASIC_USE_EIGENVAL_SYM)
elseif(${OCPBASIC_EIGENVAL_BACKEND} STREQUAL "OCPBASIC_USE_EIGENVAL_OWN")
    target_compile_definitions(OCPbasic PRIVATE OCPBASIC_USE_EIGENVAL_OWN)
endif()

# Installation
install(TARGETS OCPbasic
    LIBRARY DESTINATION ${OCPBASIC_LOCAL_PATH}/lib
)

install(FILES
    problem.h
    solution.h
    OCP_Params.h
    OCP_Timings.h
    DESTINATION ${OCPBASIC_LOCAL_PATH}/include/OCPbasic
)

if(${OCPBASIC_EIGENVAL_BACKEND} STREQUAL "OCPBASIC_USE_EIGENVAL_LAPACK_WRAPPER")
    install(FILES configHeaders/Eigenvalues_lapack_wrapper/OCPbasic_config.h
        DESTINATION ${OCPBASIC_LOCAL_PATH}/include/OCPbasic
    )
elseif(${OCPBASIC_EIGENVAL_BACKEND} STREQUAL "OCPBASIC_USE_EIGENVAL_SYM")
    install(FILES configHeaders/Eigenvalues_Sym/OCPbasic_config.h
        DESTINATION ${OCPBASIC_LOCAL_PATH}/include/OCPbasic
    )
elseif(${OCPBASIC_EIGENVAL_BACKEND} STREQUAL "OCPBASIC_USE_EIGENVAL_OWN")
    install(FILES configHeaders/Eigenvalues_Own/OCPbasic_config.h
        DESTINATION ${OCPBASIC_LOCAL_PATH}/include/OCPbasic
    )
endif()

install(FILES
    Optimizer/Optimizer.h
    Optimizer/InteriorPointMethod.h
    DESTINATION ${OCPBASIC_LOCAL_PATH}/include/OCPbasic/Optimizer)
    
install(FILES
    Discretization/trapez.h
    Discretization/DiscreteDefs.h
    Discretization/DiscreteDimension.h
    Discretization/Discretization.h
    DESTINATION ${OCPBASIC_LOCAL_PATH}/include/OCPbasic/Discretization)
    
install(FILES
    linalg/sparsematrix.h
    linalg/collectormatrix.h
    linalg/OCPbasic.h
    linalg/OCPbasic_HouseholderQR.h
    linalg/OCPbasic_SymEigenValues.h
    linalg/BandedLU.h
    linalg/DenseLU.h
    linalg/LapackKKTSolver.h
    linalg/SymmetricCyclicReductionKKTSolver.h
    DESTINATION ${OCPBASIC_LOCAL_PATH}/include/OCPbasic/linalg)
 
# Versionsinformationen der Bibliothek setzen
set_target_properties(OCPbasic PROPERTIES
    VERSION ${PROJECT_VERSION}
    SOVERSION ${MAJOR_VERSION_NUMBER_OCPBASIC}
)
