commschamp / cc.mqttsn.libs

CommsChampion Ecosystem MQTT-SN client / gateway libraries and applications
Mozilla Public License 2.0
63 stars 16 forks source link

Version 2 does not build #16

Open trivialkettle opened 2 weeks ago

trivialkettle commented 2 weeks ago

Hi, I tried to compile the version 2 code and ran into the following build error:

$ BUILD_DIR=./build ./script/prepare_externals.sh
$ cd build/
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCC_MQTTSN_CLIENT_DEFAULT_LIB=OFF -DCMAKE_PREFIX_PATH=$(pwd)/externals/comms/build/install\;$(pwd)/externals/cc.mqttsn.generated/build/install\;$(pwd)/externals/cc.mqtt311.generated/build/install
-- The C compiler identification is GNU 14.2.1
-- The CXX compiler identification is GNU 14.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /sbin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /sbin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found LibComms: .../build/externals/comms/build/install/include
-- Found Doxygen: /sbin/doxygen (found version "1.12.0") found components: doxygen dot
-- Configuring done (0.8s)
-- Generating done (0.0s)
-- Build files have been written to: xxx/cc.mqttsn.libs/build
$ cmake --build . --config Release --target install
...
In file included from /usr/include/c++/14.2.1/bits/stl_uninitialized.h:63,
                 from /usr/include/c++/14.2.1/memory:69,
                 from xxx/cc.mqttsn.libs/gateway/lib/include/cc_mqttsn_gateway/Config.h:13,
                 from xxx/cc.mqttsn.libs/gateway/app/gateway/GatewayLogger.h:10,
                 from xxx/cc.mqttsn.libs/gateway/app/gateway/GatewaySession.h:10,
                 from xxx/cc.mqttsn.libs/gateway/app/gateway/GatewaySession.cpp:8:
In static member function ‘static _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = const unsigned char; _Up = unsigned char; bool _IsMove = false]’,
    inlined from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]’ at /usr/include/c++/14.2.1/bits/stl_algobase.h:521:30,
    inlined from ‘_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]’ at /usr/include/c++/14.2.1/bits/stl_algobase.h:548:42,
    inlined from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const unsigned char*; _OI = unsigned char*]’ at /usr/include/c++/14.2.1/bits/stl_algobase.h:555:31,
    inlined from ‘_OI std::copy(_II, _II, _OI) [with _II = const unsigned char*; _OI = unsigned char*]’ at /usr/include/c++/14.2.1/bits/stl_algobase.h:651:7,
    inlined from ‘static _ForwardIterator std::__uninitialized_copy<true>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const unsigned char*; _ForwardIterator = unsigned char*]’ at /usr/include/c++/14.2.1/bits/stl_uninitialized.h:147:27,
    inlined from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const unsigned char*; _ForwardIterator = unsigned char*]’ at /usr/include/c++/14.2.1/bits/stl_uninitialized.h:185:15,
    inlined from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = const unsigned char*; _ForwardIterator = unsigned char*; _Tp = unsigned char]’ at /usr/include/c++/14.2.1/bits/stl_uninitialized.h:373:37,
    inlined from ‘void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const unsigned char*; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]’ at /usr/include/c++/14.2.1/bits/vector.tcc:1022:38,
    inlined from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = const unsigned char*; <template-parameter-2-2> = void; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]’ at /usr/include/c++/14.2.1/bits/stl_vector.h:1488:19,
    inlined from ‘cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, std::size_t)>’ at xxx/cc.mqttsn.libs/gateway/app/gateway/GatewaySession.cpp:112:36,
    inlined from ‘constexpr _Res std::__invoke_impl(__invoke_other, _Fn&&, _Args&& ...) [with _Res = void; _Fn = cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, size_t)>&; _Args = {const unsigned char*, long unsigned int}]’ at /usr/include/c++/14.2.1/bits/invoke.h:61:36,
    inlined from ‘constexpr std::enable_if_t<((bool)is_invocable_r_v<_Res, _Callable, _Args ...>), _Res> std::__invoke_r(_Callable&&, _Args&& ...) [with _Res = void; _Callable = cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, size_t)>&; _Args = {const unsigned char*, long unsigned int}]’ at /usr/include/c++/14.2.1/bits/invoke.h:111:28,
    inlined from ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes&& ...) [with _Res = void; _Functor = cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, std::size_t)>; _ArgTypes = {const unsigned char*, long unsigned int}]’ at /usr/include/c++/14.2.1/bits/std_function.h:290:30:
