ci.cmake 45 KB

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