Skip to content

windows: cross-compile Fluent Bit for Windows with the MinGW-w64 (UCRT64) toolchain - #12069

Draft
hjiawei wants to merge 20 commits into
fluent:masterfrom
hjiawei:mingw-ucrt64-cross-build
Draft

hjiawei wants to merge 20 commits into
fluent:masterfrom
hjiawei:mingw-ucrt64-cross-build

Conversation

@hjiawei

@hjiawei hjiawei commented Jul 7, 2026 •

Copy link
Copy Markdown

This draft PR lets Fluent Bit cross-compile for Windows from a Linux host with the MinGW-w64 UCRT64 toolchain (GCC). The result is a working fluent-bit.exe (PE32+ x86-64) with the standard Windows plugin set, including the WASM filter.

The existing MSVC build compiles the same code as before. MinGW-only fixes are gated on __MINGW32__ or if(MINGW). Gates widened from _MSC_VER to _WIN32 take the same branch under MSVC, which defines both.

Depends on bundled-library PRs: please do not merge first

Each bundled-library change here has been submitted upstream. The lib/ hunks are carried only so the cross-build works meanwhile. They should arrive through a re-vendor before this PR merges.

Bundled library Upstream PR Status
lib/monkey monkey/monkey#443 open
lib/chunkio fluent/chunkio#114 open
lib/wasm-micro-runtime-WAMR-2.4.1 wasm-micro-runtime/wasm-micro-runtime#4987 merged; not in a WAMR release yet (latest is WAMR-2.4.5)
lib/flb_libco edsiper/flb_libco#12 closed; fixed upstream in 96d61ad, already vendored here, no carry
lib/cmetrics fluent/cmetrics#280 merged and re-vendored, no carry

Fluent Bit links monkey's bundled libco, not lib/flb_libco. CMakeLists.txt adds lib/flb_libco only when no co target exists, and monkey defines co first. So the 96d61ad vendor alone leaves x86_64 MinGW on amd64.c. The monkey carry applies the same backend order to monkey's copy, using the upstream text.

These bundled libraries need no source change:

  • snappy: its MSVC intrinsic path builds under MinGW.
  • nghttp2: its inline byte-order fallback compiles as-is.
  • libevent (bundled in monkey): it detects MinGW and links its own platform libraries.
  • Onigmo: the build files copy its shipped win32/config.h over the misdetected one.

Fluent Bit changes

Area Change
Build (CMakeLists.txt, src/, plugins/) MinGW flags, autoconf host triple for cross-builds, lowercase Windows link libraries, static libyaml, import-library naming, and in_etw only on MSVC (MinGW ships a stub tdh.h)
compat headers use MinGW's winpthreads and skip the MSVC-only shims
WASM pick the WAMR platform from the target, not the build host; use the generic native-call wrapper instead of MASM
src/ and config_format widen _MSC_VER gates to _WIN32; lowercase Windows header includes
Plugins Windows gate, header and declaration fixes in six plugins; C23 prototype fix in filter_throttle_size
network fix the flb_net_server_unix fallback stub signature
CI new pr-compile-mingw-cross job in pr-compile-check.yaml on fedora:44
Docs cross-compile section in DEVELOPER_GUIDE.md

The network stub and filter_throttle_size fixes also apply to non-MinGW builds.


Enter [N/A] in the box, if an item is not applicable to your change.

Testing

This is a build and toolchain change, so the runtime items below are N/A. The new CI job cross-builds fluent-bit.exe on every PR. Local runs on master (adee1f53b):

Check Result
MinGW cross-build with the CI job's flags (fedora:44, CMake 3.31.6) pass, 1410/1410 targets; libco uses the fiber backend
Native Linux build with runtime and internal tests pass
flb-rt-in_http, flb-rt-filter_throttle, flb-it-network, flb-it-config_format* pass, 6/6
commit_prefix_check.py over all 20 commits pass
  • [N/A] Example configuration file for the change

  • [N/A] Debug log output from testing the change

  • [N/A] Attached Valgrind output that shows no leaks or memory corruption was found

  • Run local packaging test showing all targets (including any new ones) build.

  • Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

  • Documentation required for this feature

Backporting

  • [N/A] Backport to latest stable release.

Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cosmo0920

cosmo0920 commented Jul 7, 2026 •

Copy link
Copy Markdown
Contributor

We need to send patches into upstream if we wanted to patch bundled libraries.

@hjiawei
hjiawei force-pushed the mingw-ucrt64-cross-build branch 2 times, most recently from 4d96c59 to 6dc3994 Compare July 7, 2026 07:20
@hjiawei

hjiawei commented Jul 7, 2026

Copy link
Copy Markdown
Author

We need to send patches into upstream if we wanted to patch bundled libraries.

