1# number of parallel jobs for CTest 2set(N 10) 3 4############################################################################### 5# Needed tools. 6############################################################################### 7 8include(FindPython3) 9find_package(Python3 COMPONENTS Interpreter) 10 11find_program(ASTYLE_TOOL NAMES astyle) 12execute_process(COMMAND ${ASTYLE_TOOL} --version OUTPUT_VARIABLE ASTYLE_TOOL_VERSION ERROR_VARIABLE ASTYLE_TOOL_VERSION) 13string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" ASTYLE_TOOL_VERSION "${ASTYLE_TOOL_VERSION}") 14message(STATUS " Artistic Style ${ASTYLE_TOOL_VERSION} (${ASTYLE_TOOL})") 15 16find_program(CLANG_TOOL NAMES clang++-HEAD clang++ clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++) 17execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION) 18string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}") 19message(STATUS " Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})") 20 21find_program(CLANG_TIDY_TOOL NAMES clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy) 22execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION) 23string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}") 24message(STATUS " Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})") 25 26message(STATUS " CMake ${CMAKE_VERSION} (${CMAKE_COMMAND})") 27 28find_program(CPPCHECK_TOOL NAMES cppcheck) 29execute_process(COMMAND ${CPPCHECK_TOOL} --version OUTPUT_VARIABLE CPPCHECK_TOOL_VERSION ERROR_VARIABLE CPPCHECK_TOOL_VERSION) 30string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CPPCHECK_TOOL_VERSION "${CPPCHECK_TOOL_VERSION}") 31message(STATUS " Cppcheck ${CPPCHECK_TOOL_VERSION} (${CPPCHECK_TOOL})") 32 33find_program(GCC_TOOL NAMES g++-latest g++-HEAD g++-13 g++-12 g++-11 g++-10) 34execute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION) 35string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}") 36message(STATUS " GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})") 37 38find_program(GCOV_TOOL NAMES gcov-HEAD gcov-11 gcov-10 gcov) 39execute_process(COMMAND ${GCOV_TOOL} --version OUTPUT_VARIABLE GCOV_TOOL_VERSION ERROR_VARIABLE GCOV_TOOL_VERSION) 40string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCOV_TOOL_VERSION "${GCOV_TOOL_VERSION}") 41message(STATUS " GCOV ${GCOV_TOOL_VERSION} (${GCOV_TOOL})") 42 43find_program(GIT_TOOL NAMES git) 44execute_process(COMMAND ${GIT_TOOL} --version OUTPUT_VARIABLE GIT_TOOL_VERSION ERROR_VARIABLE GIT_TOOL_VERSION) 45string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GIT_TOOL_VERSION "${GIT_TOOL_VERSION}") 46message(STATUS " Git ${GIT_TOOL_VERSION} (${GIT_TOOL})") 47 48find_program(IWYU_TOOL NAMES include-what-you-use iwyu) 49execute_process(COMMAND ${IWYU_TOOL} --version OUTPUT_VARIABLE IWYU_TOOL_VERSION ERROR_VARIABLE IWYU_TOOL_VERSION) 50string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" IWYU_TOOL_VERSION "${IWYU_TOOL_VERSION}") 51message(STATUS " include-what-you-use ${IWYU_TOOL_VERSION} (${IWYU_TOOL})") 52 53find_program(INFER_TOOL NAMES infer) 54execute_process(COMMAND ${INFER_TOOL} --version OUTPUT_VARIABLE INFER_TOOL_VERSION ERROR_VARIABLE INFER_TOOL_VERSION) 55string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" INFER_TOOL_VERSION "${INFER_TOOL_VERSION}") 56message(STATUS " Infer ${INFER_TOOL_VERSION} (${INFER_TOOL})") 57 58find_program(LCOV_TOOL NAMES lcov) 59execute_process(COMMAND ${LCOV_TOOL} --version OUTPUT_VARIABLE LCOV_TOOL_VERSION ERROR_VARIABLE LCOV_TOOL_VERSION) 60string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" LCOV_TOOL_VERSION "${LCOV_TOOL_VERSION}") 61message(STATUS " LCOV ${LCOV_TOOL_VERSION} (${LCOV_TOOL})") 62 63find_program(NINJA_TOOL NAMES ninja) 64execute_process(COMMAND ${NINJA_TOOL} --version OUTPUT_VARIABLE NINJA_TOOL_VERSION ERROR_VARIABLE NINJA_TOOL_VERSION) 65string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" NINJA_TOOL_VERSION "${NINJA_TOOL_VERSION}") 66message(STATUS " Ninja ${NINJA_TOOL_VERSION} (${NINJA_TOOL})") 67 68find_program(OCLINT_TOOL NAMES oclint-json-compilation-database) 69find_program(OCLINT_VERSION_TOOL NAMES oclint) 70execute_process(COMMAND ${OCLINT_VERSION_TOOL} --version OUTPUT_VARIABLE OCLINT_TOOL_VERSION ERROR_VARIABLE OCLINT_TOOL_VERSION) 71string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" OCLINT_TOOL_VERSION "${OCLINT_TOOL_VERSION}") 72message(STATUS " OCLint ${OCLINT_TOOL_VERSION} (${OCLINT_TOOL})") 73 74find_program(VALGRIND_TOOL NAMES valgrind) 75execute_process(COMMAND ${VALGRIND_TOOL} --version OUTPUT_VARIABLE VALGRIND_TOOL_VERSION ERROR_VARIABLE VALGRIND_TOOL_VERSION) 76string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" VALGRIND_TOOL_VERSION "${VALGRIND_TOOL_VERSION}") 77message(STATUS " Valgrind ${VALGRIND_TOOL_VERSION} (${VALGRIND_TOOL})") 78 79find_program(GENHTML_TOOL NAMES genhtml) 80find_program(PLOG_CONVERTER_TOOL NAMES plog-converter) 81find_program(PVS_STUDIO_ANALYZER_TOOL NAMES pvs-studio-analyzer) 82find_program(SCAN_BUILD_TOOL NAMES scan-build-15 scan-build-14 scan-build-13 scan-build-12 scan-build-11 scan-build) 83 84# the individual source files 85file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp) 86 87############################################################################### 88# Thorough check with recent compilers 89############################################################################### 90 91# Ignored Clang warnings: 92# -Wno-c++98-compat The library targets C++11. 93# -Wno-c++98-compat-pedantic The library targets C++11. 94# -Wno-deprecated-declarations The library contains annotations for deprecated functions. 95# -Wno-extra-semi-stmt The library uses std::assert which triggers this warning. 96# -Wno-padded We do not care about padding warnings. 97# -Wno-covered-switch-default All switches list all cases and a default case. 98# -Wno-unsafe-buffer-usage Otherwise Doctest would not compile. 99# -Wno-weak-vtables The library is header-only. 100# -Wreserved-identifier See https://github.com/onqtam/doctest/issues/536. 101 102set(CLANG_CXXFLAGS 103 -Werror 104 -Weverything 105 -Wno-c++98-compat 106 -Wno-c++98-compat-pedantic 107 -Wno-deprecated-declarations 108 -Wno-extra-semi-stmt 109 -Wno-padded 110 -Wno-covered-switch-default 111 -Wno-unsafe-buffer-usage 112 -Wno-weak-vtables 113 -Wno-reserved-identifier 114) 115 116# Warning flags determined for GCC 13.0 (experimental) with https://github.com/nlohmann/gcc_flags: 117# Ignored GCC warnings: 118# -Wno-abi-tag We do not care about ABI tags. 119# -Wno-aggregate-return The library uses aggregate returns. 120# -Wno-long-long The library uses the long long type to interface with system functions. 121# -Wno-namespaces The library uses namespaces. 122# -Wno-padded We do not care about padding warnings. 123# -Wno-system-headers We do not care about warnings in system headers. 124# -Wno-templates The library uses templates. 125 126set(GCC_CXXFLAGS 127 -pedantic 128 -Werror 129 --all-warnings 130 --extra-warnings 131 -W 132 -WNSObject-attribute 133 -Wno-abi-tag 134 -Waddress 135 -Waddress-of-packed-member 136 -Wno-aggregate-return 137 -Waggressive-loop-optimizations 138 -Waligned-new=all 139 -Wall 140 -Walloc-zero 141 -Walloca 142 -Wanalyzer-double-fclose 143 -Wanalyzer-double-free 144 -Wanalyzer-exposure-through-output-file 145 -Wanalyzer-file-leak 146 -Wanalyzer-free-of-non-heap 147 -Wanalyzer-malloc-leak 148 -Wanalyzer-mismatching-deallocation 149 -Wanalyzer-null-argument 150 -Wanalyzer-null-dereference 151 -Wanalyzer-possible-null-argument 152 -Wanalyzer-possible-null-dereference 153 -Wanalyzer-shift-count-negative 154 -Wanalyzer-shift-count-overflow 155 -Wanalyzer-stale-setjmp-buffer 156 -Wanalyzer-tainted-allocation-size 157 -Wanalyzer-tainted-array-index 158 -Wanalyzer-tainted-divisor 159 -Wanalyzer-tainted-offset 160 -Wanalyzer-tainted-size 161 -Wanalyzer-too-complex 162 -Wanalyzer-unsafe-call-within-signal-handler 163 -Wanalyzer-use-after-free 164 -Wanalyzer-use-of-pointer-in-stale-stack-frame 165 -Wanalyzer-use-of-uninitialized-value 166 -Wanalyzer-va-arg-type-mismatch 167 -Wanalyzer-va-list-exhausted 168 -Wanalyzer-va-list-leak 169 -Wanalyzer-va-list-use-after-va-end 170 -Wanalyzer-write-to-const 171 -Wanalyzer-write-to-string-literal 172 -Warith-conversion 173 -Warray-bounds=2 174 -Warray-compare 175 -Warray-parameter=2 176 -Wattribute-alias=2 177 -Wattribute-warning 178 -Wattributes 179 -Wbool-compare 180 -Wbool-operation 181 -Wbuiltin-declaration-mismatch 182 -Wbuiltin-macro-redefined 183 -Wc++0x-compat 184 -Wc++11-compat 185 -Wc++11-extensions 186 -Wc++14-compat 187 -Wc++14-extensions 188 -Wc++17-compat 189 -Wc++17-extensions 190 -Wc++1z-compat 191 -Wc++20-compat 192 -Wc++20-extensions 193 -Wc++23-extensions 194 -Wc++2a-compat 195 -Wcannot-profile 196 -Wcast-align 197 -Wcast-align=strict 198 -Wcast-function-type 199 -Wcast-qual 200 -Wcatch-value=3 201 -Wchar-subscripts 202 -Wclass-conversion 203 -Wclass-memaccess 204 -Wclobbered 205 -Wcomma-subscript 206 -Wcomment 207 -Wcomments 208 -Wconditionally-supported 209 -Wconversion 210 -Wconversion-null 211 -Wcoverage-invalid-line-number 212 -Wcoverage-mismatch 213 -Wcpp 214 -Wctad-maybe-unsupported 215 -Wctor-dtor-privacy 216 -Wdangling-else 217 -Wdangling-pointer=2 218 -Wdate-time 219 -Wdelete-incomplete 220 -Wdelete-non-virtual-dtor 221 -Wdeprecated 222 -Wdeprecated-copy 223 -Wdeprecated-copy-dtor 224 -Wdeprecated-declarations 225 -Wdeprecated-enum-enum-conversion 226 -Wdeprecated-enum-float-conversion 227 -Wdisabled-optimization 228 -Wdiv-by-zero 229 -Wdouble-promotion 230 -Wduplicated-branches 231 -Wduplicated-cond 232 -Weffc++ 233 -Wempty-body 234 -Wendif-labels 235 -Wenum-compare 236 -Wenum-conversion 237 -Wexceptions 238 -Wexpansion-to-defined 239 -Wextra 240 -Wextra-semi 241 -Wfloat-conversion 242 -Wfloat-equal 243 -Wformat-diag 244 -Wformat-overflow=2 245 -Wformat-signedness 246 -Wformat-truncation=2 247 -Wformat=2 248 -Wframe-address 249 -Wfree-nonheap-object 250 -Whsa 251 -Wif-not-aligned 252 -Wignored-attributes 253 -Wignored-qualifiers 254 -Wimplicit-fallthrough=5 255 -Winaccessible-base 256 -Winfinite-recursion 257 -Winherited-variadic-ctor 258 -Winit-list-lifetime 259 -Winit-self 260 -Winline 261 -Wint-in-bool-context 262 -Wint-to-pointer-cast 263 -Winterference-size 264 -Winvalid-imported-macros 265 -Winvalid-memory-model 266 -Winvalid-offsetof 267 -Winvalid-pch 268 -Wliteral-suffix 269 -Wlogical-not-parentheses 270 -Wlogical-op 271 -Wno-long-long 272 -Wlto-type-mismatch 273 -Wmain 274 -Wmaybe-uninitialized 275 -Wmemset-elt-size 276 -Wmemset-transposed-args 277 -Wmisleading-indentation 278 -Wmismatched-dealloc 279 -Wmismatched-new-delete 280 -Wmismatched-tags 281 -Wmissing-attributes 282 -Wmissing-braces 283 -Wmissing-declarations 284 -Wmissing-field-initializers 285 -Wmissing-include-dirs 286 -Wmissing-profile 287 -Wmissing-requires 288 -Wmissing-template-keyword 289 -Wmultichar 290 -Wmultiple-inheritance 291 -Wmultistatement-macros 292 -Wno-namespaces 293 -Wnarrowing 294 -Wnoexcept 295 -Wnoexcept-type 296 -Wnon-template-friend 297 -Wnon-virtual-dtor 298 -Wnonnull 299 -Wnonnull-compare 300 -Wnormalized=nfkc 301 -Wnull-dereference 302 -Wodr 303 -Wold-style-cast 304 -Wopenacc-parallelism 305 -Wopenmp-simd 306 -Woverflow 307 -Woverlength-strings 308 -Woverloaded-virtual 309 -Wpacked 310 -Wpacked-bitfield-compat 311 -Wpacked-not-aligned 312 -Wno-padded 313 -Wparentheses 314 -Wpedantic 315 -Wpessimizing-move 316 -Wplacement-new=2 317 -Wpmf-conversions 318 -Wpointer-arith 319 -Wpointer-compare 320 -Wpragmas 321 -Wprio-ctor-dtor 322 -Wpsabi 323 -Wrange-loop-construct 324 -Wredundant-decls 325 -Wredundant-move 326 -Wredundant-tags 327 -Wregister 328 -Wreorder 329 -Wrestrict 330 -Wreturn-local-addr 331 -Wreturn-type 332 -Wscalar-storage-order 333 -Wsequence-point 334 -Wshadow=compatible-local 335 -Wshadow=global 336 -Wshadow=local 337 -Wshift-count-negative 338 -Wshift-count-overflow 339 -Wshift-negative-value 340 -Wshift-overflow=2 341 -Wsign-compare 342 -Wsign-conversion 343 -Wsign-promo 344 -Wsized-deallocation 345 -Wsizeof-array-argument 346 -Wsizeof-array-div 347 -Wsizeof-pointer-div 348 -Wsizeof-pointer-memaccess 349 -Wstack-protector 350 -Wstrict-aliasing=3 351 -Wstrict-null-sentinel 352 -Wno-strict-overflow 353 -Wstring-compare 354 -Wstringop-overflow=4 355 -Wstringop-overread 356 -Wstringop-truncation 357 -Wsubobject-linkage 358 -Wsuggest-attribute=cold 359 -Wsuggest-attribute=const 360 -Wsuggest-attribute=format 361 -Wsuggest-attribute=malloc 362 -Wsuggest-attribute=noreturn 363 -Wsuggest-attribute=pure 364 -Wsuggest-final-methods 365 -Wsuggest-final-types 366 -Wsuggest-override 367 -Wswitch 368 -Wswitch-bool 369 -Wswitch-default 370 -Wswitch-enum 371 -Wswitch-outside-range 372 -Wswitch-unreachable 373 -Wsync-nand 374 -Wsynth 375 -Wno-system-headers 376 -Wtautological-compare 377 -Wno-templates 378 -Wterminate 379 -Wtrampolines 380 -Wtrigraphs 381 -Wtrivial-auto-var-init 382 -Wtsan 383 -Wtype-limits 384 -Wundef 385 -Wuninitialized 386 -Wunknown-pragmas 387 -Wunreachable-code 388 -Wunsafe-loop-optimizations 389 -Wunused 390 -Wunused-but-set-parameter 391 -Wunused-but-set-variable 392 -Wunused-const-variable=2 393 -Wunused-function 394 -Wunused-label 395 -Wunused-local-typedefs 396 -Wunused-macros 397 -Wunused-parameter 398 -Wunused-result 399 -Wunused-value 400 -Wunused-variable 401 -Wuse-after-free=3 402 -Wuseless-cast 403 -Wvarargs 404 -Wvariadic-macros 405 -Wvector-operation-performance 406 -Wvexing-parse 407 -Wvirtual-inheritance 408 -Wvirtual-move-assign 409 -Wvla 410 -Wvla-parameter 411 -Wvolatile 412 -Wvolatile-register-var 413 -Wwrite-strings 414 -Wzero-as-null-pointer-constant 415 -Wzero-length-bounds 416) 417 418add_custom_target(ci_test_gcc 419 COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} 420 -DCMAKE_BUILD_TYPE=Debug -GNinja 421 -DJSON_BuildTests=ON 422 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc 423 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc 424 COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 425 COMMENT "Compile and test with GCC using maximal warning flags" 426) 427 428add_custom_target(ci_test_clang 429 COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND} 430 -DCMAKE_BUILD_TYPE=Debug -GNinja 431 -DJSON_BuildTests=ON 432 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang 433 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang 434 COMMAND cd ${PROJECT_BINARY_DIR}/build_clang && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 435 COMMENT "Compile and test with Clang using maximal warning flags" 436) 437 438############################################################################### 439# Different C++ Standards. 440############################################################################### 441 442foreach(CXX_STANDARD 11 14 17 20 23) 443 add_custom_target(ci_test_gcc_cxx${CXX_STANDARD} 444 COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} 445 -DCMAKE_BUILD_TYPE=Debug -GNinja 446 -DJSON_BuildTests=ON -DJSON_FastTests=ON 447 -DJSON_TestStandards=${CXX_STANDARD} 448 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} 449 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} 450 COMMAND cd ${PROJECT_BINARY_DIR}/build_gcc_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 451 COMMENT "Compile and test with GCC for C++${CXX_STANDARD}" 452 ) 453 454 add_custom_target(ci_test_clang_cxx${CXX_STANDARD} 455 COMMAND CXX=${CLANG_TOOL} CXXFLAGS="${CLANG_CXXFLAGS}" ${CMAKE_COMMAND} 456 -DCMAKE_BUILD_TYPE=Debug -GNinja 457 -DJSON_BuildTests=ON -DJSON_FastTests=ON 458 -DJSON_TestStandards=${CXX_STANDARD} 459 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} 460 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} 461 COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_cxx${CXX_STANDARD} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 462 COMMENT "Compile and test with Clang for C++${CXX_STANDARD}" 463 ) 464endforeach() 465 466############################################################################### 467# Disable exceptions. 468############################################################################### 469 470add_custom_target(ci_test_noexceptions 471 COMMAND ${CMAKE_COMMAND} 472 -DCMAKE_BUILD_TYPE=Debug -GNinja 473 -DJSON_BuildTests=ON -DCMAKE_CXX_FLAGS=-DJSON_NOEXCEPTION -DDOCTEST_TEST_FILTER=--no-throw 474 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noexceptions 475 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noexceptions 476 COMMAND cd ${PROJECT_BINARY_DIR}/build_noexceptions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 477 COMMENT "Compile and test with exceptions switched off" 478) 479 480############################################################################### 481# Disable implicit conversions. 482############################################################################### 483 484add_custom_target(ci_test_noimplicitconversions 485 COMMAND ${CMAKE_COMMAND} 486 -DCMAKE_BUILD_TYPE=Debug -GNinja 487 -DJSON_BuildTests=ON -DJSON_ImplicitConversions=OFF 488 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noimplicitconversions 489 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noimplicitconversions 490 COMMAND cd ${PROJECT_BINARY_DIR}/build_noimplicitconversions && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 491 COMMENT "Compile and test with implicit conversions switched off" 492) 493 494############################################################################### 495# Enable improved diagnostics. 496############################################################################### 497 498add_custom_target(ci_test_diagnostics 499 COMMAND ${CMAKE_COMMAND} 500 -DCMAKE_BUILD_TYPE=Debug -GNinja 501 -DJSON_BuildTests=ON -DJSON_Diagnostics=ON 502 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_diagnostics 503 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_diagnostics 504 COMMAND cd ${PROJECT_BINARY_DIR}/build_diagnostics && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 505 COMMENT "Compile and test with improved diagnostics enabled" 506) 507 508############################################################################### 509# Enable legacy discarded value comparison. 510############################################################################### 511 512add_custom_target(ci_test_legacycomparison 513 COMMAND ${CMAKE_COMMAND} 514 -DCMAKE_BUILD_TYPE=Debug -GNinja 515 -DJSON_BuildTests=ON -DJSON_LegacyDiscardedValueComparison=ON 516 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_legacycomparison 517 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_legacycomparison 518 COMMAND cd ${PROJECT_BINARY_DIR}/build_legacycomparison && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 519 COMMENT "Compile and test with legacy discarded value comparison enabled" 520) 521 522############################################################################### 523# Disable global UDLs. 524############################################################################### 525 526add_custom_target(ci_test_noglobaludls 527 COMMAND ${CMAKE_COMMAND} 528 -DCMAKE_BUILD_TYPE=Debug -GNinja 529 -DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_GlobalUDLs=OFF 530 -DCMAKE_CXX_FLAGS=-DJSON_TEST_NO_GLOBAL_UDLS 531 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_noglobaludls 532 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_noglobaludls 533 COMMAND cd ${PROJECT_BINARY_DIR}/build_noglobaludls && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 534 COMMENT "Compile and test with global UDLs disabled" 535) 536 537############################################################################### 538# Coverage. 539############################################################################### 540 541add_custom_target(ci_test_coverage 542 COMMAND CXX=g++ ${CMAKE_COMMAND} 543 -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="--coverage;-fprofile-arcs;-ftest-coverage" 544 -DJSON_BuildTests=ON 545 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage 546 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage 547 COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 548 549 COMMAND CXX=g++ ${CMAKE_COMMAND} 550 -DCMAKE_BUILD_TYPE=Debug -GNinja -DCMAKE_CXX_FLAGS="-m32;--coverage;-fprofile-arcs;-ftest-coverage" 551 -DJSON_BuildTests=ON -DJSON_32bitTest=ONLY 552 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_coverage32 553 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_coverage32 554 COMMAND cd ${PROJECT_BINARY_DIR}/build_coverage32 && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 555 556 COMMAND ${LCOV_TOOL} --directory . --capture --output-file json.info --rc lcov_branch_coverage=1 557 COMMAND ${LCOV_TOOL} -e json.info ${SRC_FILES} --output-file json.info.filtered --rc lcov_branch_coverage=1 558 COMMAND ${CMAKE_SOURCE_DIR}/tests/thirdparty/imapdl/filterbr.py json.info.filtered > json.info.filtered.noexcept 559 COMMAND genhtml --title "JSON for Modern C++" --legend --demangle-cpp --output-directory html --show-details --branch-coverage json.info.filtered.noexcept 560 561 COMMENT "Compile and test with coverage" 562) 563 564############################################################################### 565# Sanitizers. 566############################################################################### 567 568set(CLANG_CXX_FLAGS_SANITIZER "-g -O1 -fsanitize=address -fsanitize=undefined -fsanitize=integer -fsanitize=nullability -fno-omit-frame-pointer -fno-sanitize-recover=all -fno-sanitize=unsigned-integer-overflow -fno-sanitize=unsigned-shift-base") 569 570add_custom_target(ci_test_clang_sanitizer 571 COMMAND CXX=${CLANG_TOOL} CXXFLAGS=${CLANG_CXX_FLAGS_SANITIZER} ${CMAKE_COMMAND} 572 -DCMAKE_BUILD_TYPE=Debug -GNinja 573 -DJSON_BuildTests=ON 574 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_sanitizer 575 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_sanitizer 576 COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_sanitizer && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 577 COMMENT "Compile and test with sanitizers" 578) 579 580############################################################################### 581# Check if header is amalgamated and sources are properly indented. 582############################################################################### 583 584set(ASTYLE_FLAGS --style=allman --indent=spaces=4 --indent-modifiers --indent-switches --indent-preproc-block --indent-preproc-define --indent-col1-comments --pad-oper --pad-header --align-pointer=type --align-reference=type --add-brackets --convert-tabs --close-templates --lineend=linux --preserve-date --formatted) 585 586file(GLOB_RECURSE INDENT_FILES 587 ${PROJECT_SOURCE_DIR}/include/nlohmann/*.hpp 588 ${PROJECT_SOURCE_DIR}/tests/src/*.cpp 589 ${PROJECT_SOURCE_DIR}/tests/src/*.hpp 590 ${PROJECT_SOURCE_DIR}/tests/benchmarks/src/benchmarks.cpp 591 ${PROJECT_SOURCE_DIR}/docs/examples/*.cpp 592) 593 594set(include_dir ${PROJECT_SOURCE_DIR}/single_include/nlohmann) 595set(tool_dir ${PROJECT_SOURCE_DIR}/tools/amalgamate) 596add_custom_target(ci_test_amalgamation 597 COMMAND rm -fr ${include_dir}/json.hpp~ ${include_dir}/json_fwd.hpp~ 598 COMMAND cp ${include_dir}/json.hpp ${include_dir}/json.hpp~ 599 COMMAND cp ${include_dir}/json_fwd.hpp ${include_dir}/json_fwd.hpp~ 600 601 COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json.json -s . 602 COMMAND ${Python3_EXECUTABLE} ${tool_dir}/amalgamate.py -c ${tool_dir}/config_json_fwd.json -s . 603 COMMAND ${ASTYLE_TOOL} ${ASTYLE_FLAGS} --suffix=none --quiet ${include_dir}/json.hpp ${include_dir}/json_fwd.hpp 604 605 COMMAND diff ${include_dir}/json.hpp~ ${include_dir}/json.hpp 606 COMMAND diff ${include_dir}/json_fwd.hpp~ ${include_dir}/json_fwd.hpp 607 608 COMMAND ${ASTYLE_TOOL} ${ASTYLE_FLAGS} ${INDENT_FILES} 609 COMMAND for FILE in `find . -name '*.orig'`\; do false \; done 610 611 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 612 COMMENT "Check amalgamation and indentation" 613) 614 615############################################################################### 616# Build and test using the amalgamated header 617############################################################################### 618 619add_custom_target(ci_test_single_header 620 COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} 621 -DCMAKE_BUILD_TYPE=Debug -GNinja 622 -DJSON_BuildTests=ON -DJSON_MultipleHeaders=OFF -DJSON_FastTests=ON 623 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_single_header 624 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_single_header 625 COMMAND cd ${PROJECT_BINARY_DIR}/build_single_header && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 626 COMMENT "Compile and test single-header version" 627) 628 629############################################################################### 630# Valgrind. 631############################################################################### 632 633add_custom_target(ci_test_valgrind 634 COMMAND CXX=${GCC_TOOL} ${CMAKE_COMMAND} 635 -DCMAKE_BUILD_TYPE=Debug -GNinja 636 -DJSON_BuildTests=ON -DJSON_Valgrind=ON 637 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_valgrind 638 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_valgrind 639 COMMAND cd ${PROJECT_BINARY_DIR}/build_valgrind && ${CMAKE_CTEST_COMMAND} -L valgrind --parallel ${N} --output-on-failure 640 COMMENT "Compile and test with Valgrind" 641) 642 643############################################################################### 644# Check code with Clang Static Analyzer. 645############################################################################### 646 647set(CLANG_ANALYZER_CHECKS "fuchsia.HandleChecker,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,optin.cplusplus.UninitializedObject,optin.cplusplus.VirtualCall,optin.mpi.MPI-Checker,optin.osx.OSObjectCStyleCast,optin.osx.cocoa.localizability.EmptyLocalizationContextChecker,optin.osx.cocoa.localizability.NonLocalizedStringChecker,optin.performance.GCDAntipattern,optin.performance.Padding,optin.portability.UnixAPI,security.FloatLoopCounter,security.insecureAPI.DeprecatedOrUnsafeBufferHandling,security.insecureAPI.bcmp,security.insecureAPI.bcopy,security.insecureAPI.bzero,security.insecureAPI.rand,security.insecureAPI.strcpy,valist.CopyToSelf,valist.Uninitialized,valist.Unterminated,webkit.NoUncountedMemberChecker,webkit.RefCntblBaseVirtualDtor,core.CallAndMessage,core.DivideZero,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.VLASize,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.PlacementNew,cplusplus.PureVirtualCall,deadcode.DeadStores,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,osx.API,osx.MIG,osx.NumberObjectConversion,osx.OSObjectRetainCount,osx.ObjCProperty,osx.SecKeychainAPI,osx.cocoa.AtSync,osx.cocoa.AutoreleaseWrite,osx.cocoa.ClassRelease,osx.cocoa.Dealloc,osx.cocoa.IncompatibleMethodTypes,osx.cocoa.Loops,osx.cocoa.MissingSuperCall,osx.cocoa.NSAutoreleasePool,osx.cocoa.NSError,osx.cocoa.NilArg,osx.cocoa.NonNilReturnValue,osx.cocoa.ObjCGenerics,osx.cocoa.RetainCount,osx.cocoa.RunLoopAutoreleaseLeak,osx.cocoa.SelfInit,osx.cocoa.SuperDealloc,osx.cocoa.UnusedIvars,osx.cocoa.VariadicMethodTypes,osx.coreFoundation.CFError,osx.coreFoundation.CFNumber,osx.coreFoundation.CFRetainRelease,osx.coreFoundation.containers.OutOfBounds,osx.coreFoundation.containers.PointerSizedValues,security.insecureAPI.UncheckedReturn,security.insecureAPI.decodeValueOfObjCType,security.insecureAPI.getpw,security.insecureAPI.gets,security.insecureAPI.mkstemp,security.insecureAPI.mktemp,security.insecureAPI.vfork,unix.API,unix.Malloc,unix.MallocSizeof,unix.MismatchedDeallocator,unix.Vfork,unix.cstring.BadSizeArg,unix.cstring.NullArg") 648 649add_custom_target(ci_clang_analyze 650 COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} 651 -DCMAKE_BUILD_TYPE=Debug -GNinja 652 -DJSON_BuildTests=ON 653 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_analyze 654 COMMAND cd ${PROJECT_BINARY_DIR}/build_clang_analyze && ${SCAN_BUILD_TOOL} -enable-checker ${CLANG_ANALYZER_CHECKS} --use-c++=${CLANG_TOOL} -analyze-headers -o ${PROJECT_BINARY_DIR}/report ninja 655 COMMENT "Check code with Clang Analyzer" 656) 657 658############################################################################### 659# Check code with Cppcheck. 660############################################################################### 661 662add_custom_target(ci_cppcheck 663 COMMAND ${CPPCHECK_TOOL} --enable=warning --suppress=missingReturn --inline-suppr --inconclusive --force --std=c++11 ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp --error-exitcode=1 664 COMMENT "Check code with Cppcheck" 665) 666 667############################################################################### 668# Check code with cpplint. 669############################################################################### 670 671add_custom_target(ci_cpplint 672 COMMAND ${Python3_EXECUTABLE} -mvenv venv_cpplint 673 COMMAND venv_cpplint/bin/pip3 --quiet install cpplint 674 COMMAND venv_cpplint/bin/cpplint --filter=-whitespace,-legal,-runtime/references,-runtime/explicit,-runtime/indentation_namespace,-readability/casting,-readability/nolint --quiet --recursive ${SRC_FILES} 675 COMMENT "Check code with cpplint" 676 WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 677) 678 679############################################################################### 680# Check code with OCLint. 681############################################################################### 682 683file(COPY ${PROJECT_SOURCE_DIR}/single_include/nlohmann/json.hpp DESTINATION ${PROJECT_BINARY_DIR}/src_single) 684file(RENAME ${PROJECT_BINARY_DIR}/src_single/json.hpp ${PROJECT_BINARY_DIR}/src_single/all.cpp) 685file(APPEND "${PROJECT_BINARY_DIR}/src_single/all.cpp" "\n\nint main()\n{}\n") 686 687add_executable(single_all ${PROJECT_BINARY_DIR}/src_single/all.cpp) 688target_compile_features(single_all PRIVATE cxx_std_11) 689 690add_custom_target(ci_oclint 691 COMMAND ${CMAKE_COMMAND} 692 -DCMAKE_BUILD_TYPE=Debug 693 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 694 -DJSON_BuildTests=OFF -DJSON_CI=ON 695 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_oclint 696 COMMAND ${OCLINT_TOOL} -i ${PROJECT_BINARY_DIR}/build_oclint/src_single/all.cpp -p ${PROJECT_BINARY_DIR}/build_oclint -- 697 -report-type html -enable-global-analysis --max-priority-1=0 --max-priority-2=1000 --max-priority-3=2000 698 --disable-rule=MultipleUnaryOperator 699 --disable-rule=DoubleNegative 700 --disable-rule=ShortVariableName 701 --disable-rule=GotoStatement 702 --disable-rule=LongLine 703 -o ${PROJECT_BINARY_DIR}/build_oclint/oclint_report.html 704 COMMENT "Check code with OCLint" 705) 706 707############################################################################### 708# Check code with Clang-Tidy. 709############################################################################### 710 711add_custom_target(ci_clang_tidy 712 COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} 713 -DCMAKE_BUILD_TYPE=Debug -GNinja 714 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_CLANG_TIDY=${CLANG_TIDY_TOOL} 715 -DJSON_BuildTests=ON 716 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_clang_tidy 717 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_clang_tidy 718 COMMENT "Check code with Clang-Tidy" 719) 720 721############################################################################### 722# Check code with PVS-Studio Analyzer <https://www.viva64.com/en/pvs-studio/>. 723############################################################################### 724 725add_custom_target(ci_pvs_studio 726 COMMAND CXX=${CLANG_TOOL} ${CMAKE_COMMAND} 727 -DCMAKE_BUILD_TYPE=Debug 728 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 729 -DJSON_BuildTests=ON 730 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_pvs_studio 731 COMMAND cd ${PROJECT_BINARY_DIR}/build_pvs_studio && ${PVS_STUDIO_ANALYZER_TOOL} analyze -j 10 732 COMMAND cd ${PROJECT_BINARY_DIR}/build_pvs_studio && ${PLOG_CONVERTER_TOOL} -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs 733 COMMENT "Check code with PVS Studio" 734) 735 736############################################################################### 737# Check code with Infer <https://fbinfer.com> static analyzer. 738############################################################################### 739 740add_custom_target(ci_infer 741 COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_infer 742 COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} compile -- ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${PROJECT_SOURCE_DIR} -DJSON_BuildTests=ON 743 COMMAND cd ${PROJECT_BINARY_DIR}/build_infer && ${INFER_TOOL} run -- make 744 COMMENT "Check code with Infer" 745) 746 747############################################################################### 748# Run test suite with previously downloaded test data. 749############################################################################### 750 751add_custom_target(ci_offline_testdata 752 COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_offline_testdata/test_data 753 COMMAND cd ${PROJECT_BINARY_DIR}/build_offline_testdata/test_data && ${GIT_TOOL} clone -c advice.detachedHead=false --branch v3.1.0 https://github.com/nlohmann/json_test_data.git --quiet --depth 1 754 COMMAND ${CMAKE_COMMAND} 755 -DCMAKE_BUILD_TYPE=Debug -GNinja 756 -DJSON_BuildTests=ON -DJSON_FastTests=ON -DJSON_TestDataDirectory=${PROJECT_BINARY_DIR}/build_offline_testdata/test_data/json_test_data 757 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_offline_testdata 758 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_offline_testdata 759 COMMAND cd ${PROJECT_BINARY_DIR}/build_offline_testdata && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure 760 COMMENT "Check code with previously downloaded test data" 761) 762 763############################################################################### 764# Run test suite when project was not checked out from Git 765############################################################################### 766 767add_custom_target(ci_non_git_tests 768 COMMAND git config --global --add safe.directory ${PROJECT_SOURCE_DIR} 769 COMMAND mkdir -p ${PROJECT_BINARY_DIR}/build_non_git_tests/sources 770 COMMAND cd ${PROJECT_SOURCE_DIR} && for FILE in `${GIT_TOOL} ls-tree --name-only HEAD`\; do cp -r $$FILE ${PROJECT_BINARY_DIR}/build_non_git_tests/sources \; done 771 COMMAND ${CMAKE_COMMAND} 772 -DCMAKE_BUILD_TYPE=Debug -GNinja 773 -DJSON_BuildTests=ON -DJSON_FastTests=ON 774 -S${PROJECT_BINARY_DIR}/build_non_git_tests/sources -B${PROJECT_BINARY_DIR}/build_non_git_tests 775 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_non_git_tests 776 COMMAND cd ${PROJECT_BINARY_DIR}/build_non_git_tests && ${CMAKE_CTEST_COMMAND} --parallel ${N} -LE git_required --output-on-failure 777 COMMENT "Check code when project was not checked out from Git" 778) 779 780############################################################################### 781# Run test suite and exclude tests that change installed files 782############################################################################### 783 784add_custom_target(ci_reproducible_tests 785 COMMAND ${CMAKE_COMMAND} 786 -DCMAKE_BUILD_TYPE=Debug -GNinja 787 -DJSON_BuildTests=ON -DJSON_FastTests=ON 788 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_reproducible_tests 789 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_reproducible_tests 790 COMMAND cd ${PROJECT_BINARY_DIR}/build_reproducible_tests && ${CMAKE_CTEST_COMMAND} --parallel ${N} -LE not_reproducible --output-on-failure 791 COMMENT "Check code and exclude tests that change installed files" 792) 793 794############################################################################### 795# Check if every header in the include folder includes sufficient headers to 796# be compiled individually. 797############################################################################### 798 799set(iwyu_path_and_options ${IWYU_TOOL} -Xiwyu --max_line_length=300) 800 801foreach(SRC_FILE ${SRC_FILES}) 802 # get relative path of the header file 803 file(RELATIVE_PATH RELATIVE_SRC_FILE "${PROJECT_SOURCE_DIR}/include/nlohmann" "${SRC_FILE}") 804 # replace slashes and strip suffix 805 string(REPLACE "/" "_" RELATIVE_SRC_FILE "${RELATIVE_SRC_FILE}") 806 string(REPLACE ".hpp" "" RELATIVE_SRC_FILE "${RELATIVE_SRC_FILE}") 807 # create code file 808 file(WRITE "${PROJECT_BINARY_DIR}/src_single/${RELATIVE_SRC_FILE}.cpp" "#include \"${SRC_FILE}\" // IWYU pragma: keep\n\nint main()\n{}\n") 809 # create executable 810 add_executable(single_${RELATIVE_SRC_FILE} EXCLUDE_FROM_ALL ${PROJECT_BINARY_DIR}/src_single/${RELATIVE_SRC_FILE}.cpp) 811 target_include_directories(single_${RELATIVE_SRC_FILE} PRIVATE ${PROJECT_SOURCE_DIR}/include) 812 target_compile_features(single_${RELATIVE_SRC_FILE} PRIVATE cxx_std_11) 813 set_property(TARGET single_${RELATIVE_SRC_FILE} PROPERTY CXX_INCLUDE_WHAT_YOU_USE "${iwyu_path_and_options}") 814 # remember binary for ci_single_binaries target 815 list(APPEND single_binaries single_${RELATIVE_SRC_FILE}) 816endforeach() 817 818add_custom_target(ci_single_binaries 819 DEPENDS ${single_binaries} 820 COMMENT "Check if headers are self-contained" 821) 822 823############################################################################### 824# Benchmarks 825############################################################################### 826 827add_custom_target(ci_benchmarks 828 COMMAND ${CMAKE_COMMAND} 829 -DCMAKE_BUILD_TYPE=Release -GNinja 830 -S${PROJECT_SOURCE_DIR}/benchmarks -B${PROJECT_BINARY_DIR}/build_benchmarks 831 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_benchmarks --target json_benchmarks 832 COMMAND cd ${PROJECT_BINARY_DIR}/build_benchmarks && ./json_benchmarks 833 COMMENT "Run benchmarks" 834) 835 836############################################################################### 837# CMake flags 838############################################################################### 839 840function(ci_get_cmake version var) 841 set(${var} ${PROJECT_BINARY_DIR}/cmake-${version}/bin/cmake) 842 add_custom_command( 843 OUTPUT ${${var}} 844 COMMAND wget -nc https://github.com/Kitware/CMake/releases/download/v${version}/cmake-${version}.tar.gz 845 COMMAND tar xfz cmake-${version}.tar.gz 846 COMMAND rm cmake-${version}.tar.gz 847 COMMAND ${CMAKE_COMMAND} -S cmake-${version} -B cmake-${version} 848 COMMAND ${CMAKE_COMMAND} --build cmake-${version} --parallel 10 849 WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 850 COMMENT "Download CMake ${version}" 851 ) 852 set(${var} ${${var}} PARENT_SCOPE) 853endfunction() 854 855ci_get_cmake(3.1.0 CMAKE_3_1_0_BINARY) 856ci_get_cmake(3.13.0 CMAKE_3_13_0_BINARY) 857 858set(JSON_CMAKE_FLAGS_3_1_0 JSON_Diagnostics JSON_GlobalUDLs JSON_ImplicitConversions JSON_DisableEnumSerialization 859 JSON_LegacyDiscardedValueComparison JSON_Install JSON_MultipleHeaders JSON_SystemInclude JSON_Valgrind) 860set(JSON_CMAKE_FLAGS_3_13_0 JSON_BuildTests) 861 862function(ci_add_cmake_flags_targets flag min_version) 863 string(TOLOWER "ci_cmake_flag_${flag}" flag_target) 864 string(REPLACE . _ min_version_var ${min_version}) 865 set(cmake_binary ${CMAKE_${min_version_var}_BINARY}) 866 add_custom_target(${flag_target} 867 COMMENT "Check CMake flag ${flag} (CMake ${CMAKE_VERSION})" 868 COMMAND ${CMAKE_COMMAND} 869 -Werror=dev 870 -D${flag}=ON 871 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_${flag_target} 872 ) 873 add_custom_target(${flag_target}_${min_version_var} 874 COMMENT "Check CMake flag ${JSON_CMAKE_FLAG} (CMake ${min_version})" 875 COMMAND mkdir -pv ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var} 876 COMMAND cd ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var} 877 && ${cmake_binary} -Werror=dev ${PROJECT_SOURCE_DIR} -D${flag}=ON 878 DEPENDS ${cmake_binary} 879 ) 880 list(APPEND JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGET} ${flag_target}_${min_version_var}) 881 list(APPEND JSON_CMAKE_FLAG_BUILD_DIRS ${PROJECT_BINARY_DIR}/build_${flag_target} ${PROJECT_BINARY_DIR}/build_${flag_target}_${min_version_var}) 882 set(JSON_CMAKE_FLAG_TARGETS ${JSON_CMAKE_FLAG_TARGETS} PARENT_SCOPE) 883 set(JSON_CMAKE_FLAG_BUILD_DIRS ${JSON_CMAKE_FLAG_BUILD_DIRS} PARENT_SCOPE) 884endfunction() 885 886foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS_3_1_0}) 887 ci_add_cmake_flags_targets(${JSON_CMAKE_FLAG} 3.1.0) 888endforeach() 889 890foreach(JSON_CMAKE_FLAG ${JSON_CMAKE_FLAGS_3_13_0}) 891 ci_add_cmake_flags_targets(${JSON_CMAKE_FLAG} 3.13.0) 892endforeach() 893 894add_custom_target(ci_cmake_flags 895 DEPENDS ${JSON_CMAKE_FLAG_TARGETS} 896 COMMENT "Check CMake flags" 897) 898 899############################################################################### 900# Use more installed compilers. 901############################################################################### 902 903foreach(COMPILER g++-4.8 g++-4.9 g++-5 g++-6 g++-7 g++-8 g++-9 g++-10 g++-11 clang++-3.5 clang++-3.6 clang++-3.7 clang++-3.8 clang++-3.9 clang++-4.0 clang++-5.0 clang++-6.0 clang++-7 clang++-8 clang++-9 clang++-10 clang++-11 clang++-12 clang++-13 clang++-14 clang++-15 clang++-16 clang++-17) 904 find_program(COMPILER_TOOL NAMES ${COMPILER}) 905 if (COMPILER_TOOL) 906 unset(ADDITIONAL_FLAGS) 907 908 add_custom_target(ci_test_compiler_${COMPILER} 909 COMMAND CXX=${COMPILER} ${CMAKE_COMMAND} 910 -DCMAKE_BUILD_TYPE=Debug -GNinja 911 -DJSON_BuildTests=ON -DJSON_FastTests=ON 912 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} 913 ${ADDITIONAL_FLAGS} 914 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} 915 COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_${COMPILER} && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure 916 COMMENT "Compile and test with ${COMPILER}" 917 ) 918 endif() 919 unset(COMPILER_TOOL CACHE) 920endforeach() 921 922add_custom_target(ci_test_compiler_default 923 COMMAND ${CMAKE_COMMAND} 924 -DCMAKE_BUILD_TYPE=Debug -GNinja 925 -DJSON_BuildTests=ON -DJSON_FastTests=ON 926 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_compiler_default 927 ${ADDITIONAL_FLAGS} 928 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_compiler_default --parallel ${N} 929 COMMAND cd ${PROJECT_BINARY_DIR}/build_compiler_default && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" -LE git_required --output-on-failure 930 COMMENT "Compile and test with default C++ compiler" 931) 932 933############################################################################### 934# CUDA example 935############################################################################### 936 937add_custom_target(ci_cuda_example 938 COMMAND ${CMAKE_COMMAND} 939 -DCMAKE_BUILD_TYPE=Debug -GNinja 940 -DCMAKE_CUDA_HOST_COMPILER=g++-8 941 -S${PROJECT_SOURCE_DIR}/tests/cuda_example -B${PROJECT_BINARY_DIR}/build_cuda_example 942 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_cuda_example 943) 944 945############################################################################### 946# Intel C++ Compiler 947############################################################################### 948 949add_custom_target(ci_icpc 950 COMMAND ${CMAKE_COMMAND} 951 -DCMAKE_BUILD_TYPE=Debug -GNinja 952 -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc 953 -DJSON_BuildTests=ON -DJSON_FastTests=ON 954 -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_icpc 955 COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_icpc 956 COMMAND cd ${PROJECT_BINARY_DIR}/build_icpc && ${CMAKE_CTEST_COMMAND} --parallel ${N} --exclude-regex "test-unicode" --output-on-failure 957 COMMENT "Compile and test with ICPC" 958) 959 960############################################################################### 961# test documentation 962############################################################################### 963 964add_custom_target(ci_test_examples 965 COMMAND make CXX="${GCC_TOOL}" check_output_portable -j8 966 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs 967 COMMENT "Check that all examples compile and create the desired output" 968) 969 970add_custom_target(ci_test_api_documentation 971 COMMAND ${Python3_EXECUTABLE} scripts/check_structure.py 972 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs/mkdocs 973 COMMENT "Lint the API documentation" 974) 975 976############################################################################### 977# Clean up all generated files. 978############################################################################### 979 980add_custom_target(ci_clean 981 COMMAND rm -fr ${PROJECT_BINARY_DIR}/build_* cmake-3.1.0-Darwin64 ${JSON_CMAKE_FLAG_BUILD_DIRS} ${single_binaries} 982 COMMENT "Clean generated directories" 983) 984