/usr/include/c++/14.2.1/bits/stl_algobase.h:452:30: error: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ writing between 2 and 9223372036854775807 bytes into a region of size 0 overflows the destination [-Werror=stringop-overflow=]
  452 |             __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      |             ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/c++allocator.h:33,
                 from /usr/include/c++/14.2.1/bits/allocator.h:46,
                 from /usr/include/c++/14.2.1/memory:65:
In member function ‘_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = unsigned char]’,
    inlined from ‘static _Tp* std::allocator_traits<std::allocator<_Tp1> >::allocate(allocator_type&, size_type) [with _Tp = unsigned char]’ at /usr/include/c++/14.2.1/bits/alloc_traits.h:478:28,
    inlined from ‘std::_Vector_base<_Tp, _Alloc>::pointer std::_Vector_base<_Tp, _Alloc>::_M_allocate(std::size_t) [with _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]’ at /usr/include/c++/14.2.1/bits/stl_vector.h:380:33,
    inlined from ‘void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const unsigned char*; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]’ at /usr/include/c++/14.2.1/bits/vector.tcc:1013:40,
    inlined from ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = const unsigned char*; <template-parameter-2-2> = void; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>]’ at /usr/include/c++/14.2.1/bits/stl_vector.h:1488:19,
    inlined from ‘cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, std::size_t)>’ at xxx/cc.mqttsn.libs/gateway/app/gateway/GatewaySession.cpp:112:36,
    inlined from ‘constexpr _Res std::__invoke_impl(__invoke_other, _Fn&&, _Args&& ...) [with _Res = void; _Fn = cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, size_t)>&; _Args = {const unsigned char*, long unsigned int}]’ at /usr/include/c++/14.2.1/bits/invoke.h:61:36,
    inlined from ‘constexpr std::enable_if_t<((bool)is_invocable_r_v<_Res, _Callable, _Args ...>), _Res> std::__invoke_r(_Callable&&, _Args&& ...) [with _Res = void; _Callable = cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, size_t)>&; _Args = {const unsigned char*, long unsigned int}]’ at /usr/include/c++/14.2.1/bits/invoke.h:111:28,
    inlined from ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes&& ...) [with _Res = void; _Functor = cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, std::size_t)>; _ArgTypes = {const unsigned char*, long unsigned int}]’ at /usr/include/c++/14.2.1/bits/std_function.h:290:30:
/usr/include/c++/14.2.1/bits/new_allocator.h:151:55: note: at offset [-9223372036854775808, -1] into destination object of size [1, 9223372036854775807] allocated by ‘operator new’
  151 |         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
      |                                                       ^
