Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f5910ea
build: support Windows cross-compilation with the MinGW toolchain
hjiawei Jul 6, 2026
9282a0a
compat: support the MinGW UCRT toolchain in Windows headers
hjiawei Jul 6, 2026
ac0cd21
network: fix share_port arg in flb_net_server_unix fallback stub
hjiawei Jul 6, 2026
22be970
config_format: use Windows gates for MinGW cross-builds
hjiawei Jul 6, 2026
4b5f1be
wasm: cross-compile WAMR for Windows with the MinGW toolchain
hjiawei Jul 6, 2026
6423c62
bin: lowercase the consoleapi.h include for MinGW cross-builds
hjiawei Jul 8, 2026
3f479da
sosreport: gate Windows code on _WIN32 instead of _MSC_VER
hjiawei Jul 8, 2026
6537346
time: gate Windows code on _WIN32 instead of _MSC_VER
hjiawei Jul 8, 2026
825fc43
tls: gate Windows code on _WIN32 instead of _MSC_VER
hjiawei Jul 8, 2026
0be0f35
win32: lowercase the windows.h/shlwapi.h includes for MinGW cross-builds
hjiawei Jul 8, 2026
4e69669
filter_throttle_size: add the size parameter to create_throttle_size_…
hjiawei Jul 8, 2026
2c79ad0
in_calyptia_fleet: gate on _WIN32 and lowercase windows.h for MinGW
hjiawei Jul 8, 2026
04a15bd
in_prometheus_textfile: gate on _WIN32 and lowercase windows.h for MinGW
hjiawei Jul 8, 2026
52e3a1c
in_syslog: guard S_ISSOCK, which MinGW's headers do not define
hjiawei Jul 8, 2026
c5e2958
in_tail: use a WIN32 gate and lowercase shlwapi for MinGW
hjiawei Jul 8, 2026
78e19f0
in_windows_exporter_metrics: fix includes and declarations for the Mi…
hjiawei Jul 8, 2026
c379f0e
out_file: lowercase the shlobj.h/shlwapi.h includes for MinGW
hjiawei Jul 8, 2026
4880080
lib: carry upstream-bound MinGW cross-build fixes for vendored libraries
hjiawei Jul 6, 2026
1cd43cb
workflows: add MinGW UCRT64 Windows cross-compile check
hjiawei Jul 6, 2026
b21b836
docs: describe MinGW Windows cross-compilation
hjiawei Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/pr-compile-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,49 @@ jobs:
cmake -DFLB_PREFER_SYSTEM_LIB_ZSTD=ON -DFLB_PREFER_SYSTEM_LIB_KAFKA=ON ../
make -j $nparallel
working-directory: build

# Sanity check for Windows cross-compilation from Linux with the
# MinGW-w64 UCRT64 toolchain (no MSVC or Windows runner involved).
# See "Cross-compiling for Windows with MinGW" in DEVELOPER_GUIDE.md.
pr-compile-mingw-cross:
runs-on: ubuntu-latest
container: fedora:44
timeout-minutes: 60
steps:
- name: Install toolchain and build dependencies
run: |
dnf install -y bison file flex gcc git make ninja-build \
ucrt64-gcc ucrt64-gcc-c++ ucrt64-openssl ucrt64-zlib

- name: Install cmake
uses: jwlawson/actions-setup-cmake@0d6a7d60b009d01c9e7523be22153ff8f19460d3 # v2.2.0
with:
cmake-version: "3.31.6"

- name: Checkout Fluent Bit code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Cross-compile a static libyaml
run: |
mkdir -p /tmp/libyaml-src
curl -sfL https://github.com/yaml/libyaml/releases/download/0.2.5/yaml-0.2.5.tar.gz \
| tar xz --strip-components 1 -C /tmp/libyaml-src
cd /tmp/libyaml-src
./configure --host=x86_64-w64-mingw32ucrt --prefix=/opt/libyaml \
--enable-static --disable-shared CFLAGS="-DYAML_DECLARE_STATIC"
make -j 8 -C src
make -C src install
make -C include install

# No plugin selection here: the build takes the standard Windows
# defaults from cmake/windows-setup.cmake, the same profile the MSVC
# Windows CI builds.
- name: Cross-compile Fluent Bit for Windows
run: |
cmake -G Ninja \
-DCMAKE_TOOLCHAIN_FILE=/usr/share/mingw/toolchain-ucrt64.cmake \
-DFLB_LIBYAML_DIR=/opt/libyaml \
../
ninja
file bin/fluent-bit.exe
working-directory: build
59 changes: 52 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ if (MSVC)
add_compile_options(/MT)
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
if (MINGW)
# MinGW-w64 headers only declare the POSIX thread-safe time functions
# (gmtime_r and friends) when the feature test macro is set.
add_definitions(-D_POSIX_THREAD_SAFE_FUNCTIONS=200112L)