Agreed. Each bundled-library change has been submitted upstream. They are listed in the PR description. I will rebase or update the vendored libs once they are merged or brought into the Fluent Bit codebase.

@hjiawei
hjiawei force-pushed the mingw-ucrt64-cross-build branch 2 times, most recently from 34b9aba to b21b836 Compare July 8, 2026 14:20
@hjiawei
hjiawei force-pushed the mingw-ucrt64-cross-build branch from b21b836 to dd7de3e Compare August 6, 2026 06:51
Make the cmake tree usable for a Linux-hosted MinGW-w64 UCRT64
cross-build targeting Windows, building the standard Windows plugin
profile from cmake/windows-setup.cmake:

- Define _POSIX_THREAD_SAFE_FUNCTIONS so the MinGW headers declare the
  POSIX gmtime_r()/localtime_r() family, and keep the Winsock
  char-pointer signature mismatches (warnings under MSVC) from becoming
  hard errors under GCC 14 and later unless the strict option is set.
- Derive the autoconf host triple from the cross compiler when
  CMAKE_CROSSCOMPILING and no GNU_HOST was given, so the external
  autotools sub-builds (libbacktrace, jemalloc) configure for the
  target instead of silently producing build-host objects.
- Use plain make for external autotools sub-builds under the Ninja
  generator on all targets; the $(MAKE) escape only exists in the
  Make-family generators.
- Give the executable an import-library suffix distinct from the shared
  library's on MinGW, mirroring the MSVC branch; Ninja rejects the
  duplicate libfluent-bit.dll.a output NMake never noticed.
- Link libbacktrace on fluent-bit-static, where the stacktrace helpers
  are compiled, so GNU ld orders the archive correctly.
- Guard the MSVC /W2 warning flag with if(MSVC) in the core and plugin
  cmake files, link the Windows system libraries by their lowercase
  names (GNU ld resolves them against import libraries, MSVC accepts
  them unchanged), and append to FLB_DEPS instead of overwriting it so
  onigmo-static and friends survive on Windows.
- Keep the ELF hardening link flags off for all Windows targets, not
  just MSVC, since GNU ld does not support them for PE.
- Define YAML_DECLARE_STATIC for any Windows toolchain when
  FLB_LIBYAML_DIR is given; that path carries a static libyaml for MSVC
  (vcpkg static triplets) and MinGW alike.
- Link OpenSSL statically only on MSVC; the MinGW cross-build uses the
  toolchain's dynamic OpenSSL to avoid GNU ld link-order issues.
- Keep FLB_HAVE_UNIX_SOCKET off for non-MSVC Windows builds: the Windows
  unix socket paths are untested, so keep feature parity with MSVC.
- Skip the tools/xxd-c host tool when cross-compiling, since it cannot
  run on the build host.
- Overwrite onigmo's generated config.h with the win32/config.h it
  ships when cross-compiling to Windows; Onigmo's configure-time probes
  otherwise inspect the build host and misdetect the target. This keeps
  the vendored onigmo tree unpatched.
- Register in_etw only for MSVC. The plugin decodes events with the TDH
  API, and MinGW-w64 ships only a stub tdh.h without the TDH_INTYPE_*
  and TdhGetEventInformation declarations it needs.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
MinGW-w64 UCRT headers already provide strcasecmp(), strncasecmp(),
timezone, tzname, usleep() and, with _POSIX_THREAD_SAFE_FUNCTIONS set
by the build system, the POSIX gmtime_r()/localtime_r() family, plus a
real pthread implementation (winpthreads); redefining them or pulling
in monkey's Windows pthread shim breaks compilation. Guard the MSVC
replacement shims and route MinGW to <pthread.h>, mapping only the BSD
random()/srandom() pair the MinGW unistd.h lacks. Use GCC's __thread
for the thread-local basename() buffer since MinGW GCC ignores
__declspec(thread), add a PTHREAD_STACK_MIN fallback for the coroutine
stack sizing, lowercase the wincrypt.h include for cross-builds from
case-sensitive filesystems, and use the Windows gate instead of the
MSVC one in flb_langinfo.h.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
The header declares flb_net_server_unix() with four parameters, but the
fallback stub compiled when FLB_HAVE_UNIX_SOCKET is not set still has
the old three-parameter signature, so any platform taking that branch
fails to compile with a conflicting declaration error.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
The glob(3) fallback and _fullpath() usage apply to any Windows
toolchain, not just MSVC, so gate them on _WIN32 instead of _MSC_VER,
and lowercase the windows.h include so it resolves against the
lowercase MinGW SDK headers when cross-compiling from a case-sensitive
filesystem. No behavior change for MSVC builds.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
hjiawei added 16 commits October 8, 2026 11:08
Make the bundled WAMR runtime build for a Windows target with a
non-MSVC toolchain:

