-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
209 lines (169 loc) · 7.45 KB
/
CMakeLists.txt
File metadata and controls
209 lines (169 loc) · 7.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# Build Clarabel.rs (Rust library)
project(clarabel_c VERSION ${CLARABEL_PROJECT_VERSION})
# Define interface targets for the imported Rust library
add_library(libclarabel_c_static INTERFACE)
add_library(libclarabel_c_shared INTERFACE)
# Set the build flags and output directory
# Debug/Release flags
if(CMAKE_BUILD_TYPE MATCHES Release)
set(clarabel_c_build_flags "--release")
set(clarabel_c_output_directory "${CLARABEL_ROOT_DIR}/rust_wrapper/target/release")
else()
set(clarabel_c_build_flags "")
set(clarabel_c_output_directory "${CLARABEL_ROOT_DIR}/rust_wrapper/target/debug")
endif()
set(CLARABEL_C_OUTPUT_DIR ${clarabel_c_output_directory} PARENT_SCOPE)
if(NOT DEFINED CLARABEL_RUST_FEATURES)
set(CLARABEL_RUST_FEATURES "")
endif()
# -------------------------------------
# Cargo feature configuration helper functions
#--------------------------------------
# Check if CLARABEL_RUST_FEATURES contains a specific feature
function(rust_feature_is_enabled PATTERN RESULT_VAR)
string(REPLACE "," ";" FEATURE_LIST "${CLARABEL_RUST_FEATURES}")
set(${RESULT_VAR} FALSE PARENT_SCOPE)
foreach(FEATURE ${FEATURE_LIST})
if(FEATURE MATCHES "${PATTERN}")
set(${RESULT_VAR} TRUE PARENT_SCOPE)
break()
endif()
endforeach()
endfunction()
# Check if CLARABEL_RUST_FEATURES contains any of the "sdp" options
function(rust_features_has_sdp RESULT_VAR)
if(CLARABEL_RUST_FEATURES MATCHES ".*sdp.*")
set(${RESULT_VAR} TRUE PARENT_SCOPE)
else()
set(${RESULT_VAR} FALSE PARENT_SCOPE)
endif()
endfunction()
# Helper function to append a feature to a comma-separated list
function(append_feature FEATURE_LIST_VAR NEW_FEATURE)
if(${FEATURE_LIST_VAR} STREQUAL "")
set(${FEATURE_LIST_VAR} "${NEW_FEATURE}" PARENT_SCOPE)
else()
set(${FEATURE_LIST_VAR} "${${FEATURE_LIST_VAR}},${NEW_FEATURE}" PARENT_SCOPE)
endif()
endfunction()
# Automatically prefix features with 'clarabel/' if not already prefixed
# For serde, add it as both clarabel/serde and serde, with the latter
# necessary for the rust_wrapper cargo configuration.
function(format_clarabel_rust_features INPUT_FEATURES OUTPUT_VAR)
string(REPLACE "," ";" FEATURE_LIST "${INPUT_FEATURES}")
set(FORMATTED_FEATURES "")
foreach(FEATURE ${FEATURE_LIST})
# Regular handling: prefix with clarabel/ if not already prefixed
if(NOT FEATURE MATCHES "^clarabel/")
set(FEATURE "clarabel/${FEATURE}")
endif()
append_feature(FORMATTED_FEATURES "${FEATURE}")
endforeach()
set(${OUTPUT_VAR} "${FORMATTED_FEATURES}" PARENT_SCOPE)
endfunction()
# -------------------------------------
# Cargo feature configuration backward compatibility
#--------------------------------------
if(NOT CLARABEL_FEATURE_SDP STREQUAL "none")
append_feature(CLARABEL_RUST_FEATURES "${CLARABEL_FEATURE_SDP}")
endif()
if(CLARABEL_FEATURE_FAER_SPARSE)
append_feature(CLARABEL_RUST_FEATURES "faer-sparse")
endif()
if(CLARABEL_FEATURE_PARDISO_MKL)
append_feature(CLARABEL_RUST_FEATURES "pardiso-mkl")
endif()
# SERDE feature flag
if(CLARABEL_FEATURE_SERDE)
append_feature(CLARABEL_RUST_FEATURES "serde")
endif()
# -------------------------------------
# Cargo feature configuration
#--------------------------------------
# ----
# Rust features should be passed via the CLARABEL_RUST_FEATURES variable.
# For some features, we requires some additional CMake configuration.
# ---
rust_features_has_sdp(CONFIG_SDP)
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)
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)
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)
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)
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)
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)
endif()
# replace each rust <feature> with clarabel/<feature> so that they pass through
# this wrapper to the clarabel crate underneath
format_clarabel_rust_features("${CLARABEL_RUST_FEATURES}" CLARABEL_RUST_FEATURES)
# some features must also be specified at the wrapper level
# add them again, but after prepending clarabel/ to everything
if(CONFIG_SDP)
append_feature(CLARABEL_RUST_FEATURES "sdp")
endif()
if(CONFIG_SERDE)
append_feature(CLARABEL_RUST_FEATURES "serde")
endif()
if(NOT CLARABEL_RUST_FEATURES STREQUAL "")
set(clarabel_c_build_flags "${clarabel_c_build_flags};--features=${CLARABEL_RUST_FEATURES}")
endif()
message("-- Rust feature list: " ${CLARABEL_RUST_FEATURES})
message("-- Cargo options: " "${clarabel_c_build_flags}")
# -------------------------------------
# -------------------------------------
# Get the path to the Rust library for linking
if(APPLE)
set(LIBCLARABEL_C_SHARED_PATH "${clarabel_c_output_directory}/libclarabel_c.dylib")
set(LIBCLARABEL_C_STATIC_PATH "${clarabel_c_output_directory}/libclarabel_c.a")
elseif(UNIX)
set(LIBCLARABEL_C_SHARED_PATH "${clarabel_c_output_directory}/libclarabel_c.so")
set(LIBCLARABEL_C_STATIC_PATH "${clarabel_c_output_directory}/libclarabel_c.a")
elseif(WIN32)
set(LIBCLARABEL_C_SHARED_PATH "${clarabel_c_output_directory}/clarabel_c.dll.lib")
set(LIBCLARABEL_C_STATIC_PATH "${clarabel_c_output_directory}/clarabel_c.lib")
endif()
# Add the cargo project as a custom target
add_custom_target(
libclarabel_c
WORKING_DIRECTORY ${CLARABEL_ROOT_DIR}/rust_wrapper
# Commands for building the Rust library
COMMAND cargo build ${clarabel_c_build_flags}
COMMAND cargo install cbindgen
# Generate the C header
COMMAND cbindgen --config cbindgen.toml --quiet --crate clarabel_c --output ./headers/clarabel.h --lang c
# Generate the C++ header
COMMAND cbindgen --config cbindgen.toml --quiet --crate clarabel_c --output ./headers/clarabel.hpp
BYPRODUCTS
"${LIBCLARABEL_C_SHARED_PATH}"
"${LIBCLARABEL_C_STATIC_PATH}"
)
# Wrap the Rust library in a CMake library target
# Static library
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)
# 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)