# The Winsock APIs take 'char *' buffers where POSIX takes 'void *',
# which trips -Wincompatible-pointer-types across the code base. MSVC
# reports the same mismatches as warnings; keep GCC (>= 14 makes them
# errors by default) at warning level too unless the strict option is
# enabled explicitly.
if(NOT FLB_COMPILER_STRICT_POINTER_TYPES)
add_compile_options(-Wno-error=incompatible-pointer-types)
endif()
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Prevent the toolchain from emitting an executable stack on Linux targets,
# which triggers kernel warnings (e.g. "started with executable stack") and
Expand Down Expand Up @@ -570,7 +584,7 @@ endif()

# Harden release binary against security vulnerabilities
if(FLB_SECURITY STREQUAL "On" OR (FLB_SECURITY STREQUAL "ReleaseOnly" AND FLB_RELEASE))
if (NOT MSVC)
if (NOT WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,relro,-z,now")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack")
if(NOT FLB_SMALL)
Expand Down Expand Up @@ -865,8 +879,10 @@ if(FLB_TLS)
option(ENABLE_PROGRAMS OFF)
option(INSTALL_MBEDTLS_HEADERS OFF)

# Link OpenSSL statically on Windows.
if (FLB_SYSTEM_WINDOWS)
# Link OpenSSL statically on MSVC Windows builds only.
# MinGW cross-compiles use dynamic OpenSSL to avoid GNU ld link-order issues
# with static archives that have cascading system library dependencies.
if (FLB_SYSTEM_WINDOWS AND MSVC)
set(OPENSSL_USE_STATIC_LIBS ON)
set(OPENSSL_MSVC_STATIC_RT ON)
endif()
Expand Down Expand Up @@ -1138,7 +1154,9 @@ check_c_source_compiles("
close(sock);
return 0;
}" FLB_HAVE_UNIX_SOCKET)
if(FLB_HAVE_UNIX_SOCKET)
if(FLB_HAVE_UNIX_SOCKET AND NOT FLB_SYSTEM_WINDOWS)
# MinGW headers can satisfy the sys/un.h probe, but the Windows unix
# socket paths are untested; keep feature parity with MSVC builds.
FLB_DEFINITION(FLB_HAVE_UNIX_SOCKET)
endif()

Expand Down Expand Up @@ -1170,7 +1188,10 @@ if(FLB_CONFIG_YAML)
set(LIBYAML_LIBRARY_DIRS "${FLB_LIBYAML_DIR}/lib")
set(LIBYAML_INCLUDEDIR "${FLB_LIBYAML_DIR}/include")
message(STATUS "specified libyaml dir: ${FLB_LIBYAML_DIR}")
if (MSVC)
if (FLB_SYSTEM_WINDOWS)
# FLB_LIBYAML_DIR on Windows carries a static libyaml (the MSVC CI
# uses vcpkg static triplets, MinGW cross-builds a static libyaml),
# so keep <yaml.h> from declaring dllimport symbols.
FLB_DEFINITION(YAML_DECLARE_STATIC)
endif ()
set(FLB_HAVE_LIBYAML 1)
Expand Down Expand Up @@ -1233,7 +1254,9 @@ if (FLB_BENCHMARKS)
endif()

# Build tools/xxd-c
add_subdirectory(tools/xxd-c)
if(NOT CMAKE_CROSSCOMPILING)
add_subdirectory(tools/xxd-c)
endif()

# Static configuration generator (using xxd-c)
if(FLB_STATIC_CONF)
Expand All @@ -1256,13 +1279,29 @@ if(FLB_PROXY_GO)
FLB_DEFINITION(FLB_HAVE_PROXY_GO)
endif()

if("${GNU_HOST}" STREQUAL "" AND CMAKE_CROSSCOMPILING
AND CMAKE_C_COMPILER_ID STREQUAL "GNU")
# Derive the autoconf host triple from the cross compiler so the
# external autotools sub-builds (libbacktrace, jemalloc) configure for
# the target instead of silently building host objects.
get_filename_component(FLB_C_COMPILER_NAME "${CMAKE_C_COMPILER}" NAME)
string(REGEX REPLACE "-gcc(-[0-9.]+)?$" "" GNU_HOST "${FLB_C_COMPILER_NAME}")
if(GNU_HOST STREQUAL FLB_C_COMPILER_NAME)
# Compiler name carries no triple prefix; leave GNU_HOST unset.
set(GNU_HOST "")
endif()
endif()

