-
Notifications
You must be signed in to change notification settings - Fork 12
/
CMakeLists.txt
657 lines (556 loc) · 30.1 KB
/
CMakeLists.txt
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
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
# Copyright 2024 AVSystem <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
################# DEFINITION ###################################################
cmake_minimum_required(VERSION 3.6.0)
project(avs_commons C)
set(AVS_COMMONS_VERSION "5.4.7")
################# DISTRIBUTION #################################################
set(AVS_COMMONS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(AVS_COMMONS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/output")
if(NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
set(AVS_COMMONS_VERSION "${AVS_COMMONS_VERSION}" PARENT_SCOPE)
set(AVS_COMMONS_SOURCE_DIR "${AVS_COMMONS_SOURCE_DIR}" PARENT_SCOPE)
set(AVS_COMMONS_BINARY_DIR "${AVS_COMMONS_BINARY_DIR}" PARENT_SCOPE)
endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${AVS_COMMONS_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${AVS_COMMONS_BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${AVS_COMMONS_BINARY_DIR}/lib")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "AVSystem Commons Library")
set(CPACK_PACKAGE_VENDOR "AVSystem")
set(CPACK_PACKAGE_VERSION "${AVS_COMMONS_VERSION}")
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES
\\\\.a\\$
\\\\.so\\$
\\\\.so\\\\.
/list/avs_list_test\\$
/buffer/avs_buffer_test\\$
/log/avs_log_test\\$
/nbproject
\\\\.log\\$
/CMakeFiles/
/CMakeTmp/
/Makefile\\$
/CMakeCache\\\\.txt\\$
\\\\.cmake\\$
/compile_commands\\\\.json\\$
/install_manifest\\\\.txt\\$
/_CPack_Packages/
/Testing/
\\\\.tar\\\\.gz\\$
\\\\.tgz\\$
\\\\.deb\\$
/\\\\.git)
include(CPack)
add_custom_target(dist COMMAND ${CMAKE_CPACK_COMMAND} --config ${CMAKE_BINARY_DIR}/CPackSourceConfig.cmake WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
################# INITIALIZATION ###############################################
set(WITH_ADDITIONAL_LIBRARY_SUFFIXES "" CACHE STRING "Additional library file name suffixes")
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} ${WITH_ADDITIONAL_LIBRARY_SUFFIXES})
set(CMAKE_USE_RELATIVE_PATHS TRUE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
################# LIBRARIES ####################################################
macro(avs_temp_name fname)
if(${ARGC} GREATER 1) # Have to escape ARGC to correctly compare
set(_base ${ARGV1})
else(${ARGC} GREATER 1)
set(_base ".cmake-tmp")
endif(${ARGC} GREATER 1)
set(_counter 0)
while(EXISTS "${CMAKE_BINARY_DIR}/${_base}${_counter}")
math(EXPR _counter "${_counter} + 1")
endwhile(EXISTS "${CMAKE_BINARY_DIR}/${_base}${_counter}")
set(${fname} "${CMAKE_BINARY_DIR}/${_base}${_counter}")
endmacro()
macro(avs_install_export TNAME CNAME)
get_target_property(_ALIASED_TARGET ${TNAME} ALIASED_TARGET)
if(_ALIASED_TARGET)
# ALIAS targets cannot be exported, and non-global imported targets
# cannot be aliased. So let's create an INTERFACE target instead...
set_property(GLOBAL APPEND_STRING PROPERTY AVS_ALIASED_TARGETS "
if(NOT TARGET ${TNAME} AND TARGET ${_ALIASED_TARGET})
add_library(${TNAME} INTERFACE)
target_link_libraries(${TNAME} INTERFACE ${_ALIASED_TARGET})
endif()")
else()
install(TARGETS ${TNAME} COMPONENT ${CNAME} EXPORT avs_commons-targets DESTINATION ${LIB_INSTALL_DIR})
endif()
endmacro()
macro(avs_eval EXPR)
# CMake does not have an "eval()" like functionality. However, with
# this macro we should be able to simulate it.
avs_temp_name(_fname)
file(WRITE ${_fname} "${EXPR}")
include(${_fname})
file(REMOVE ${_fname})
endmacro()
macro(avs_add_find_routine EXPR)
set_property(GLOBAL APPEND_STRING PROPERTY AVS_LIBRARY_FIND_ROUTINES "
${EXPR}")
endmacro()
macro(avs_find_library EXPR)
avs_eval(${EXPR})
avs_add_find_routine(${EXPR})
endmacro()
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
set(MODULES_ENABLED ON)
else()
set(MODULES_ENABLED OFF)
endif()
if(MODULES_ENABLED OR WITH_TEST)
set(WITH_AVS_UNIT_DEFAULT ON)
else()
set(WITH_AVS_UNIT_DEFAULT OFF)
endif()
option(WITH_AVS_ALGORITHM "AVSystem algorithm utilities library" ${MODULES_ENABLED})
option(WITH_AVS_UNIT "AVSystem unit test library" ${WITH_AVS_UNIT_DEFAULT})
option(WITH_AVS_BUFFER "AVSystem buffer implementation" ${MODULES_ENABLED})
option(WITH_AVS_LIST "AVSystem generic linked list implementation" ${MODULES_ENABLED})
option(WITH_AVS_VECTOR "AVSystem generic vector implementation" ${MODULES_ENABLED})
option(WITH_AVS_UTILS "AVSystem various utility functions" ${MODULES_ENABLED})
option(WITH_AVS_NET "AVSystem network communication abstraction layer" ${MODULES_ENABLED})
option(WITH_AVS_STREAM "AVSystem IO stream abstraction layer" ${MODULES_ENABLED})
option(WITH_AVS_LOG "AVSystem logging framework" ${MODULES_ENABLED})
option(WITH_AVS_RBTREE "AVSystem generic red-black tree implementation" ${MODULES_ENABLED})
option(WITH_AVS_HTTP "AVSystem HTTP client" ${MODULES_ENABLED})
option(WITH_AVS_PERSISTENCE "AVSystem persistence framework" ${MODULES_ENABLED})
option(WITH_AVS_SCHED "AVSystem job scheduler" ${MODULES_ENABLED})
option(WITH_AVS_URL "AVSystem URL handling library" ${MODULES_ENABLED})
option(WITH_AVS_COMPAT_THREADING "Use multithreading utility compatibility layer" ${MODULES_ENABLED})
option(WITH_AVS_CRYPTO "Cryptogaphic functions abstraction layer" ${MODULES_ENABLED})
option(WITH_AVS_MICRO_LOGS "Replaces all invocations of AVS_DISPOSABLE_LOG() with single space. This saves a lot on binary size in applications that log a lot." OFF)
option(WITH_AVS_SORTED_SET "AVSystem wrapper for list and red-black tree implementation" OFF)
include(CMakeDependentOption)
cmake_dependent_option(WITH_INTERNAL_LOGS "Enable logging from inside AVSystem Commons libraries" ON WITH_AVS_LOG OFF)
set(AVS_COMMONS_WITH_INTERNAL_LOGS ${WITH_INTERNAL_LOGS})
cmake_dependent_option(WITH_INTERNAL_TRACE "Enable TRACE-level logs inside AVSystem Commons libraries" OFF "WITH_INTERNAL_LOGS;NOT EXTERNAL_LOG_LEVELS_HEADER" OFF)
set(AVS_COMMONS_WITH_INTERNAL_TRACE ${WITH_INTERNAL_TRACE})
cmake_dependent_option(WITH_MBEDTLS_LOGS "Enable logging from mbedTLS backend library (if used)" OFF "WITH_INTERNAL_LOGS;WITH_MBEDTLS" OFF)
set(AVS_COMMONS_NET_WITH_MBEDTLS_LOGS ${WITH_MBEDTLS_LOGS})
if(WITH_AVS_LOG)
set(AVS_LOG_MAX_LINE_LENGTH 512 CACHE INTEGER "Max length of a single log message. Longer ones will be truncated.")
set(AVS_COMMONS_LOG_MAX_LINE_LENGTH ${AVS_LOG_MAX_LINE_LENGTH})
cmake_dependent_option(AVS_LOG_USE_GLOBAL_BUFFER
"Use global log message buffer instead of allocating one on stack. Reduces stack usage of threads that use avs_log() at the cost of synchronized access to the buffer."
OFF WITH_AVS_COMPAT_THREADING OFF)
set(AVS_COMMONS_LOG_USE_GLOBAL_BUFFER ${AVS_LOG_USE_GLOBAL_BUFFER})
option(WITH_AVS_LOG_DEFAULT_HANDLER "Provide a default avs_log handler that prints log messages on stderr." ON)
set(AVS_COMMONS_LOG_WITH_DEFAULT_HANDLER ${WITH_AVS_LOG_DEFAULT_HANDLER})
set(EXTERNAL_LOG_HEADER_DEFAULT "")
set(EXTERNAL_LOG_HEADER ${EXTERNAL_LOG_HEADER_DEFAULT} CACHE STRING "External log header path, if required")
set(AVS_COMMONS_WITH_EXTERNAL_LOGGER_HEADER "${EXTERNAL_LOG_HEADER}")
set(EXTERNAL_LOG_LEVELS_HEADER_DEFAULT "")
set(EXTERNAL_LOG_LEVELS_HEADER ${EXTERNAL_LOG_LEVELS_HEADER_DEFAULT} CACHE STRING "Excluded logs header path, if required")
set(AVS_COMMONS_WITH_EXTERNAL_LOG_LEVELS_HEADER "${EXTERNAL_LOG_LEVELS_HEADER}")
set(AVS_COMMONS_WITHOUT_LOG_CHECK_IN_RUNTIME ${WITHOUT_LOG_CHECK_IN_RUNTIME})
endif()
cmake_dependent_option(WITH_TEST "Enable unit tests of AVSystem Commons library itself" OFF WITH_AVS_UNIT OFF)
cmake_dependent_option(WITH_CXX_TESTS "Enable C++ unit tests" ON WITH_TEST OFF)
if(WITH_CXX_TESTS)
enable_language(CXX)
endif()
set(POSIX_COMPAT_HEADER_DEFAULT "")
if(WIN32)
set(POSIX_COMPAT_HEADER_DEFAULT "${CMAKE_CURRENT_SOURCE_DIR}/compat/winsock-posix-compat.h")
endif()
set(POSIX_COMPAT_HEADER ${POSIX_COMPAT_HEADER_DEFAULT} CACHE STRING "POSIX compatibility header path, if required")
set(AVS_COMMONS_POSIX_COMPAT_HEADER "${POSIX_COMPAT_HEADER}")
################################################################################
option(WITH_EXTRA_WARNINGS "Enable extra compilation warnings" OFF)
if(WITH_EXTRA_WARNINGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -pedantic -Wall -Wextra -Winit-self -Wmissing-declarations -Wc++-compat -Wsign-conversion -Wconversion -Wcast-qual -Wno-variadic-macros -Wno-long-long -Wvla -Wshadow -Wjump-misses-init")
if(WITH_CXX_TESTS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98 -pedantic -Wall -Wextra -Winit-self -Wmissing-declarations -Wsign-conversion -Wconversion -Wcast-qual -Wno-variadic-macros -Wno-long-long")
endif()
endif()
if(WITH_TEST)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftrapv")
endif()
option(WITH_POISONING "Poison libc symbols that shall not be used" ${WITH_TEST})
if(CMAKE_C_COMPILE_OPTIONS_PIC)
option(WITH_PIC "Generate position-independent code" ON)
if(WITH_PIC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_COMPILE_OPTIONS_PIC}")
if(WITH_CXX_TESTS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_COMPILE_OPTIONS_PIC}")
endif()
endif()
endif()
# -fvisibility, #pragma GCC visibility
if(NOT DEFINED AVS_COMMONS_HAVE_VISIBILITY)
file(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/visibility.c "#pragma GCC visibility push(default)\nint f();\n#pragma GCC visibility push(hidden)\nint f() { return 0; }\n#pragma GCC visibility pop\nint main() { return f(); }\n\n")
try_compile(AVS_COMMONS_HAVE_VISIBILITY
${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp
${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/visibility.c
COMPILE_DEFINITIONS -Wall -Wextra -Werror -fvisibility=default)
endif()
if(NOT DEFINED AVS_COMMONS_HAVE_PRAGMA_DIAGNOSTIC)
file(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/diagnostic.c "#pragma GCC diagnostic ignored \"-Wformat\"\nint main(){}\n\n")
try_compile(AVS_COMMONS_HAVE_PRAGMA_DIAGNOSTIC
${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp
${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/diagnostic.c
COMPILE_DEFINITIONS -Werror)
endif()
# Check for builtin GCC/Clang safe arithmetic functions
# we need to use try_compile to attempt linking
# as they might not work on Clang if -rtlib=compiler-rt is not set
if(NOT DEFINED AVS_COMMONS_HAVE_BUILTIN_ADD_OVERFLOW)
file(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/builtin_add_overflow.c "#include <stdint.h>\n__attribute__((optimize(\"-fno-trapv\"))) int main() { int64_t a=0,b=0,c=0; return __builtin_add_overflow(a, b, &c); }\n")
try_compile(AVS_COMMONS_HAVE_BUILTIN_ADD_OVERFLOW ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/builtin_add_overflow.c)
endif()
if(NOT DEFINED AVS_COMMONS_HAVE_BUILTIN_MUL_OVERFLOW)
file(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/builtin_mul_overflow.c "#include <stdint.h>\n__attribute__((optimize(\"-fno-trapv\"))) int main() { int64_t a=0,b=0,c=0; return __builtin_mul_overflow(a, b, &c); }\n")
try_compile(AVS_COMMONS_HAVE_BUILTIN_MUL_OVERFLOW ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/builtin_mul_overflow.c)
endif()
# C11 stdatomic
if(NOT DEFINED HAVE_C11_STDATOMIC)
file(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/c11_stdatomic.c "#include <stdatomic.h>\nint main() { volatile atomic_flag a = ATOMIC_FLAG_INIT; return atomic_flag_test_and_set(&a); }\n")
try_compile(HAVE_C11_STDATOMIC ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/c11_stdatomic.c)
endif()
include(${CMAKE_CURRENT_LIST_DIR}/cmake/PosixFeatures.cmake)
include(TestBigEndian)
test_big_endian(AVS_COMMONS_BIG_ENDIAN)
include(CheckFunctionExists)
check_function_exists(backtrace_symbols HAVE_BACKTRACE_SYMBOLS)
if(HAVE_BACKTRACE_SYMBOLS)
check_function_exists(backtrace AVS_COMMONS_UNIT_POSIX_HAVE_BACKTRACE)
else()
set(AVS_COMMONS_UNIT_POSIX_HAVE_BACKTRACE 0)
endif()
include(CheckSymbolExists)
if(NOT HAVE_MATH_LIBRARY)
foreach(MATH_LIBRARY_IT "" "m")
file(WRITE ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/fmod.c "#include <math.h>\nint main() { volatile double a = 4.0, b = 3.2; return (int) fmod(a, b); }\n\n")
try_compile(HAVE_MATH_LIBRARY ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp/fmod.c CMAKE_FLAGS "-DLINK_LIBRARIES=${MATH_LIBRARY_IT}")
if(HAVE_MATH_LIBRARY)
set(MATH_LIBRARY "${MATH_LIBRARY_IT}" CACHE STRING "Library that provides C math functions. Can be empty if no extra library is required." FORCE)
break()
endif()
endforeach()
if(NOT HAVE_MATH_LIBRARY)
message(FATAL_ERROR "Floating-point math functions not available")
endif()
endif()
if(NOT DEFINED AVS_COMMONS_HAVE_DLSYM)
# On Linux, one needs to link libdl to use dlsym(). On BSD, it is not necessary,
# and even harmful, since libdl does not exist.
set(DETECTED_DLSYM_LIBRARY "" CACHE STRING "" FORCE)
set(CMAKE_REQUIRED_INCLUDES "dlfcn.h")
foreach(lib "" dl)
message(STATUS "Looking for dlsym() in library: ${lib}")
set(CMAKE_REQUIRED_LIBRARIES ${lib})
# check_function_exists caches its result; make sure the check is
# actually repeated for each lib
unset(AVS_COMMONS_HAVE_DLSYM CACHE)
check_function_exists(dlsym AVS_COMMONS_HAVE_DLSYM)
set(CMAKE_REQUIRED_LIBRARIES)
if(AVS_COMMONS_HAVE_DLSYM)
set(DETECTED_DLSYM_LIBRARY "${lib}" CACHE STRING "" FORCE)
break()
endif()
endforeach()
set(CMAKE_REQUIRED_INCLUDES)
endif()
set(DLSYM_LIBRARY "${DETECTED_DLSYM_LIBRARY}" CACHE STRING "Name of the library containing dlsym() symbol")
option(WITH_IPV4 "Enable IPv4 support" ON)
option(WITH_IPV6 "Enable IPv6 support" ON)
option(WITH_SOCKET_LOG "Enable socket communication logging" OFF)
set(AVS_COMMONS_NET_WITH_SOCKET_LOG ${WITH_SOCKET_LOG})
option(WITHOUT_64BIT_FORMAT_SPECIFIERS "Disable using 64-bit format specifiers in printf/scanf" OFF)
set(AVS_COMMONS_WITHOUT_64BIT_FORMAT_SPECIFIERS ${WITHOUT_64BIT_FORMAT_SPECIFIERS})
option(WITHOUT_FLOAT_FORMAT_SPECIFIERS "Disable using floating-point format specifiers in printf/scanf" OFF)
set(AVS_COMMONS_WITHOUT_FLOAT_FORMAT_SPECIFIERS ${WITHOUT_FLOAT_FORMAT_SPECIFIERS})
find_program(VALGRIND_EXECUTABLE valgrind)
# This is enabled in devconfig only, and should be disabled in CMakeLists.txt,
# to avoid cross-compilation errors on stations with valgrind installed.
cmake_dependent_option(WITH_VALGRIND "Enable usage of valgrind during unit tests" OFF VALGRIND_EXECUTABLE OFF)
set(AVS_COMMONS_WITH_AVS_CRYPTO_VALGRIND ${WITH_VALGRIND})
if(WITH_VALGRIND)
execute_process(COMMAND ${VALGRIND_EXECUTABLE} --tool=helgrind --version
RESULT_VARIABLE HELGRIND_TEST_RESULT
OUTPUT_QUIET ERROR_QUIET)
if(HELGRIND_TEST_RESULT EQUAL 0)
option(WITH_HELGRIND "Put valgrind in helgrind mode (test for race conditions instead of memory errors)" OFF)
endif()
if(WITH_HELGRIND)
set(VALGRIND_ARGS --tool=helgrind)
else()
set(VALGRIND_ARGS --leak-check=full --track-origins=yes --errors-for-leak-kinds=definite)
endif()
set(VALGRIND ${VALGRIND_EXECUTABLE} ${VALGRIND_ARGS} -q --error-exitcode=63 --suppressions=${CMAKE_CURRENT_SOURCE_DIR}/avs_commons_test.valgrind.supp)
endif()
enable_testing()
if(NOT LIB_INSTALL_DIR)
set(LIB_INSTALL_DIR lib)
endif()
if(NOT INCLUDE_INSTALL_DIR)
set(INCLUDE_INSTALL_DIR include)
endif()
include_directories($<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
add_library(avs_commons_global_headers INTERFACE)
target_include_directories(avs_commons_global_headers INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include_public>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include_public>
$<INSTALL_INTERFACE:include>)
avs_install_export(avs_commons_global_headers global_headers)
set(MODULE_INCLUDE_DIRS)
# Named arguments:
# PATH - relative path to the module subdirectory. If not given, NAME is used instead.
# NAME - module name, used as a substring of output library name and Makefile targets
# INCLUDE_DIRS_VAR - name of the variable to append module include dirs to. If not set,
# MODULE_INCLUDE_DIRS is assumed.
function(add_module_with_include_dirs)
set(options)
set(one_value_args PATH NAME INCLUDE_DIRS_VAR)
set(multi_value_args)
cmake_parse_arguments(AMWID "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
if(NOT DEFINED AMWID_NAME)
message(FATAL_ERROR "Required argument NAME not given")
endif()
if(NOT DEFINED AMWID_PATH)
set(AMWID_PATH "src/${AMWID_NAME}")
endif()
if(NOT DEFINED INCLUDE_DIRS_VAR)
set(AMWID_INCLUDE_DIRS_VAR MODULE_INCLUDE_DIRS)
endif()
string(TOUPPER "${AMWID_NAME}" AMWID_NAME_UPPER)
set(AVS_COMMONS_WITH_AVS_${AMWID_NAME_UPPER} "${WITH_AVS_${AMWID_NAME_UPPER}}" PARENT_SCOPE)
if(WITH_AVS_${AMWID_NAME_UPPER})
add_subdirectory(${AMWID_PATH})
# Append module includes to a specified variable name (i.e. MODULE_INCLUDE_DIRS_VAR).
set(${AMWID_INCLUDE_DIRS_VAR}
${${AMWID_INCLUDE_DIRS_VAR}}
$<TARGET_PROPERTY:${AMWID_NAME},INTERFACE_INCLUDE_DIRECTORIES>
PARENT_SCOPE)
if(TARGET avs_${AMWID_NAME}_check)
add_test(NAME test_avs_${AMWID_NAME}_symbols
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test_symbols.sh $<TARGET_FILE:avs_${AMWID_NAME}> avs_ AVS_ _avs _AVS_ "__odr_asan[.]")
add_dependencies(avs_commons_symbols_check avs_${AMWID_NAME})
endif()
file(GLOB_RECURSE MODULE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${AMWID_PATH}/*.c
${CMAKE_CURRENT_SOURCE_DIR}/${AMWID_PATH}/*.h)
foreach(F ${MODULE_FILES})
add_test(NAME test_${F}_visibility COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test_visibility.py ${F})
add_test(NAME test_${F}_headers
COMMAND ./test_headers.py ${F} conditional_headers_whitelist.json
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endforeach()
endif()
endfunction()
add_module_with_include_dirs(NAME unit)
if(WITH_TEST)
if(NOT WITH_AVS_UNIT)
message(FATAL_ERROR "WITH_TEST requires WITH_AVS_UNIT to be enabled")
endif()
if(NOT EXISTS "${AVS_COMMONS_BINARY_DIR}/certs/client.crt.der")
execute_process(COMMAND
env bash
"${CMAKE_CURRENT_SOURCE_DIR}/tools/generate-certs.sh"
"${AVS_COMMONS_BINARY_DIR}/certs"
RESULT_VARIABLE RES)
if(NOT ${RES} EQUAL 0)
message(FATAL_ERROR "could not generate SSL certificates")
endif()
endif()
add_custom_target(avs_commons_check)
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
add_custom_target(check)
add_dependencies(check avs_commons_check)
endif()
# license check is only possible if running in a Git working tree
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
add_custom_target(license_check COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/license_headers.py"
--root "${CMAKE_CURRENT_SOURCE_DIR}")
add_dependencies(avs_commons_check license_check)
endif()
add_custom_target(avs_commons_extern_c_check COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/check_extern_c.py")
add_dependencies(avs_commons_check avs_commons_extern_c_check)
add_custom_target(avs_commons_symbols_check COMMAND ${CMAKE_CTEST_COMMAND} -R "'^test_.*_symbols$$'" --output-on-failure)
add_dependencies(avs_commons_check avs_commons_symbols_check)
add_custom_target(avs_commons_visibility_check COMMAND ${CMAKE_CTEST_COMMAND} -R "'^test_.*_visibility$$'")
add_dependencies(avs_commons_check avs_commons_visibility_check)
add_custom_target(avs_commons_headers_check COMMAND ${CMAKE_CTEST_COMMAND} -R "'^test_.*_headers$$'")
add_dependencies(avs_commons_check avs_commons_headers_check)
add_custom_target(avs_commons_filename_check
COMMAND ! find src include_public -name "'*.[ch]'" | sed -e "'s|^.*/||'" | grep -v "'^avs_'" | grep -v "'^pkcs11.\\?\\.h'"
COMMAND ! find src include_public -name "'*.[ch]'" | sed -e "'s|^.*/||'" | sort | uniq -c | grep -v "'^ *1 '"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
add_dependencies(avs_commons_check avs_commons_filename_check)
add_custom_target(avs_install_test
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/test-install.sh"
"${CMAKE_CURRENT_SOURCE_DIR}/tests/install")
set(_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
# NAME - test target name, without _test suffix
# LIBS - libs to link to
# SOURCES - test sources
function(avs_add_test)
set(options)
set(one_value_args NAME)
set(multi_value_args LIBS SOURCES VALGRIND_ARGS COMPILE_DEFINITIONS ENVIRONMENT)
cmake_parse_arguments(AAT "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
add_executable(${AAT_NAME}_test EXCLUDE_FROM_ALL
${AAT_SOURCES})
target_link_libraries(${AAT_NAME}_test PRIVATE avs_unit ${AAT_LIBS})
target_include_directories(${AAT_NAME}_test PRIVATE "${AVS_COMMONS_SOURCE_DIR}")
set_property(TARGET ${AAT_NAME}_test APPEND PROPERTY COMPILE_DEFINITIONS AVS_UNIT_TESTING ${AAT_COMPILE_DEFINITIONS})
set_property(TARGET ${AAT_NAME}_test APPEND PROPERTY COMPILE_FLAGS
"-Wno-clobbered -Wno-overlength-strings -Wno-sign-conversion -Wno-vla")
if(VALGRIND)
file(MAKE_DIRECTORY "${AVS_COMMONS_BINARY_DIR}/log")
set(VALGRIND_CMD ${VALGRIND} "--log-file=${AVS_COMMONS_BINARY_DIR}/log/VALGRIND.${AAT_NAME}.log" ${AAT_VALGRIND_ARGS})
else()
set(VALGRIND_CMD)
endif()
add_test(NAME ${AAT_NAME}_test
COMMAND ${VALGRIND_CMD} $<TARGET_FILE:${AAT_NAME}_test>
WORKING_DIRECTORY $<TARGET_FILE_DIR:${AAT_NAME}_test>)
set_property(TEST ${AAT_NAME}_test APPEND PROPERTY ENVIRONMENT
"ASAN_OPTIONS=allocator_may_return_null=1"
"LSAN_OPTIONS=suppressions=${AVS_COMMONS_SOURCE_DIR}/avs_commons_test.lsan.supp"
${AAT_ENVIRONMENT})
add_custom_target(${AAT_NAME}_check COMMAND ${CMAKE_CTEST_COMMAND} -V -R "^${AAT_NAME}_test$" DEPENDS ${AAT_NAME}_test)
add_dependencies(avs_commons_check ${AAT_NAME}_check)
endfunction()
else(WITH_TEST)
function(avs_add_test)
endfunction()
endif(WITH_TEST)
# SSL
find_package(OpenSSL)
option(WITH_OPENSSL "Enable OpenSSL" ${OPENSSL_FOUND})
set(AVS_COMMONS_WITH_OPENSSL ${WITH_OPENSSL})
set(MBEDTLS_ROOT_DIR "" CACHE STRING "mbed TLS installation directory")
find_package(MbedTLS)
option(WITH_MBEDTLS "Enable mbed TLS" ${MBEDTLS_FOUND})
set(AVS_COMMONS_WITH_MBEDTLS ${WITH_MBEDTLS})
set(TINYDTLS_ROOT_DIR "/usr" CACHE STRING "TinyDTLS installation root directory")
find_package(TinyDTLS)
option(WITH_TINYDTLS "Enable tinyDTLS" ${TINYDTLS_FOUND})
set(AVS_COMMONS_WITH_TINYDTLS ${WITH_TINYDTLS})
option(WITH_CUSTOM_TLS "Enable support for custom TLS socket implementation" OFF)
set(AVS_COMMONS_WITH_CUSTOM_TLS ${WITH_CUSTOM_TLS})
cmake_dependent_option(WITH_PSK "Enable pre-shared key support" ON "WITH_OPENSSL OR WITH_MBEDTLS OR WITH_TINYDTLS OR WITH_CUSTOM_TLS" OFF)
set(AVS_COMMONS_WITH_AVS_CRYPTO_PSK ${WITH_PSK})
if(DEFINED WITH_X509)
message(FATAL_ERROR "WITH_X509 has been removed since avs_commons 5.0. Please use WITH_PKI instead.")
endif()
cmake_dependent_option(WITH_PKI "Enable X.509 certificate support" ON "WITH_OPENSSL OR WITH_MBEDTLS OR WITH_TINYDTLS OR WITH_CUSTOM_TLS" OFF)
set(AVS_COMMONS_WITH_AVS_CRYPTO_PKI ${WITH_PKI})
# Hardware security engines
if(DEFINED WITH_AVS_CRYPTO_ENGINE)
message(FATAL_ERROR "WITH_AVS_CRYPTO_ENGINE has been removed since avs_commons 5.0. Please use WITH_AVS_CRYPTO_PKI_ENGINE instead.")
endif()
cmake_dependent_option(WITH_AVS_CRYPTO_PKI_ENGINE "Enable hardware-based PKI engine support" OFF
"WITH_OPENSSL OR WITH_MBEDTLS OR WITH_CUSTOM_TLS;WITH_PKI" OFF)
set(AVS_COMMONS_WITH_AVS_CRYPTO_PKI_ENGINE ${WITH_AVS_CRYPTO_PKI_ENGINE})
cmake_dependent_option(WITH_AVS_CRYPTO_PSK_ENGINE "Enable hardware-based PSK engine support" OFF "WITH_MBEDTLS OR WITH_CUSTOM_TLS;WITH_PSK" OFF)
set(AVS_COMMONS_WITH_AVS_CRYPTO_PSK_ENGINE ${WITH_AVS_CRYPTO_PSK_ENGINE})
if(WITH_OPENSSL)
avs_add_find_routine("find_package(OpenSSL REQUIRED)")
endif()
if(WITH_MBEDTLS)
set(INSTALLED_MBEDTLS_ROOT_DIR "")
if(MBEDTLS_ROOT_DIR)
# If mbed TLS has been imported from a non-standard location while
# compiling avs_commons, let's assume that both libraries are going to
# be installed into the same sysroot
set(INSTALLED_MBEDTLS_ROOT_DIR "\\\${CMAKE_CURRENT_LIST_DIR}/../..")
endif()
avs_add_find_routine("
set(CMAKE_MODULE_PATH \\\${CMAKE_MODULE_PATH} \"\\\${CMAKE_CURRENT_LIST_DIR}/cmake\")
# Assume mbed TLS is installed to the same root as avs_commons
set(MBEDTLS_ROOT_DIR \"${INSTALLED_MBEDTLS_ROOT_DIR}\" CACHE STRING \"mbed TLS installation directory\")
set(MBEDTLS_USE_STATIC_LIBS ${MBEDTLS_USE_STATIC_LIBS} CACHE BOOL \"Force static versoin of mbed TLS\")
find_package(MbedTLS REQUIRED)")
endif()
if(WITH_TINYDTLS)
avs_add_find_routine("
set(TINYDTLS_ROOT_DIR \"${TINYDTLS_ROOT_DIR}\" CACHE STRING \"TinyDTLS installation directory\")
find_package(TinyDTLS REQUIRED)
")
endif()
add_module_with_include_dirs(NAME algorithm)
add_module_with_include_dirs(NAME buffer)
add_module_with_include_dirs(NAME list)
add_module_with_include_dirs(NAME vector)
add_module_with_include_dirs(NAME utils)
add_module_with_include_dirs(NAME net)
add_module_with_include_dirs(NAME stream)
add_module_with_include_dirs(NAME log)
add_module_with_include_dirs(NAME rbtree)
add_module_with_include_dirs(NAME sorted_set)
add_module_with_include_dirs(NAME sched)
add_module_with_include_dirs(NAME url)
cmake_dependent_option(WITH_AVS_HTTP_ZLIB
"Enable support for HTTP compression using zlib"
ON WITH_AVS_HTTP OFF)
set(AVS_COMMONS_HTTP_WITH_ZLIB ${WITH_AVS_HTTP_ZLIB})
add_module_with_include_dirs(NAME http)
add_module_with_include_dirs(NAME persistence)
add_module_with_include_dirs(NAME compat_threading
PATH src/compat/threading)
add_module_with_include_dirs(NAME crypto)
# API documentation
set(DOXYGEN_SKIP_DOT TRUE)
find_package(Doxygen)
if(DOXYGEN_FOUND)
set(DOXYGEN_INPUT_PATHS ${AVS_COMMONS_SOURCE_DIR}/include_public)
configure_file(${AVS_COMMONS_SOURCE_DIR}/doc/Doxyfile.in
${AVS_COMMONS_BINARY_DIR}/doc/Doxyfile
@ONLY)
add_custom_target(avs_commons_doc
COMMAND ${DOXYGEN_EXECUTABLE} ${AVS_COMMONS_BINARY_DIR}/doc/Doxyfile)
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
add_custom_target(doc)
add_dependencies(doc avs_commons_doc)
endif()
endif()
# Export general avs_commons includes as well as module level includes.
if(NOT ${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
set(avs_commons_INCLUDE_DIRS ${INCLUDE_DIRS} ${MODULE_INCLUDE_DIRS} PARENT_SCOPE)
endif()
set(AVS_COMMONS_NET_WITH_IPV4 "${WITH_IPV4}")
set(AVS_COMMONS_NET_WITH_IPV6 "${WITH_IPV6}")
set(AVS_COMMONS_NET_WITH_DTLS "${WITH_DTLS}")
set(AVS_COMMONS_NET_WITH_POSIX_AVS_SOCKET "${WITH_POSIX_AVS_SOCKET}")
set(AVS_COMMONS_NET_POSIX_AVS_SOCKET_WITHOUT_IN6_V4MAPPED_SUPPORT "${WITHOUT_IN6_V4MAPPED_SUPPORT}")
set(AVS_COMMONS_NET_WITH_TLS_SESSION_PERSISTENCE "${WITH_TLS_SESSION_PERSISTENCE}")
set(AVS_COMMONS_SCHED_THREAD_SAFE "${WITH_SCHEDULER_THREAD_SAFE}")
set(AVS_COMMONS_STREAM_WITH_FILE "${WITH_AVS_STREAM_FILE}")
set(AVS_COMMONS_UTILS_WITH_POSIX_AVS_TIME "${WITH_POSIX_AVS_TIME}")
set(AVS_COMMONS_UTILS_WITH_STANDARD_ALLOCATOR "${WITH_STANDARD_ALLOCATOR}")
set(AVS_COMMONS_UTILS_WITH_ALIGNFIX_ALLOCATOR "${WITH_ALIGNFIX_ALLOCATOR}")
set(AVS_COMMONS_WITH_MICRO_LOGS "${WITH_AVS_MICRO_LOGS}")
set(AVS_COMMONS_WITH_POISONING "${WITH_POISONING}")
configure_file("include_public/avsystem/commons/avs_commons_config.h.in"
"include_public/avsystem/commons/avs_commons_config.h")
get_property(LIBRARY_FIND_ROUTINES GLOBAL PROPERTY AVS_LIBRARY_FIND_ROUTINES)
get_property(ALIASED_TARGETS GLOBAL PROPERTY AVS_ALIASED_TARGETS)
configure_file(avs_commons-config.cmake.in avs_commons-config.cmake @ONLY)
configure_file(avs_commons-version.cmake.in avs_commons-version.cmake @ONLY)
install(EXPORT avs_commons-targets DESTINATION ${LIB_INSTALL_DIR}/avs_commons)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/avs_commons-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/avs_commons-version.cmake
DESTINATION ${LIB_INSTALL_DIR}/avs_commons)
install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindMbedTLS.cmake
${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindTinyDTLS.cmake
DESTINATION ${LIB_INSTALL_DIR}/avs_commons/cmake)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/include_public/avsystem/commons/avs_commons_config.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include_public/avsystem/commons/avs_defs.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include_public/avsystem/commons/avs_errno.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include_public/avsystem/commons/avs_errno_map.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include_public/avsystem/commons/avs_sorted_set.h"
DESTINATION "${INCLUDE_INSTALL_DIR}/avsystem/commons")