Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,47 @@ endif()
add_subdirectory(rust_wrapper)

# Add other subdirectories
add_subdirectory(examples)
option(CLARABEL_BUILD_EXAMPLES "Build the examples of Clarabel.cpp" true)
if(CLARABEL_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()

# Add tests
option(CLARABEL_BUILD_TESTS "Build the unit tests for Clarabel.cpp" false)
if(CLARABEL_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()

#----------------------------------------------
# Installation
#----------------------------------------------
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

set(CLARABEL_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Clarabel"
CACHE STRING "Installation directory of the CMake package files")

install(DIRECTORY "${CLARABEL_ROOT_DIR}/include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

if(WIN32)
install(FILES "${CLARABEL_C_OUTPUT_DIR}/clarabel_c.dll"
DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
install(FILES "${LIBCLARABEL_C_SHARED_PATH}" "${LIBCLARABEL_C_STATIC_PATH}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}")

configure_package_config_file(
"${CLARABEL_ROOT_DIR}/cmake/ClarabelConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/ClarabelConfig.cmake"
INSTALL_DESTINATION "${CLARABEL_INSTALL_CMAKEDIR}"
PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_BINDIR)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/ClarabelConfigVersion.cmake"
VERSION ${CLARABEL_PROJECT_VERSION}
COMPATIBILITY SameMinorVersion)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/ClarabelConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/ClarabelConfigVersion.cmake"
DESTINATION "${CLARABEL_INSTALL_CMAKEDIR}")
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,23 @@ where `VCPKG_TOOLCHAIN_PATH` is the path to the vcpkg toolchain file.

- For 32-bit platforms, use `x86-windows` instead of `x64-windows`.

## Installing the solver

```sh
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=<prefix>
cmake --build .
cmake --install .
```

installs the headers, the shared and the static library and a CMake package, which another project uses with

```cmake
find_package(Clarabel CONFIG REQUIRED)
target_link_libraries(my_target PRIVATE Clarabel::clarabel_c) # or Clarabel::clarabel_c_static
```

The same two targets are available when Clarabel.cpp is added with `add_subdirectory`. The examples are not built with `-DCLARABEL_BUILD_EXAMPLES=OFF`.

## Optional solver features

Clarabel.rs supports a variety of build options for semidefinite program (SDP) support, JSON file read/write, 3rd party linear solvers etc. Feature options can be passed to cargo via CMake using `-DCLARABEL_CARGO_FEATURES = "feature1,feature2,..."`.
Expand Down
74 changes: 74 additions & 0 deletions cmake/ClarabelConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# CMake package of Clarabel.cpp, which defines the imported targets
#
# Clarabel::clarabel_c the shared library
# Clarabel::clarabel_c_static the static library
#
# both with the C headers (clarabel.h) and the C++ ones (clarabel.hpp), the
# latter needing Eigen.

@PACKAGE_INIT@

# before the dependencies, whose own package files redefine PACKAGE_PREFIX_DIR
set(_clarabel_includedir "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
set(_clarabel_libdir "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
set(_clarabel_bindir "@PACKAGE_CMAKE_INSTALL_BINDIR@")
set(_clarabel_definitions "@CLARABEL_C_DEFINITIONS@")

include(CMakeFindDependencyMacro)
find_dependency(Threads)
find_package(Eigen3 3.4 CONFIG QUIET)

if(NOT TARGET Clarabel::clarabel_c)
add_library(Clarabel::clarabel_c SHARED IMPORTED)
if(WIN32)
set_target_properties(Clarabel::clarabel_c PROPERTIES
IMPORTED_LOCATION "${_clarabel_bindir}/clarabel_c.dll"
IMPORTED_IMPLIB "${_clarabel_libdir}/clarabel_c.dll.lib")
elseif(APPLE)
set_target_properties(Clarabel::clarabel_c PROPERTIES
IMPORTED_LOCATION "${_clarabel_libdir}/libclarabel_c.dylib")
else()
# the library has no SONAME, so that it is linked by name rather than
# by its path, which would otherwise be recorded in the executables
set_target_properties(Clarabel::clarabel_c PROPERTIES
IMPORTED_LOCATION "${_clarabel_libdir}/libclarabel_c.so"
IMPORTED_NO_SONAME TRUE)
endif()
endif()

if(NOT TARGET Clarabel::clarabel_c_static)
add_library(Clarabel::clarabel_c_static STATIC IMPORTED)
if(WIN32)
set_target_properties(Clarabel::clarabel_c_static PROPERTIES
IMPORTED_LOCATION "${_clarabel_libdir}/clarabel_c.lib")
else()
set_target_properties(Clarabel::clarabel_c_static PROPERTIES
IMPORTED_LOCATION "${_clarabel_libdir}/libclarabel_c.a")
endif()
# the system libraries needed by the Rust standard library
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set_property(TARGET Clarabel::clarabel_c_static APPEND PROPERTY
INTERFACE_LINK_LIBRARIES Threads::Threads ${CMAKE_DL_LIBS} m rt util)
endif()
endif()

foreach(_clarabel_target Clarabel::clarabel_c Clarabel::clarabel_c_static)
set_property(TARGET ${_clarabel_target} APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${_clarabel_includedir}")
if(_clarabel_definitions)
set_property(TARGET ${_clarabel_target} APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS ${_clarabel_definitions})
endif()
if(TARGET Eigen3::Eigen)
set_property(TARGET ${_clarabel_target} APPEND PROPERTY
INTERFACE_LINK_LIBRARIES Eigen3::Eigen)
endif()
endforeach()

unset(_clarabel_target)
unset(_clarabel_includedir)
unset(_clarabel_libdir)
unset(_clarabel_bindir)
unset(_clarabel_definitions)

check_required_components(Clarabel)
27 changes: 26 additions & 1 deletion rust_wrapper/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ endif()

set(CLARABEL_C_OUTPUT_DIR ${clarabel_c_output_directory} PARENT_SCOPE)

# The compile definitions of the enabled features, which are also given to
# the targets of the installed package
set(clarabel_c_definitions "")

if(NOT DEFINED CLARABEL_CARGO_FEATURES)
set(CLARABEL_CARGO_FEATURES "")
endif()
Expand Down Expand Up @@ -111,35 +115,41 @@ if(CONFIG_SDP)
# Define the FEATURE_SDP flag for all targets that link against clarabel_c
target_compile_definitions(libclarabel_c_static INTERFACE FEATURE_SDP)
target_compile_definitions(libclarabel_c_shared INTERFACE FEATURE_SDP)
list(APPEND clarabel_c_definitions FEATURE_SDP)
endif()

rust_feature_is_enabled("faer-sparse" CONFIG_FAER_SPARSE)
if(CONFIG_FAER_SPARSE)
target_compile_definitions(libclarabel_c_static INTERFACE FEATURE_FAER_SPARSE)
target_compile_definitions(libclarabel_c_shared INTERFACE FEATURE_FAER_SPARSE)
list(APPEND clarabel_c_definitions FEATURE_FAER_SPARSE)
endif()

rust_feature_is_enabled("pardiso-mkl" CONFIG_PARDISO_MKL)
if(CONFIG_PARDISO_MKL)
target_compile_definitions(libclarabel_c_static INTERFACE FEATURE_PARDISO_MKL)
target_compile_definitions(libclarabel_c_shared INTERFACE FEATURE_PARDISO_MKL)
list(APPEND clarabel_c_definitions FEATURE_PARDISO_MKL)
endif()

rust_feature_is_enabled("pardiso-panua" CONFIG_PARDISO_PANUA)
if(CONFIG_PARDISO_PANUA)
target_compile_definitions(libclarabel_c_static INTERFACE FEATURE_PARDISO_PANUA)
target_compile_definitions(libclarabel_c_shared INTERFACE FEATURE_PARDISO_PANUA)
list(APPEND clarabel_c_definitions FEATURE_PARDISO_PANUA)
endif()

if(CONFIG_PARDISO_MKL OR CONFIG_PARDISO_PANUA)
target_compile_definitions(libclarabel_c_static INTERFACE FEATURE_PARDISO_ANY)
target_compile_definitions(libclarabel_c_shared INTERFACE FEATURE_PARDISO_ANY)
list(APPEND clarabel_c_definitions FEATURE_PARDISO_ANY)
endif()

rust_feature_is_enabled("serde" CONFIG_SERDE)
if(CONFIG_SERDE)
target_compile_definitions(libclarabel_c_static INTERFACE FEATURE_SERDE)
target_compile_definitions(libclarabel_c_shared INTERFACE FEATURE_SERDE)
list(APPEND clarabel_c_definitions FEATURE_SERDE)
endif()

# replace each rust <feature> with clarabel/<feature> so that they pass through
Expand Down Expand Up @@ -178,10 +188,14 @@ elseif(WIN32)
set(LIBCLARABEL_C_STATIC_PATH "${clarabel_c_output_directory}/clarabel_c.lib")
endif()

set(LIBCLARABEL_C_SHARED_PATH "${LIBCLARABEL_C_SHARED_PATH}" PARENT_SCOPE)
set(LIBCLARABEL_C_STATIC_PATH "${LIBCLARABEL_C_STATIC_PATH}" PARENT_SCOPE)
set(CLARABEL_C_DEFINITIONS "${clarabel_c_definitions}" PARENT_SCOPE)


# Add the cargo project as a custom target
add_custom_target(
libclarabel_c
libclarabel_c ALL
WORKING_DIRECTORY ${CLARABEL_ROOT_DIR}/rust_wrapper
# Commands for building the Rust library
COMMAND cargo build ${clarabel_c_build_flags}
Expand All @@ -202,8 +216,19 @@ add_custom_target(
target_link_libraries(libclarabel_c_static INTERFACE ${LIBCLARABEL_C_STATIC_PATH})
target_include_directories(libclarabel_c_static INTERFACE ${CLARABEL_ROOT_DIR}/include)
add_dependencies(libclarabel_c_static libclarabel_c)
# the system libraries needed by the Rust standard library
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package(Threads REQUIRED)
target_link_libraries(libclarabel_c_static INTERFACE
Threads::Threads ${CMAKE_DL_LIBS} m rt util)
endif()

# Shared library
target_link_libraries(libclarabel_c_shared INTERFACE ${LIBCLARABEL_C_SHARED_PATH})
target_include_directories(libclarabel_c_shared INTERFACE ${CLARABEL_ROOT_DIR}/include)
add_dependencies(libclarabel_c_shared libclarabel_c)

# The names of the targets of the installed package, also when Clarabel.cpp
# is consumed via `add_subdirectory`
add_library(Clarabel::clarabel_c ALIAS libclarabel_c_shared)
add_library(Clarabel::clarabel_c_static ALIAS libclarabel_c_static)