danielaparker / jsoncons

A C++, header-only library for constructing JSON and JSON-like data formats, with JSON Pointer, JSON Patch, JSON Schema, JSONPath, JMESPath, CSV, MessagePack, CBOR, BSON, UBJSON
https://danielaparker.github.io/jsoncons
Other
726 stars 164 forks source link

compiling on RHEL8 / g++ 8.5 #513

Closed baallan closed 5 months ago

baallan commented 6 months ago

The documented cmake build fails on rhel8 as does attempted cmake permutation: cmake .. -DJSONCONS_BUILD_TESTS=On -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON && cmake --build . -- VERBOSE=1 && ctest --output-on-failure

[ 12%] Building CXX object test/CMakeFiles/unit_tests.dir/cbor/src/encode_cbor_tests.cpp.o
cd /tlt/app-data-collection/jsoncons/build/test && /usr/bin/c++  -I/tlt/app-data-collection/jsoncons/include -I/tlt/app-data-collection/jsoncons/test -/tlt/app-data-collection/jsoncons/third_party -I/tlt/app-data-collection/jsoncons/third_party/catch -O3 -DNDEBUG -Werror=maybe-uninitialized -Wnon-virtual-dtor -Werror=stringop-overflow -Werror -Wall -Wextra -Wcast-align -Wcast-qual -Wimplicit-fallthrough -Wsign-compare -pedantic -Wnonnull -Werror=nonnull -std=gnu++17 -MD -MT test/CMakeFiles/unit_tests.dir/cbor/src/encode_cbor_tests.cpp.o -MF CMakeFiles/unit_tests.dir/cbor/src/encode_cbor_tests.cpp.o.d -o CMakeFiles/unit_tests.dir/cbor/src/encode_cbor_tests.cpp.o -c /tlt/app-data-collection/jsoncons/test/cbor/src/encode_cbor_tests.cpp
In file included from /tlt/app-data-collection/jsoncons/test/cbor/src/encode_cbor_tests.cpp:9:
/usr/include/c++/8/scoped_allocator: In instantiation of ‘std::scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs>::scoped_allocator_adaptor() [with _OuterAlloc = FreeListAllocator<char>; _InnerAllocs = {}]’:
/usr/include/c++/8/bits/basic_string.h:619:28:   required from ‘std::__cxx11::basic_string<_CharT, _Traits, _Allocator>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_replace_dispatch(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::const_iterator, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::const_iterator, _InputIterator, _InputIterator, std::__false_type) [with _InputIterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::scoped_allocator_adaptor<FreeListAllocator<char> >; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::scoped_allocator_adaptor<FreeListAllocator<char> > > >; typename __gnu_cxx::__alloc_traits<typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_CharT>::other>::const_pointer = const char*]’
/usr/include/c++/8/bits/basic_string.h:2095:28:   required from ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::replace(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::const_iterator, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::const_iterator, _InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; <template-parameter-2-2> = void; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::scoped_allocator_adaptor<FreeListAllocator<char> >; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::scoped_allocator_adaptor<FreeListAllocator<char> > > >; typename __gnu_cxx::__alloc_traits<typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_CharT>::other>::const_pointer = const char*]’
/usr/include/c++/8/bits/basic_string.h:1585:4:   required from ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::iterator std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::insert(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::const_iterator, _InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >; <template-parameter-2-2> = void; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::scoped_allocator_adaptor<FreeListAllocator<char> >; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::scoped_allocator_adaptor<FreeListAllocator<char> > > >; typename __gnu_cxx::__alloc_traits<typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_CharT>::other>::pointer = char*; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::scoped_allocator_adaptor<FreeListAllocator<char> > > >; typename __gnu_cxx::__alloc_traits<typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_CharT>::other>::const_pointer = const char*]’
/tlt/app-data-collection/jsoncons/include/jsoncons/item_event_visitor.hpp:1477:17:   required from ‘bool jsoncons::basic_item_event_visitor_to_json_visitor<CharT, Allocator>::visit_null(jsoncons::semantic_tag, const jsoncons::ser_context&, std::error_code&) [with CharT = char; Allocator = std::scoped_allocator_adaptor<FreeListAllocator<char> >]’
/tlt/app-data-collection/jsoncons/include/jsoncons/item_event_visitor.hpp:1472:14:   required from here
/usr/include/c++/8/scoped_allocator:287:60: error: no matching function for call to ‘FreeListAllocator<char>::FreeListAllocator()’
       scoped_allocator_adaptor() : _OuterAlloc(), _M_inner() { }
                                                            ^