if("${GNU_HOST}" STREQUAL "")
set(AUTOCONF_HOST_OPT "")
else()
set(AUTOCONF_HOST_OPT "--host=${GNU_HOST}")
endif()

if(CMAKE_GENERATOR MATCHES "Ninja" AND NOT FLB_SYSTEM_WINDOWS)
# The $(MAKE) escape only exists in the Make-family generators; under Ninja
# the external autotools sub-builds always run with plain make on the build
# host, including when cross-compiling for a Windows target.
if(CMAKE_GENERATOR MATCHES "Ninja")
set(EXTERNAL_BUILD_TOOL "make")
else()
set(EXTERNAL_BUILD_TOOL "$(MAKE)")
Expand Down Expand Up @@ -1332,6 +1371,12 @@ if(FLB_REGEX)
endif()
add_subdirectory(${FLB_PATH_LIB_ONIGMO} EXCLUDE_FROM_ALL)
target_include_directories(onigmo-static INTERFACE ${FLB_PATH_ROOT_SOURCE}/${FLB_PATH_LIB_ONIGMO})
if(CMAKE_CROSSCOMPILING AND WIN32)
# Onigmo's configure_file(config.h.cmake config.h) misdetects when cross
# compiling; overwrite it with the prebuilt Windows config it ships.
file(COPY ${FLB_PATH_ROOT_SOURCE}/${FLB_PATH_LIB_ONIGMO}/win32/config.h
DESTINATION ${FLB_PATH_ROOT_SOURCE}/${FLB_PATH_LIB_ONIGMO}/)
endif()
endif()

# tutf8e (UTF8 Encoding)
Expand Down
15 changes: 15 additions & 0 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,21 @@ At time of writing this workflow *does not run any of the Fluent Bit test suite*
- so it only checks that the target branch can be compiled. To run tests, a local
build will be required.

#### Cross-compiling from Linux with MinGW

Fluent Bit can also be cross-compiled for Windows from a Linux host using the
MinGW-w64 UCRT64 toolchain, without a Windows machine or MSVC. The
[`.github/workflows/pr-compile-check.yaml`](.github/workflows/pr-compile-check.yaml)
`pr-compile-mingw-cross` job is the reference recipe: it runs in a Fedora
container, installs the `ucrt64-gcc` cross toolchain, cross-builds a static
libyaml, and then configures with
`-DCMAKE_TOOLCHAIN_FILE=/usr/share/mingw/toolchain-ucrt64.cmake`.

Cross-builds produce `bin/fluent-bit.exe` but cannot run the test suites (the
binaries are Windows executables). Note the toolchain must target UCRT
(`x86_64-w64-mingw32ucrt`); the older MSVCRT-based MinGW toolchains are not
supported.

#### Using Docker for Windows

For Windows users with Hyper-V capable machines the simplest way to build a
Expand Down
64 changes: 37 additions & 27 deletions include/fluent-bit/flb_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <windows.h>
#include <Wincrypt.h> /* flb_io_tls.c */
#include <wincrypt.h> /* flb_io_tls.c */

#include <monkey/mk_core/mk_sleep.h>
#include <fluent-bit/flb_dlfcn_win32.h>
Expand All @@ -56,23 +56,30 @@
/* monkey exposes a broken vsnprintf macro. Undo it */
#undef vsnprintf

/*
* Windows prefer to add an underscore to each POSIX function.
* To suppress compiler warnings, we need these trivial macros.
*/
#define timezone _timezone
#define tzname _tzname
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define timegm _mkgmtime


static inline int getpagesize(void)
{
SYSTEM_INFO info;
GetSystemInfo(&info);
return info.dwPageSize;
}

static inline char* realpath(char *path, char *buf)
{
if (buf != NULL) {
return NULL; /* Read BUGS in realpath(3) */
}
return _fullpath(NULL, path, 0);
}

#ifndef __MINGW32__
#define timezone _timezone
#define tzname _tzname
#define strcasecmp _stricmp
#define strncasecmp _strnicmp

static inline struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
if (gmtime_s(result, timep)) {
Expand All @@ -90,10 +97,6 @@ static inline char *ctime_r(const time_t *timep, char *result)
return strcpy(result, tmp);
}

