-
Notifications
You must be signed in to change notification settings - Fork 549
CXX-3180 address misc. mingw-w64 GCC compatibility issues #1512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
kevinAlbs
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with minor changes. The detailed write-up is much appreciated.
| // (multiple definitions) until 19.20 even when __cpp_inline_variables is defined. | ||
| // | ||
| // mingw-w64: this is an ancient bug/issue: https://sourceware.org/bugzilla/show_bug.cgi?id=9687. Use the | ||
| // Windows-specific [[gnu::selectany]] attribute instead, which provides linke-once semantics for global variables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Windows-specific [[gnu::selectany]] attribute instead, which provides linke-once semantics for global variables. | |
| // Windows-specific [[gnu::selectany]] attribute instead, which provides link-once semantics for global variables. |
| (__cplusplus >= 201703L || (defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L))) || \ | ||
| (defined(_MSC_VER) && _MSC_VER >= 1920 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) | ||
| #define BSONCXX_PRIVATE_INLINE_CXX17 inline | ||
| #elif defined(__MINGW32__) || defined(__MINGW64__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #elif defined(__MINGW32__) || defined(__MINGW64__) | |
| #elif defined(__MINGW32__) |
Remove unnecessary check? Other changes in this PR only check for __MINGW32__, and https://sourceforge.net/p/predef/wiki/Compilers/ notes __MINGW32__ is defined for both 32 and 64 bit builds.
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).