In file included from/tlt/app-data-collection/jsoncons/test/cbor/src/encode_cbor_tests.cpp:10:
/tlt/app-data-collection/jsoncons/test/common/FreeListAllocator.hpp:45:5: note: candidate: ‘FreeListAllocator<T>::FreeListAllocator(FreeListAllocator<T>&&) [with T = char]’
     FreeListAllocator(FreeListAllocator&& other) noexcept :  list(other.list) {
     ^~~~~~~~~~~~~~~~~
/tlt/app-data-collection/jsoncons/test/common/FreeListAllocator.hpp:45:5: note:   candidate expects 1 argument, 0 provided
/tlt/app-data-collection/jsoncons/test/common/FreeListAllocator.hpp:44:5: note: candidate: ‘template<class U> FreeListAllocator<T>::FreeListAllocator(const FreeListAllocator<U>&)’
     FreeListAllocator(const FreeListAllocator<U>&) noexcept {}
     ^~~~~~~~~~~~~~~~~
/tlt/app-data-collection/jsoncons/test/common/FreeListAllocator.hpp:44:5: note:   template argument deduction/substitution failed:
In file included from /tlt/app-data-collection/jsoncons/test/cbor/src/encode_cbor_tests.cpp:9:
/usr/include/c++/8/scoped_allocator:287:60: note:   candidate expects 1 argument, 0 provided
       scoped_allocator_adaptor() : _OuterAlloc(), _M_inner() { }
                                                            ^
In file included from /tlt/app-data-collection/jsoncons/test/cbor/src/encode_cbor_tests.cpp:10:
/tlt/app-data-collection/jsoncons/test/common/FreeListAllocator.hpp:42:5: note: candidate: ‘FreeListAllocator<T>::FreeListAllocator(const FreeListAllocator<T>&) [with T = char]’
     FreeListAllocator(const FreeListAllocator&) noexcept {}
     ^~~~~~~~~~~~~~~~~
/tlt/app-data-collection/jsoncons/test/common/FreeListAllocator.hpp:42:5: note:   candidate expects 1 argument, 0 provided
/tlt/app-data-collection/jsoncons/test/common/FreeListAllocator.hpp:40:5: note: candidate: ‘FreeListAllocator<T>::FreeListAllocator(int) [with T = char]’
     FreeListAllocator(int) noexcept
     ^~~~~~~~~~~~~~~~~
/tlt/app-data-collection/jsoncons/test/common/FreeListAllocator.hpp:40:5: note:   candidate expects 1 argument, 0 provided
gmake[2]: *** [test/CMakeFiles/unit_tests.dir/build.make:300: test/CMakeFiles/unit_tests.dir/cbor/src/encode_cbor_tests.cpp.o] Error 1
gmake[2]: Leaving directory '/tlt/app-data-collection/jsoncons/build'
gmake[1]: *** [CMakeFiles/Makefile2:854: test/CMakeFiles/unit_tests.dir/all] Error 2
gmake[1]: Leaving directory '/tlt/app-data-collection/jsoncons/build'
gmake: *** [Makefile:146: all] Error 2

What compiler, architecture, and operating system?

What jsoncons library version?

baallan commented 6 months ago

Any hints on how to use current jsoncons with ancient g++ versions much appreciated.

danielaparker commented 6 months ago

Off hand, it looks like an allocator isn't being propagated to a std::basic_string, not sure why, need to investigate. Old (4.8) versions of g++ didn't support stateful allocators in strings, and we have some work around code for that, but your compiler certainly should.

Could you try compiling with -DJSONCONS_HAS_STATEFUL_ALLOCATOR=0

Regarding ancient g++ versions, how ancient? We used to support 4.8, but we lost our test environments for that, and at the moment it would take some work to get back 4.8 compatibility.

baallan commented 6 months ago

re ancient versions: rhel-8 and newer, so g++ 8.5. rhel 7 is eol in a month, so no 4.8 is longer of interest (or reasonable).

Same error with

cmake .. -DJSONCONS_HAS_STATEFUL_ALLOCATOR=0 -DJSONCONS_BUILD_TESTS=On -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON && cmake --build . -- VERBOSE=1 && ctest --output-on-failure
baallan commented 6 months ago

Possibly related to #488

danielaparker commented 6 months ago

Possibly related to #488

Yes, I misdiagnosed #488, @barracuda156 was using _GLIBCXX_USE_CXX11_ABI=0 and COW strings, and I thought it was related to that.

We've been relying on github-hosted compilers for linux/g++ tests. We introduced tests with std::scoped_allocator_adaptor wrapping a sample stateful allocator around the time github dropped g++ 9. I've just confirmed that those tests pass with all versions of g++ later than 10 (10, 11,12, 13) but fail to compile with earlier versions. I'm not sure why, I haven't been able to find an obviously related g++ defect report.

So you wouldn't be able to use regular stateful allocators (which we require to be wrapped in an std::scoped_allocator_adaptor) with g++ versions prior to 10. You should be able to use stateful pmr allocators with C++17. (I believe the vast majority of our users use the default (stateless) allocator.)

We'll fix the tests so you can compile them with the older compilers, and add some compilers to our coverage as well.

danielaparker commented 6 months ago

Could you try the cmake build with the code on master?

baallan commented 6 months ago

master now happily yields from:

cd build
cmake .. -DJSONCONS_HAS_STATEFUL_ALLOCATOR=0 -DJSONCONS_BUILD_TESTS=On -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON && cmake --build . -j -- VERBOSE=1 && ctest --output-on-failure
-- The CXX compiler identification is GNU 8.5.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- jsoncons v0.175.0
-- Forcing tests build type to Release
-- Version 8.5.0
-- Configuring done
-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:

    JSONCONS_HAS_STATEFUL_ALLOCATOR
...
[100%] Built target unit_tests
gmake[1]: Leaving directory '/app-data-collection/jsoncons/build'
/usr/bin/cmake -E cmake_progress_start /tlt/app-data-collection/jsoncons/build/CMakeFiles 0
Test project /tlt/app-data-collection/jsoncons/build
    Start 1: unit_tests
1/1 Test #1: unit_tests .......................   Passed    5.09 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   5.16 sec
danielaparker commented 6 months ago

Good. Incidentally, you don't need to supply -DJSONCONS_HAS_STATEFUL_ALLOCATOR=0. Tests for stateful allocators are configured to be #define'd out if the compiler is g++ and the version is less than 10.

barracuda156 commented 6 months ago

@danielaparker _GLIBCXX_USE_CXX11_ABI=0 is added by MacPorts base for systems using libstdc++, because if it is not done, different ABI will be used for ports which are built with the OS compiler (Xcode gcc) and newer gccs (which must be used when C++11 or later are required), and linking gonna fail in many instances.