/*
* We can't just define localtime_r here, since mk_core/mk_utils.c is
* exposing a symbol with the same name inadvertently.
*/
static struct tm *flb_localtime_r(time_t *timep, struct tm *result)
{
if (localtime_s(result, timep)) {
Expand All @@ -103,34 +106,41 @@ static struct tm *flb_localtime_r(time_t *timep, struct tm *result)
}
#define localtime_r flb_localtime_r

static inline int usleep(LONGLONG usec)
{
// Convert into 100ns unit.
return nanosleep(usec * 10);
}
#else /* __MINGW32__ */
/*
* MinGW-w64 headers provide the POSIX functions replaced above, but the
* real unistd.h they ship has no BSD random()/srandom(); map them to
* rand()/srand() like monkey's unistd drop-in does for MSVC.
*/
#define random rand
#define srandom srand
#endif /* !__MINGW32__ */

static inline char* basename(const char *path)
{
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
#ifdef _MSC_VER
static __declspec(thread) char buf[_MAX_PATH];
#else
/* MinGW GCC ignores __declspec(thread); use GCC's own TLS keyword so
* the buffer keeps the thread-safety the MSVC build has. */
static __thread char buf[_MAX_PATH];
#endif

_splitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR,
fname, _MAX_FNAME, ext, _MAX_EXT);

_makepath_s(buf, _MAX_PATH, "", "", fname, ext);
return buf;
}

static inline char* realpath(char *path, char *buf)
{
if (buf != NULL) {
return NULL; /* Read BUGS in realpath(3) */
}
return _fullpath(NULL, path, 0);
}

static inline int usleep(LONGLONG usec)
{
// Convert into 100ns unit.
return nanosleep(usec * 10);
}
#else
#include <netdb.h>
#include <netinet/in.h>
Expand Down
5 changes: 5 additions & 0 deletions include/fluent-bit/flb_coro.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@

#include <stdlib.h>
#include <limits.h>

/* MinGW-w64's winpthreads does not define PTHREAD_STACK_MIN */
#ifndef PTHREAD_STACK_MIN
#define PTHREAD_STACK_MIN 16384
#endif
#include <libco.h>

#ifdef FLB_HAVE_VALGRIND
Expand Down
2 changes: 1 addition & 1 deletion include/fluent-bit/flb_langinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#ifndef FLB_LANGINFO_H
#define FLB_LANGINFO_H

#ifndef _MSC_VER
#ifndef _WIN32
#include <langinfo.h>
#else

Expand Down
3 changes: 2 additions & 1 deletion include/fluent-bit/flb_pthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
#define FLB_PTHREAD_H

#include <fluent-bit/flb_info.h>
#ifdef FLB_SYSTEM_WINDOWS
#if defined(FLB_SYSTEM_WINDOWS) && !defined(__MINGW32__)
#include <monkey/mk_core/external/winpthreads.h>
#else
/* MinGW-w64 ships a real pthread implementation (winpthreads) */
#include <pthread.h>
#endif

Expand Down
3 changes: 2 additions & 1 deletion include/fluent-bit/flb_thread_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@
#define FLB_THREAD_POOL_STOPPED 2

#include <fluent-bit/flb_info.h>
#ifdef FLB_SYSTEM_WINDOWS
#if defined(FLB_SYSTEM_WINDOWS) && !defined(__MINGW32__)
#include <monkey/mk_core/external/winpthreads.h>
#else
/* MinGW-w64 ships a real pthread implementation (winpthreads) */
#include <pthread.h>
#endif

Expand Down
3 changes: 2 additions & 1 deletion include/fluent-bit/flb_thread_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@

#include <fluent-bit/flb_info.h>

#ifdef FLB_SYSTEM_WINDOWS
#if defined(FLB_SYSTEM_WINDOWS) && !defined(__MINGW32__)
#include <monkey/mk_core/external/winpthreads.h>
#else
/* MinGW-w64 ships a real pthread implementation (winpthreads) */
#include <pthread.h>
#endif

Expand Down
2 changes: 2 additions & 0 deletions lib/chunkio/include/chunkio/chunkio_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define strerror_r(errno,buf,len) strerror_s(buf,len,errno)

#ifndef __MINGW32__
typedef SSIZE_T ssize_t;
typedef unsigned mode_t;
#endif

static inline char* dirname(const char *path)
{
Expand Down
2 changes: 1 addition & 1 deletion lib/chunkio/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
)
set(libs
${libs}
Shell32.lib)
shell32)
else()
set(src
${src}
Expand Down
2 changes: 1 addition & 1 deletion lib/chunkio/src/cio_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <chunkio/chunkio_compat.h>

#ifdef _WIN32
#include <Shlobj.h>
#include <shlobj.h>
#endif

/* Check if a path is a directory */
Expand Down
Loading
Loading