Skip to content

Conversation

eramongodb
Copy link
Contributor

@eramongodb eramongodb commented Aug 13, 2025

This PR fixes and improves libmongocrypt compatibility with the mingw-w64 GCC toolchain (referred to as just "mingw" going forward for brevity) to unblock upcoming changes to downstream mingw task coverage improvements in the C and C++ drivers.


The first issue is with libbson compatibility:

 error: #error "__USE_MINGW_ANSI_STDIO > 0 is required for correct PRI* macros"
   27 | #error "__USE_MINGW_ANSI_STDIO > 0 is required for correct PRI* macros"
      |  ^~~~~

This is an old mingw compatibility problem that is well-described by this comment concerning format string tests:

The test failure appears if you compile for the target platform MINGW64 or MINGW32 which uses the old Microsoft C standard library called "msvcrt" which is C89 and also uses some MinGW functions that implement some C99 functionality. strftime is part of msvcrt which means it conforms only to C89 and it does not have the new conversion specifiers like %G or %g. The fix is to upgrade to MinGW+UCRT and just use the new C standard library which properly conforms to new standards.

Upgrading to a UCRT-based mingw-w64 toolchain is beyond the scope of this PR (although we should investigate doing so properly; filed DEVPROD-20813 in advance to prepare EVG Windows distros for such a transition). For now, given this mingw workaround applies to the entire codebase (not just libbson), a call to add_compile_definitions() is added to the root CMakeLists.txt that defines __USE_MINGW_ANSI_STDIO=1 for the entire project when CMake detects a MINGW compiler is being used.


The second issue is with calls to BCrypt* API:

error: passing argument 9 of 'BCryptEncrypt' from incompatible pointer type [-Werror=incompatible-pointer-types]
      |                               args.bytes_written,
      |                               ~~~~^~~~~~~~~~~~~~
      |                                   |
      |                                   uint32_t * {aka unsigned int *}
note: expected 'ULONG *' {aka 'long unsigned int *'} but argument is of type 'uint32_t *' {aka 'unsigned int *'}

The platform-independent struct aes_256_args_t contains a uint32_t *bytes_written pointer, where uint32_t is an unsigned int. This pointer type is incompatible with mingw where ULONG is defined as unsigned long. Therefore, a ULONG bytes_written local variable is used to obtain a valid pointer to ULONG (guarded by args.bytes_written != nullptr).


The third issue is related to the __USE_MINGW_ANSI_STDIO problem above:

warning: unknown conversion type character 'z' in format [-Wformat=]
      |       kms_request_str_appendf (v, "%zu", request->payload->len);
      |                                     ^

It seems __attribute__((format(__printf__, ...))) is not aware of __USE_MINGW_ANSI_STDIO=1 and uses the MSVCRT-compatible (non-C99-conforming) printf mingw definition rather than a C99-conforming definition. These warnings are addressed by using gnu_printf rather than __printf__ (or printf) when building with GCC, as currently done in mongo-c-driver (the GCC version check is omitted, as I do not believe we are, or want to, continue supporting such old GCC versions).

@eramongodb eramongodb requested a review from kevinAlbs August 13, 2025 20:47
@eramongodb eramongodb self-assigned this Aug 13, 2025
@eramongodb eramongodb requested a review from a team as a code owner August 13, 2025 20:47
Copy link
Contributor

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you for investigating and the fix.

@eramongodb eramongodb merged commit 9be8568 into mongodb:master Aug 15, 2025
52 of 55 checks passed
@eramongodb eramongodb deleted the crypt-mingw branch August 15, 2025 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants