-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
363 lines (332 loc) · 14.7 KB
/
CMakeLists.txt
File metadata and controls
363 lines (332 loc) · 14.7 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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
cmake_minimum_required(VERSION 3.16)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/version.txt version)
project(
zenohc
VERSION ${version}
DESCRIPTION "The C bindings for Zenoh"
HOMEPAGE_URL "https://github.com/eclipse-zenoh/zenoh-c"
LANGUAGES C CXX
)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
include(helpers)
set_default_build_type(Release)
enable_testing()
#
# Build zenohc library from rust sources
#
# target zenohc::lib - for linking zenoh-c as static or dynamic library depending on BUILD_SHARED_LIBS boolean cache var
# target zenohc::static - for linking zenoh-c as static library
# target zenohc::shared - for linking zenoh-c as dynamic library
#
#
# Configuration options
#
declare_cache_var_true_if_vscode(ZENOHC_BUILD_IN_SOURCE_TREE "Do build inside source tree")
declare_cache_var(ZENOHC_BUILD_WITH_SHARED_MEMORY FALSE BOOL "Enable shared-memory zenoh-c feature")
declare_cache_var(ZENOHC_BUILD_WITH_UNSTABLE_API FALSE BOOL "Enable unstable API feature")
declare_cache_var(ZENOHC_BUILD_TESTS_WITH_CXX FALSE BOOL "Use C++ compiler for building tests to check API's C++ compatibility")
declare_cache_var(ZENOHC_CUSTOM_TARGET "" STRING "Rust target for cross compilation, 'aarch64-unknown-linux-gnu' for example")
message(STATUS "ENV{CARGO_BUILD_TARGET} = $ENV{CARGO_BUILD_TARGET}")
if(NOT(ZENOHC_CUSTOM_TARGET STREQUAL ""))
set(_INTERNAL_ZENOHC_BUILD_TARGET ${ZENOHC_CUSTOM_TARGET})
set(_INTERNAL_ZENOHC_BUILD_TARGET_SOURCE ZENOHC_CUSTOM_TARGET)
elseif(NOT("$ENV{CARGO_BUILD_TARGET}" STREQUAL ""))
set(_INTERNAL_ZENOHC_BUILD_TARGET $ENV{CARGO_BUILD_TARGET})
set(_INTERNAL_ZENOHC_BUILD_TARGET_SOURCE ENV{CARGO_BUILD_TARGET})
endif()
if(NOT("${_INTERNAL_ZENOHC_BUILD_TARGET}" STREQUAL ""))
message(STATUS "Build target: ${_INTERNAL_ZENOHC_BUILD_TARGET} (from ${_INTERNAL_ZENOHC_BUILD_TARGET_SOURCE})")
endif()
declare_cache_var(ZENOHC_CARGO_CHANNEL "" STRING "Cargo channel parameter. Should be '+stable', '+nightly' or empty value")
declare_cache_var(ZENOHC_CARGO_FLAGS "" STRING "Additional cargo flags")
declare_cache_var(BUILD_SHARED_LIBS TRUE BOOL "Alias zenohc::lib target to zenohc::shared if TRUE, to zenohc::static if FALSE")
declare_cache_var(ZENOHC_TREAT_WARNING_AS_ERROR OFF BOOL "Whether to treat compilation warnings as errors")
set(CMAKE_COMPILE_WARNING_AS_ERROR ${ZENOHC_TREAT_WARNING_AS_ERROR})
set(project_version "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
if(PROJECT_VERSION_TWEAK STREQUAL "")
set(project_version "${project_version}")
elseif(PROJECT_VERSION_TWEAK EQUAL 0)
set(project_version "${project_version}-dev")
elseif(PROJECT_VERSION_TWEAK GREATER 0)
set(project_version "${project_version}-pre.${PROJECT_VERSION_TWEAK}")
endif()
status_print(project_version)
#
# There are 3 possible variants of placement generated Cargo.toml files:
# 1. Build in source tree (in IDE usually), using single config generator (Ninja, Makefiles)
#
# In this case Cargo.toml is placed at the root of source tree to make it visible for rust-analyzer. When release or debug
# configuration is selected, Cargo.toml is updated accordingly
#
# 2. Build in source tree (in IDE usually), using multi config generator (Visual Studio, Ninja Multi-Config)
#
# Cargo.toml is placed at the root of source tree to make it visible for rust-analyzer. Also two additional Cargo.toml files
# are placed in ${CMAKE_CURRENT_BINARY_DIR}/debug and ${CMAKE_CURRENT_BINARY_DIR}/release directories configured for debug and
# release builds respectively
#
# 3. Build in build tree, no matter what generator is used
#
# Cargo.toml is placed in ${CMAKE_CURRENT_BINARY_DIR}/debug and ${CMAKE_CURRENT_BINARY_DIR}/release directories. No care is taken
# about Cargo.toml at the root of source tree
#
if(ZENOHC_BUILD_IN_SOURCE_TREE AND(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}))
set(cargo_toml_dir_ide ${CMAKE_SOURCE_DIR})
if (GENERATOR_IS_MULTI_CONFIG)
message(STATUS "Mode: IDE, Multi-Config generator (${CMAKE_GENERATOR}))")
set(cargo_toml_dir_debug ${CMAKE_CURRENT_BINARY_DIR}/debug)
set(cargo_toml_dir_release ${CMAKE_CURRENT_BINARY_DIR}/release)
file(MAKE_DIRECTORY ${cargo_toml_dir_debug}/include)
file(MAKE_DIRECTORY ${cargo_toml_dir_release}/include)
else()
message(STATUS "Mode: IDE, Single-Config generator (${CMAKE_GENERATOR})")
set(cargo_toml_dir_debug ${cargo_toml_dir_ide})
set(cargo_toml_dir_release ${cargo_toml_dir_ide})
endif()
else()
message(STATUS "Mode: Non-IDE")
unset(cargo_toml_dir_ide)
set(cargo_toml_dir_debug ${CMAKE_CURRENT_BINARY_DIR}/debug)
set(cargo_toml_dir_release ${CMAKE_CURRENT_BINARY_DIR}/release)
file(MAKE_DIRECTORY ${cargo_toml_dir_debug}/include)
file(MAKE_DIRECTORY ${cargo_toml_dir_release}/include)
endif()
# note: case-insensitive build configuration check
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
set(DEBUG TRUE)
endif()
set_genexpr_condition(cargo_toml_dir DEBUG $<CONFIG:Debug> ${cargo_toml_dir_debug} ${cargo_toml_dir_release})
set_genexpr_condition(cargo_generated_include_dir DEBUG $<CONFIG:Debug> ${cargo_toml_dir_debug}/include ${cargo_toml_dir_release}/include)
set(cargo_target_dir_debug ${cargo_toml_dir_debug}/target)
set(cargo_target_dir_release ${cargo_toml_dir_release}/target)
if(NOT("${_INTERNAL_ZENOHC_BUILD_TARGET}" STREQUAL ""))
set(cargo_target_dir_debug ${cargo_target_dir_debug}/${_INTERNAL_ZENOHC_BUILD_TARGET})
set(cargo_target_dir_release ${cargo_target_dir_release}/${_INTERNAL_ZENOHC_BUILD_TARGET})
endif()
set(cargo_binary_dir_debug ${cargo_target_dir_debug}/debug)
set(cargo_binary_dir_release ${cargo_target_dir_release}/release)
set_genexpr_condition(cargo_binary_dir DEBUG $<CONFIG:Debug> ${cargo_binary_dir_debug} ${cargo_binary_dir_release})
set(source_include_dir ${CMAKE_CURRENT_SOURCE_DIR}/include)
function(configure_cargo_toml cargo_toml_dir CARGO_PROJECT_VERSION CARGO_LIB_NAME)
message(STATUS "Configuring Cargo.toml in ${cargo_toml_dir} for ${CARGO_LIB_NAME}")
if(NOT(cargo_toml_dir STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}))
set(CARGO_PROJECT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/")
file(COPY
${CMAKE_CURRENT_SOURCE_DIR}/splitguide.yaml
${CMAKE_CURRENT_SOURCE_DIR}/cbindgen.toml
${CMAKE_CURRENT_SOURCE_DIR}/rust-toolchain.toml
${CMAKE_CURRENT_SOURCE_DIR}/version.txt
DESTINATION ${cargo_toml_dir})
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.lock")
file(COPY
${CMAKE_CURRENT_SOURCE_DIR}/Cargo.lock
DESTINATION ${cargo_toml_dir})
endif()
file(COPY
${CMAKE_CURRENT_SOURCE_DIR}/include/zenoh.h
${CMAKE_CURRENT_SOURCE_DIR}/include/zenoh_memory.h
${CMAKE_CURRENT_SOURCE_DIR}/include/zenoh_constants.h
DESTINATION ${cargo_toml_dir}/include/)
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml.in" "${cargo_toml_dir}/Cargo.toml" @ONLY)
endfunction()
#
# Configure Cargo.toml files
#
# Set COMMENT_PINNED_DEPS based on ZENOHC_CARGO_CHANNEL
if(ZENOHC_CARGO_CHANNEL STREQUAL "+1.75" OR ZENOHC_CARGO_CHANNEL STREQUAL "+1.75.0")
set(COMMENT_PINNED_DEPS "")
else()
set(COMMENT_PINNED_DEPS "# ")
endif()
set(cargo_lib_name_debug zenohc)
set(cargo_lib_name_release zenohc)
if(cargo_toml_dir_debug STREQUAL cargo_toml_dir_release)
# same Cargo.toml is for ide, debug and release configurations
# This happens only for non-multiconfig generators, so testing for debug/release on configuration stage is allowed
# note: case-insensitive build configuration check
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
if (CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
set(cargo_lib_name ${cargo_lib_name_debug})
else()
set(cargo_lib_name ${cargo_lib_name_release})
endif()
configure_cargo_toml(${cargo_toml_dir_ide} ${project_version} ${cargo_lib_name})
else()
set_genexpr_condition(cargo_lib_name DEBUG $<CONFIG:Debug> ${cargo_lib_name_debug} ${cargo_lib_name_release})
if(DEFINED cargo_toml_dir_ide)
configure_cargo_toml(${cargo_toml_dir_ide} ${project_version} ${cargo_lib_name_release})
endif()
configure_cargo_toml(${cargo_toml_dir_debug} ${project_version} ${cargo_lib_name_debug})
configure_cargo_toml(${cargo_toml_dir_release} ${project_version} ${cargo_lib_name_release})
endif()
#
# Copy toolchain configuration to build directory to ensure it is used when cargo is invoked from a directory other
# than the directory containing the manifest file
#
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/rust-toolchain.toml")
file(COPY
${CMAKE_CURRENT_SOURCE_DIR}/rust-toolchain.toml
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
endif()
#
# Configure result library names
#
macro(set_lib list var value)
set(${var} ${value})
list(APPEND ${list} ${value})
endmacro()
# dylib[r|d] - dymamic library (.so, .dll, .dylib)
# staticlib[r|d] - static library (.a, .lib)
# implib[r|d] - import library for windows dynamic library (DLL) - .lib
# dylibs[r|d] - list of files required for use dynamic library
# staticlibs[r|d] - list of files required for use static library
# get rust output library names from https://github.com/corrosion-rs/corrosion/blob/1c6974c2473765449e7c4649f9f96f1b751420c3/cmake/Corrosion.cmake#L331
if(WIN32)
set_lib(dylibsr dylibr zenohc.dll)
set_lib(dylibsd dylibd zenohc.dll)
if(MSVC)
set_lib(staticlibsr staticlibr zenohc.lib)
set_lib(staticlibsd staticlibd zenohc.lib)
set_lib(dylibsr implibr zenohc.dll.lib)
set_lib(dylibsd implibd zenohc.dll.lib)
else() #gnu/mingw/msys ?
set_lib(staticlibsr staticlibr libzenohc.a)
set_lib(staticlibsd staticlibd libzenohc.a)
set_lib(dylibsr implibr libzenohc.dll.a)
set_lib(dylibsd implibd libzenohc.dll.a)
endif()
elseif(APPLE)
set_lib(dylibsr dylibr libzenohc.dylib)
set_lib(dylibsd dylibd libzenohc.dylib)
set_lib(staticlibsr staticlibr libzenohc.a)
set_lib(staticlibsd staticlibd libzenohc.a)
else() #UNIX
set_lib(dylibsr dylibr libzenohc.so)
set_lib(dylibsd dylibd libzenohc.so)
set_lib(staticlibsr staticlibr libzenohc.a)
set_lib(staticlibsd staticlibd libzenohc.a)
endif()
list(APPEND libsr ${dylibsr})
list(APPEND libsr ${staticlibsr})
list(APPEND libsd ${dylibsd})
list(APPEND libsd ${staticlibsd})
list(TRANSFORM libsr PREPEND "${cargo_binary_dir_release}/")
list(TRANSFORM libsd PREPEND "${cargo_binary_dir_debug}/")
set_genexpr_condition(libs DEBUG $<CONFIG:Debug> "${libsd}" "${libsr}")
#
# Build rust sources
#
# Combine "--release" and "--manifest-path" options under DEBUG condition to avoid passing empty parameter to cargo command line in `add_custom_command`, causing build failure
# This empty item ($<IF:$<CONFIG:Debug>;,--release>) can't be filtered out by `list(FILTER ...)` because it becomes empty only on
# build stage when generator expressions are evaluated.
set_genexpr_condition(cargo_flags DEBUG $<CONFIG:Debug>
"--manifest-path=${cargo_toml_dir_debug}/Cargo.toml"
"--release;--manifest-path=${cargo_toml_dir_release}/Cargo.toml")
set(cargo_flags ${cargo_flags} ${ZENOHC_CARGO_FLAGS})
if(ZENOHC_BUILD_WITH_SHARED_MEMORY)
set(cargo_flags ${cargo_flags} --features=shared-memory)
elseif("${cargo_flags}" MATCHES ^.*shared-memory.*$)
set(ZENOHC_BUILD_WITH_SHARED_MEMORY TRUE)
message(STATUS "Due to ZENOHC_CARGO_FLAGS setting ZENOHC_BUILD_WITH_SHARED_MEMORY = TRUE")
endif()
if(ZENOHC_BUILD_WITH_UNSTABLE_API)
set(cargo_flags ${cargo_flags} --features=unstable)
elseif("${cargo_flags}" MATCHES ^.*unstable.*$)
set(ZENOHC_BUILD_WITH_UNSTABLE_API TRUE)
message(STATUS "Due to ZENOHC_CARGO_FLAGS setting ZENOHC_BUILD_WITH_UNSTABLE_API = TRUE")
endif()
if(NOT(ZENOHC_CUSTOM_TARGET STREQUAL ""))
set(cargo_flags ${cargo_flags} --target=${ZENOHC_CUSTOM_TARGET})
endif()
status_print(cargo_flags)
status_print(libs)
file(GLOB_RECURSE rust_sources "Cargo.toml.in" "src/*.rs" "build.rs" "splitguide.yaml")
add_custom_command(
OUTPUT ${libs}
COMMAND ${CMAKE_COMMAND} -E echo \"RUSTFLAGS = $$RUSTFLAGS\"
COMMAND ${CMAKE_COMMAND} -E echo \"cargo ${ZENOHC_CARGO_CHANNEL} build ${cargo_flags}\"
COMMAND ${CMAKE_COMMAND} -E env OPAQUE_TYPES_BUILD_DIR=${CMAKE_BINARY_DIR}/opaque-types cargo ${ZENOHC_CARGO_CHANNEL} build ${cargo_flags}
VERBATIM
COMMAND_EXPAND_LISTS
DEPENDS "${rust_sources}"
USES_TERMINAL
)
add_custom_target(cargo ALL DEPENDS "${libs}")
#
# Define libraries built by cargo as targets
#
function(set_target_imported_locations target libr libd)
set(_loc_debug ${cargo_binary_dir_debug}/${libd})
set(_loc_release ${cargo_binary_dir_release}/${libr})
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(_loc "${_loc_debug}")
else()
set(_loc "${_loc_release}")
endif()
set_target_properties(${target}
PROPERTIES
IMPORTED_GLOBAL TRUE
IMPORTED_LOCATION ${_loc}
IMPORTED_LOCATION_DEBUG ${_loc_debug}
IMPORTED_LOCATION_RELEASE ${_loc_release}
IMPORTED_LOCATION_MINSIZEREL ${_loc_release}
IMPORTED_LOCATION_RELWITHDEBINFO ${_loc_release}
)
endfunction()
function(set_target_imported_implib target libr libd)
set(_loc_debug ${cargo_binary_dir_debug}/${libd})
set(_loc_release ${cargo_binary_dir_release}/${libr})
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(_loc "${_loc_debug}")
else()
set(_loc "${_loc_release}")
endif()
set_target_properties(${target}
PROPERTIES
IMPORTED_GLOBAL TRUE
IMPORTED_IMPLIB ${_loc}
IMPORTED_IMPLIB_DEBUG ${_loc_debug}
IMPORTED_IMPLIB_RELEASE ${_loc_release}
IMPORTED_IMPLIB_MINSIZEREL ${_loc_release}
IMPORTED_IMPLIB_RELWITHDEBINFO ${_loc_release}
)
endfunction()
#
# Setup additional properties for library targets
# *IMPORTANT* any options in this section should be repeated in install/PackageConfig.cmake.in
# to achieve correct behavior of find_package(zenohc)
#
add_library(zenohc_shared SHARED IMPORTED GLOBAL)
add_library(zenohc::shared ALIAS zenohc_shared)
add_dependencies(zenohc_shared cargo)
target_compile_definitions(zenohc_shared INTERFACE ZENOHC_DYN_LIB)
set_target_imported_locations(zenohc_shared ${dylibr} ${dylibd})
add_library(zenohc_static STATIC IMPORTED GLOBAL)
add_library(zenohc::static ALIAS zenohc_static)
add_dependencies(zenohc_static cargo)
get_required_static_libs(NATIVE_STATIC_LIBS)
target_link_libraries(zenohc_static INTERFACE ${NATIVE_STATIC_LIBS})
set_target_imported_locations(zenohc_static ${staticlibr} ${staticlibd})
target_include_directories(zenohc_static INTERFACE ${cargo_generated_include_dir})
set_target_properties(zenohc_static PROPERTIES IMPORTED_GLOBAL TRUE)
if(DEFINED implibr)
set_target_imported_implib(zenohc_shared ${implibr} ${implibd})
endif()
target_include_directories(zenohc_shared INTERFACE ${cargo_generated_include_dir})
set_target_properties(zenohc_shared PROPERTIES IMPORTED_GLOBAL TRUE)
if (BUILD_SHARED_LIBS)
add_library(zenohc::lib ALIAS zenohc_shared)
else()
add_library(zenohc::lib ALIAS zenohc_static)
endif()
#
# Components included only if project is the root project
#
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(install)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${cargo_binary_dir}/tests)
add_subdirectory(tests)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${cargo_binary_dir}/examples)
add_subdirectory(examples)
endif()