cc1plus: all warnings being treated as errors
make[2]: *** [gateway/app/gateway/CMakeFiles/cc_mqttsn_gateway_app.dir/build.make:216: gateway/app/gateway/CMakeFiles/cc_mqttsn_gateway_app.dir/GatewaySession.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:283: gateway/app/gateway/CMakeFiles/cc_mqttsn_gateway_app.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

When I built the target it worked though.

$ cmake --build /xxx/cc.mqttsn.libs/build --target cc_mqttsn_gateway_app -- -j 4
arobenko commented 2 weeks ago

I would attribute it to be a bug in the compiler. It's just unable to compile a legit line of code of appending data to the end of std::vector.

    ...
    inlined from ‘cc_mqttsn_gateway_app::GatewaySession::doBrokerConnect()::<lambda(const uint8_t*, std::size_t)>’ at xxx/cc.mqttsn.libs/gateway/app/gateway/GatewaySession.cpp:112:36,
    ...

The only thing I can recommend here is to try to build without treating warnings as errors, i.e. pass -DCC_MQTTSN_WARN_AS_ERR=OFF to your cmake invocation.

I didn't come around to upgrade my development system to Ubuntu-24.04, still using 22.04. I'll try to reproduce the problem on github actions ubuntu-24.04 runner and see if I can do anything to workaround the problem.

arobenko commented 1 week ago

The ubuntu-24.04 runner on github actions uses gcc v14.0.1 and compiles fine. Looks like the image hasn't been updated for a while. I guess it will have to wait until I upgrade my development PC to 24.04 and reproduce the issue in my environment.

trivialkettle commented 1 week ago

I could reproduce the issue using the gcc-14.2, gcc-14.1 and gcc-13 docker image:

# clone repository and cd into then:
docker run -it --rm -v $(pwd):/src gcc:14.2
apt-get update && apt-get install --yes cmake libboost-all-dev
cd src
BUILD_DIR=./build ./script/prepare_externals.sh
cd build/
cmake .. -DCMAKE_BUILD_TYPE=Release -DCC_MQTTSN_CLIENT_DEFAULT_LIB=OFF -DCMAKE_PREFIX_PATH=$(pwd)/externals/comms/build/install\;$(pwd)/externals/cc.mqttsn.generated/build/install\;$(pwd)/externals/cc.mqtt311.generated/build/install
cmake --build . --config Release --target install
trivialkettle commented 1 week ago

I also tested with ubuntu-24.

My Dockerfile:

FROM curlimages/curl:latest AS download

ARG MQTTSN_GW_VERSION=2.0.3
ARG LINK=https://github.com/commschamp/cc.mqttsn.libs/archive/refs/tags
RUN echo $(PWD)
RUN curl -L ${LINK}/v${MQTTSN_GW_VERSION}.tar.gz -o /tmp/mqttsn.tar.gz \
    && mkdir /tmp/mqttsn/ \
    && tar -zxf /tmp/mqttsn.tar.gz -C /tmp/mqttsn --strip-components=1

FROM ubuntu:24.04 AS build

RUN set -eux; \
    apt-get update; \
    apt-get install --yes --no-install-recommends \
      make \
      ca-certificates  \
      cmake \
      gcc-14 \
      g++-14 \
      git \
      libboost-all-dev \
    ; \
    rm -rf /var/lib/apt/lists/*

COPY --from=download /tmp/mqttsn/ ./mqttsn/
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 50; \
    update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 50

RUN cd mqttsn/ \
    && mkdir build \
    && BUILD_DIR=./build ./script/prepare_externals.sh \
    && cd build \
    && cmake .. -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_CXX_STANDARD=20 \
      -DCC_MQTTSN_CLIENT_DEFAULT_LIB=OFF \
      -DCC_MQTTSN_WARN_AS_ERR=OFF \
      -DCMAKE_PREFIX_PATH=$(pwd)/externals/comms/build/install\;$(pwd)/externals/cc.mqttsn.generated/build/install\;$(pwd)/externals/cc.mqtt311.generated/build/install \
    && cmake --build /mqttsn/build/ --target cc_mqttsn_gateway_app -- -j4

There are even some warnings related to builtin_memcmp:

#12 23.41 In file included from /usr/include/c++/14/list:62,
#12 23.41                  from /mqttsn/gateway/lib/src/session_op/Encapsulate.h:11,
#12 23.41                  from /mqttsn/gateway/lib/src/session_op/Encapsulate.cpp:8:
#12 23.41 In function 'constexpr decltype (__comp((* __first1), (* __first2))) std::lexicographical_compare_three_way(_InputIter1, _InputIter1, _InputIter2, _InputIter2, _Comp) [with _InputIter1 = __gnu_cxx::__normal_iterator<const unsigned char*, vector<unsigned char> >; _InputIter2 = __gnu_cxx::__normal_iterator<const unsigned char*, vector<unsigned char> >; _Comp = __detail::_Synth3way]',
#12 23.41     inlined from 'constexpr std::__detail::__synth3way_t<_T1> std::operator<=>(const vector<_Tp, _Alloc>&, const vector<_Tp, _Alloc>&) [with _Tp = unsigned char; _Alloc = allocator<unsigned char>]' at /usr/include/c++/14/bits/stl_vector.h:2071:52,
#12 23.41     inlined from 'constexpr bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::vector<unsigned char>]' at /usr/include/c++/14/bits/stl_function.h:405:20,
#12 23.41     inlined from 'std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = std::vector<unsigned char>; _Val = std::pair<const std::vector<unsigned char>, std::unique_ptr<cc_mqttsn_gateway::Session> >; _KeyOfValue = std::_Select1st<std::pair<const std::vector<unsigned char>, std::unique_ptr<cc_mqttsn_gateway::Session> > >; _Compare = std::less<std::vector<unsigned char> >; _Alloc = std::allocator<std::pair<const std::vector<unsigned char>, std::unique_ptr<cc_mqttsn_gateway::Session> > >]' at /usr/include/c++/14/bits/stl_tree.h:2114:35:
#12 23.41 /usr/include/c++/14/bits/stl_algobase.h:1874:39: warning: 'int __builtin_memcmp(const void*, const void*, long unsigned int)' specified bound [9223372036854775808, 18446744073709551615] exceeds maximum object size 9223372036854775807 [-Wstringop-overread]
#12 23.41  1874 |                     = __builtin_memcmp(&*__first1, &*__first2, __blen) <=> 0;
#12 23.41       |                       ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

And the __builtin_memmove warning shwn above.

arobenko commented 1 week ago

I'm planning to upgrade my development system to 24.04 over the next weekend and will take closer look at it. However, I think the "fix" is going to be to suppress the pesky warning. The gcc bug tracking seems to have similar issues to periodically pop-up, like this one. As a temporary option, please pass -DCC_MQTTSN_WARN_AS_ERR=OFF to your CMake configuration.