Uploaded image for project: 'C++ Driver'
  1. C++ Driver
  2. CXX-880

MongoDB C++11 driver fails to build on FreeBSD

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Blocker - P1 Blocker - P1
    • 3.0.2
    • Affects Version/s: 3.0.0
    • Component/s: Portability
    • Labels:

      The driver fails to build on FreeBSD with the following errors:

      [  4%] Building CXX object src/bsoncxx/CMakeFiles/bsoncxx.dir/types/value.cpp.o
      In file included from /home/karrotkake/mongo-cxx-driver/src/bsoncxx/types/value.cpp:48:
      /home/karrotkake/mongo-cxx-driver/src/bsoncxx/enums/type.hpp:20:1: error: static_assert failed "Copy may throw"
      BSONCXX_ENUM(utf8, 0x02)
      ^~~~~~~~~~~~~~~~~~~~~~~~
      /home/karrotkake/mongo-cxx-driver/src/bsoncxx/types/value.cpp:36:9: note: expanded from macro 'BSONCXX_ENUM'
              static_assert(std::is_nothrow_copy_constructible<b_##name>::value, "Copy may throw");  \
              ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      In file included from /home/karrotkake/mongo-cxx-driver/src/bsoncxx/types/value.cpp:48:
      /home/karrotkake/mongo-cxx-driver/src/bsoncxx/enums/type.hpp:31:1: error: static_assert failed "Copy may throw"
      BSONCXX_ENUM(code, 0x0D)
      ^~~~~~~~~~~~~~~~~~~~~~~~
      /home/karrotkake/mongo-cxx-driver/src/bsoncxx/types/value.cpp:36:9: note: expanded from macro 'BSONCXX_ENUM'
              static_assert(std::is_nothrow_copy_constructible<b_##name>::value, "Copy may throw");  \
              ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      In file included from /home/karrotkake/mongo-cxx-driver/src/bsoncxx/types/value.cpp:48:
      /home/karrotkake/mongo-cxx-driver/src/bsoncxx/enums/type.hpp:32:1: error: static_assert failed "Copy may throw"
      BSONCXX_ENUM(symbol, 0x0E)
      ^~~~~~~~~~~~~~~~~~~~~~~~~~
      /home/karrotkake/mongo-cxx-driver/src/bsoncxx/types/value.cpp:36:9: note: expanded from macro 'BSONCXX_ENUM'
              static_assert(std::is_nothrow_copy_constructible<b_##name>::value, "Copy may throw");  \
              ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      3 errors generated.
      *** [src/bsoncxx/CMakeFiles/bsoncxx.dir/types/value.cpp.o] Error code 1
      

      Interesting that BSON types b_symbol, b_code and b_utf8 fail nothrow requirement of the constructor. The fix I applied in this case is to rewrite "bsoncxx/types/value.cpp:32"

      #if !defined(BSONCXX_POLY_USE_BOOST)
      

      as

      #if defined(BSONCXX_POLY_USE_BOOST)
      

      Another error relates to failure of the Clang to select and appropriate overloaded function when using chrono::count(), here's an error example for modify_collection.cpp (it fails also on collection.cpp, basically anywhere append() is called with chrono::count()):

      [ 20%] Building CXX object src/mongocxx/CMakeFiles/mongocxx.dir/options/modify_collection.cpp.o
      In file included from /home/karrotkake/mongo-cxx-driver/src/mongocxx/options/modify_collection.cpp:17:
      In file included from /home/karrotkake/mongo-cxx-driver/src/bsoncxx/builder/stream/document.hpp:18:
      In file included from /home/karrotkake/mongo-cxx-driver/src/bsoncxx/builder/stream/key_context.hpp:19:
      /home/karrotkake/mongo-cxx-driver/src/bsoncxx/builder/stream/value_context.hpp:70:16: error: call to member
            function 'append' is ambiguous
              _core->append(std::forward<T>(t));
              ~~~~~~~^~~~~~
      /home/karrotkake/mongo-cxx-driver/src/mongocxx/options/modify_collection.cpp:38:55: note: in instantiation of
            function template specialization
            'bsoncxx::v_noabi::builder::stream::value_context<bsoncxx::v_noabi::builder::stream::key_context<bsoncxx::v_noabi::builder::stream::closed_context>
            >::operator<<<long long>' requested here
                                    << "expireAfterSeconds" << seconds.count() << finalize);
      

      The problem comes from the fact that libc++ <chrono> defines seconds, milliseconds etc. as:

      typedef duration<long long,        milli> milliseconds;
      typedef duration<long long              > seconds;
      

      But append() accepts int32_t, int64_t etc., and int64_t is defined in system <stdint.h> header as

      typedef long int64_t
      

      So compiler fails during overload resolutio to select correct version of append(), because chrono::count() returns long long which, supposedly, can match into both append(int32_t) and append(int64_t).

      Also here's the include hierarchy of Clang's (libc++) <cstdint> header:

      . /usr/include/c++/v1/cstdint
      .. /usr/include/c++/v1/__config
      ... /usr/include/sys/endian.h
      .... /usr/include/sys/cdefs.h
      .... /usr/include/sys/_types.h
      ..... /usr/include/machine/_types.h
      ...... /usr/include/x86/_types.h
      

            Assignee:
            mira.carey@mongodb.com Mira Carey
            Reporter:
            KarrotKake Jimmy [X]
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: