CXX-3180 address misc. mingw-w64 GCC compatibility issues #1512
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Related to CXX-3180. This PR applies various mingw-w64 GCC toolchain ("mingw") compatibility fixes to enable pkg-config tasks coverage on Windows (CXX-2973).
This PR is a followup to various prior work across the libmongocrypt and mongo-c-driver repositories concerning mingw compatibility. It is not sufficient to build the C++ Driver libraries with mingw alone: all dependent libraries must also be built with the same toolchain in order to satisfy linker requirements (a la libstdc++ vs. libc++). Therefore, upstream compatibility issues in the C Driver and libmongocrypt libraries needed to be addressed together or in advance of the C++ Driver libraries.
This PR description enumerates the various compatibility issues addressed by this PR (ordered by commit).
mingw-w64 GCC refuses to link weak variable symbols:
Per GCC docs:
Therefore, this PR proposes using
[[gnu::selectany]]instead of[[gnu::weak]]on Windows, for mingw-w64 GCC only, via theBSONCXX_PRIVATE_INLINE_CXX17macro added in #1468.When linking with mingw, ABI symbols do not seem to have a unique address as typically assumed:
This
scoped_bsontest assumes the globally-definedbson_freefunction has a unique address; however, this (and related) test assertions fail, suggesting themongocxx_mockedlibrary "sees" a different definition ofbson_freethan thetest_driverexecutable. It is unclear to me if this behavior also affects other unique identity assumptions within the codebase, such as inbsoncxx::v1::document::valueconcerning the identity of the preallocated empty BSON document storage. For now, this PR implements a workaround that tests the inverse of the regular "deleter changed as expected" ("changed to Y" -> "is no longer X").Possibly related to the
bson_freeissue, the behavior ofbson_concat()allocation viascoped_bsondiffers when built with mingw:I do not think there is a compelling motivation for the error message here to differ from the one here given both depend on the result of
bson_concat(notbson_new_from_data). Therefore, this PR makes the error messages the same in both cases.Possibly related to the
bson_freeissue, linking with mingw detected an ODR violation of theCatch::StringMaker<T>::convert()specialization forbsoncxx::v1::document::view(output edited for clarity):This seems to be caused by the implicit instantiation of
Catch::StringMaker<T>in thebsoncxx/test/v_noabi/array.cppcomponent inbsoncxx_testing, which later conflicts with the explicit definition(s) defined by themongocxx_mockedlibrary. It is unclear why this ODR violation is not detected during linking of thebsoncxx_testinglibrary itself.Building with mingw-w64 revealed the presence of overlooked export macros applied to inline function definitions, e.g.:
All such stray export macros are removed by this PR.
mingw does not provide
<sys/wait.h>, per docs:Preprocessor conditions for
fork()-related test features are extended from excluding MSVC only (defined(_MSC_VER)) to excluding Windows entirely (defined(_WIN32)).Following mongodb/mongo-c-driver#2171 (MSVCRT -> UCRT), in theory the compatibility issues with C99 format specifiers should have all been addressed. However, despite the UCRT library documenting support for C99 format specifiers, including
%Fand%Tforstd::strftime, mingw does not seem to correctly expose these features in its own front-end:This is not merely a compiler warning problem: the runtime behavior is also unsupported:
This unresolved GCC issue may be related, summarized:
Per this comment:
GCC 12 and newer may be required for correct behavior; however, the currently available mingw-w64 GCC toolchain on
windows-2022-latestfollowing DEVPROD-20813 is GCC 10.2.0. Unless the choco winlibs package is updated or DevProd manually installs a newer version (GCC 15.2 is currently available) and we document/enforce minimum mingw-w64 GCC compiler requirements, we will likely need to continue supporting these compatibility issues. Therefore, this PR rewrites the format specifiers as (near-)equivalents (e.g.%F->%Y-%m-%d).