- Select the WAMR platform port from the target system (CMAKE_SYSTEM_NAME)
  instead of the build host, so a Linux-hosted Windows cross-build uses
  the windows port rather than compiling the linux port against missing
  POSIX headers.
- The MASM assembler (ASM_MASM) is MSVC-only, so enable it only for
  MSVC; MinGW and other Windows toolchains still build WASM, using the
  generic C native-call wrapper the ARM64 Windows build already uses.
- Link pathcch and ntdll, which WAMR's Windows platform needs for
  PathCchCombine (win_file.c) and NtQueryTimerResolution (win_clock.c).
  MSVC pulls these in via #pragma comment(lib, ...), which GCC ignores;
  declare them on vmlib-static so CMake orders them after the archive on
  consumers' link lines.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
GCC on a case-sensitive filesystem cannot resolve the capitalised
<ConsoleApi.h>; MSVC is unaffected.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
The blocks guard Windows-only functionality, not the MSVC compiler, so
MinGW builds must take the same path.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
The block guards Windows-only functionality, not the MSVC compiler.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
The blocks guard Windows-only functionality, not the MSVC compiler.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
Capitalised headers do not resolve on a case-sensitive filesystem under
GCC; MSVC is unaffected.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
…table

The prototype used empty parens; under C23 that means (void) and
conflicts with the definition that takes a size_t.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
The block guards Windows functionality, not MSVC; the capitalised header
also fails to resolve under GCC.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
The block guards Windows functionality, not MSVC; the capitalised header
also fails to resolve under GCC.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
Only test the socket type when the platform provides the macro.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
Widen the MSVC-only CMake gate to WIN32, link shlwapi by its lowercase
name, and lowercase the windows.h includes in the win32 helpers.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
…nGW build

Add the missing math.h and we_util.h/we_perflib.h includes and adjust
the headers so the plugin compiles with GCC.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
Capitalised headers do not resolve on a case-sensitive filesystem under
GCC; MSVC is unaffected.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
Make the vendored libraries build and run with the MinGW-w64 UCRT
toolchain. Each change belongs in the library's own upstream and has
been submitted there (monkey/monkey#443, fluent/chunkio#114,
wasm-micro-runtime/wasm-micro-runtime#4987), so these hunks are carried
here only until those land in a release and are re-vendored. cmetrics
(fluent/cmetrics#280) and the top-level flb_libco have completed this
cycle and are no longer carried. Two other vendored libraries need no
source change: nghttp2 (its inline byte-order fallback compiles as-is;
the consumers that include it do not pull in winsock2) and snappy (its
MSVC intrinsic path builds under MinGW). Onigmo's cross-compile config
is handled in the fluent-bit build files, not by patching its tree.

- monkey: select the POSIX threading model for MinGW (winpthreads is a
  real pthread implementation; the hand-rolled shim stays MSVC-only),
  guard the MSVC-only typedefs and shims MinGW already provides, widen
  MSVC-only gates covering Windows functionality to _WIN32, use the
  standard GCC container_of, and lowercase Windows header includes.
  The bundled libevent needs no changes. In monkey's bundled
  deps/flb_libco, check _WIN32 before the architecture so x86_64 MinGW
  selects the fiber backend, matching lib/flb_libco. The HTTP server
  build compiles this copy.
- chunkio: guard the ssize_t/mode_t typedefs MinGW provides, widen the
  fts.h gate to _WIN32, lowercase Windows header includes, and link
  shell32 by its lowercase name.
- wasm-micro-runtime: lowercase the pathcch.h include and reword the //
  comments in win_file.c that end in a backslash; GCC treats a
  backslash-newline as a line continuation even inside a // comment and
  swallows the following line of code, while MSVC does not.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
Add a compile sanity check that cross-builds fluent-bit.exe for Windows
from Linux with the Fedora MinGW-w64 UCRT64 toolchain, so the MinGW
support does not bit-rot. The job runs in a fedora container, pins the
same cmake version as the other compile checks, cross-builds a static
libyaml, and configures with the distribution's ucrt64 toolchain file
and the standard Windows plugin defaults. It is a single configuration
with no matrix to keep the added CI cost low.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
Document the Linux-hosted MinGW-w64 UCRT64 cross-compilation option in
the Windows section of the developer guide, pointing at the
pr-compile-mingw-cross workflow job as the reference recipe.

Signed-off-by: Jiawei Huang <jiawei@tigera.io>
@hjiawei
hjiawei force-pushed the mingw-ucrt64-cross-build branch from dd7de3e to 7f717e4 Compare October 8, 2026 18:35

This branch was previously deployed

1 inactive (outdated) deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants