* Refactor unit test creation
Add functions for creating tests and to supply test- and
standard-specific build settings.
Raises minimum CMake version to 3.13 in test directory.
json_test_add_test_for(
<file>
MAIN <main>
[CXX_STANDARDS <version_number>...] [FORCE])
Given a <file> unit-foo.cpp, produces
test-foo_cpp<version_number>
if C++ standard <version_number> is supported by the compiler and
thesource file contains JSON_HAS_CPP_<version_number>. Use FORCE to
create the test regardless of the file containing
JSON_HAS_CPP_<version_number>. Test targets are linked against <main>.
CXX_STANDARDS defaults to "11".
json_test_set_test_options(
all|<tests>
[CXX_STANDARDS all|<args>...]
[COMPILE_DEFINITIONS <args>...]
[COMPILE_FEATURES <args>...]
[COMPILE_OPTIONS <args>...]
[LINK_LIBRARIES <args>...]
[LINK_OPTIONS <args>...])
Supply test- and standard-specific build settings.
Specify multiple tests using a list e.g., "test-foo;test-bar".
Must be called BEFORE the test is created.
* Use CMAKE_MODULE_PATH
* Don't undef some macros if JSON_TEST_KEEP_MACROS is defined
* Use JSON_TEST_KEEP_MACROS
Incidentally enables the regression tests for #2546 and #3070.
A CHECK_THROWS_WITH_AS in #3070 was disabled which is tracked in #3377
and a line in from_json(..., std_fs::path&) was marked with LCOV_EXCL_LINE.
* Add three-way comparison feature test macro
* Disable broken comparison if JSON_HAS_THREE_WAY_COMPARISON
* Fix redefinition of inline constexpr statics
Redelcaration of inline constexpr static data members in namespace scope
was deprecated in C++17. Fixes -Werror=deprecated compilation failures.
* Fix more test build failures due to missing noexcept
* CI: update cmake_flags test to use CMake 3.13 in test directory
Also change default for JSON_BuildTests option to depend on CMake
version.
* CI: turn *_CXXFLAGS into CMake lists
* CI: use JSON_TestStandards to set CXX_STANDARD
* CI: pass extra CXXFLAGS to standards tests
Github issue:
https://github.com/nlohmann/json/issues/2073
nlohmann::json documents 2 way of depending on it using CMake
1) Copy-paste the project/source into your own project.
2) Install nlohman::json and then use find_package.
(1) pollutes your git repository, (2) requires everyone to install the
dependencies themselves.
Since 2018, CMake provide some kind of 'package manager' features using
[FetchContent](https://cmake.org/cmake/help/v3.17/module/FetchContent.html)
It gives the following:
~~~cmake
include(FetchContent)
FetchContent_Declare(json
GIT_REPOSITORY https://github.com/nlohmann/json
GIT_TAG v3.7.3)
FetchContent_GetProperties(json)
if(NOT json_POPULATED)
FetchContent_Populate(json)
add_subdirectory( ${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
~~~
Then declares the dependency in the target using it:
~~~cmake
target_link_library(my_project PRIVATE nlohmann_json::nlohmann_json
~~~
This patch updates the documentation and provides tests.
Using GLOB is slow and considered bad practice.
From https://cmake.org/cmake/help/latest/command/file.html:
> We do not recommend using GLOB to collect a list of source files from
> your source tree. If no CMakeLists.txt file changes when a source is
> added or removed then the generated build system cannot know when to ask
> CMake to regenerate. The CONFIGURE_DEPENDS flag may not work reliably on
> all generators, or if a new generator is added in the future that cannot
> support it, projects using it will be stuck. Even if CONFIGURE_DEPENDS
> works reliably, there is still a cost to perform the check on every
> rebuild.
- Switch to clang-7
- Adapt PATH so that llvm-symbolizer can be found for useful stacktraces
- Adapt compile flags
"-O0" ensures much faster compile times
"-fno-sanitize-recover=all
-fsanitize-recover=unsigned-integer-overflow" this fails the build on
all issues except unsigned integer overflows. Not failing in this case
is required in combination with the sanitizer suppression file as only
recoverable errors can be suppressed.
The UBSAN suppression file ignores errors from stl_bvector.h (which
holds std::vector<bool>).
Clang reports that error as
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:158:20 in
Start 34: test-deserialization_all
28/88 Test #71: test-testsuites_default .............***Failed 0.32 sec
/usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:158:20: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int'
#0 0x628f72 in std::_Bit_iterator_base::_M_bump_down() /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:158:20
#1 0x628d16 in std::_Bit_iterator::operator--() /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:251:7
#2 0x634aac in std::vector<bool, std::allocator<bool> >::pop_back() /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_bvector.h:1010:7
#3 0x61eff0 in bool nlohmann::detail::parser<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::sax_parse_internal<nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > >(nlohmann::detail::json_sax_dom_parser<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >*) /home/firma/devel/json/include/nlohmann/detail/input/parser.hpp:439:28
#4 0x604864 in nlohmann::detail::parser<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::parse(bool, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer>&) /home/firma/devel/json/include/nlohmann/detail/input/parser.hpp:116:13
#5 0x5f8079 in nlohmann::operator>>(std::istream&, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer>&) /home/firma/devel/json/include/nlohmann/json.hpp:6356:42
#6 0x5e1d92 in _DOCTEST_ANON_FUNC_21() /home/firma/devel/json/test/src/unit-testsuites.cpp:343:9
#7 0x7207fe in doctest::Context::run() /home/firma/devel/json/test/thirdparty/doctest/doctest.h:5938:21
#8 0x72681a in main /home/firma/devel/json/test/thirdparty/doctest/doctest.h:6016:71
#9 0x7f75d22362e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
#10 0x4c28b9 in _start (/home/firma/devel/json/build/test/test-testsuites+0x4c28b9)
The pop_back() in parser.hpp
assert(not states.empty());
-> states.pop_back();
triggers the UBSAN report. But the assertion above ensure that we only
call pop_back() on an non-empty vector, therefore this is a STL library
bug and thus must be ignored for us.