From cef604a26a2dce90ca65f4a13a68a8e7598b7e00 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sat, 27 Jun 2026 17:52:29 +0300 Subject: [PATCH] cgen: include stdio for GCC MinGW prelude (#27577) --- vlib/v/gen/c/cheaders.v | 6 ++++++ vlib/v/gen/c/cheaders_manual_stdlib_decls_test.v | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index 962cdbd3e..9ebcf85c2 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -429,6 +429,12 @@ extern struct __sFstub __stderr[]; #define stdout ((struct __sFILE *)__stdout) #define stderr ((struct __sFILE *)__stderr) #endif +#elif (defined(__MINGW32__) || defined(__MINGW64__)) && defined(__V_GCC__) +// mingw-w64 stdio.h provides fprintf/vfprintf as static inline overrides +// when __USE_MINGW_ANSI_STDIO is enabled, so use the system declarations +// instead of the manual formatted-stdio prototypes below. +#include +#include #elif defined(__MINGW32__) || defined(__MINGW64__) || (defined(__clang__) && (defined(_WIN32) || defined(_WIN64))) typedef struct _iobuf FILE; FILE* __cdecl __acrt_iob_func(unsigned index); diff --git a/vlib/v/gen/c/cheaders_manual_stdlib_decls_test.v b/vlib/v/gen/c/cheaders_manual_stdlib_decls_test.v index 912fd9e8b..4bb3f6eb6 100644 --- a/vlib/v/gen/c/cheaders_manual_stdlib_decls_test.v +++ b/vlib/v/gen/c/cheaders_manual_stdlib_decls_test.v @@ -47,6 +47,7 @@ fn test_default_c_prelude_uses_manual_stdio_stdlib_string_and_stdarg_decls() { assert generated_c.contains('V_CRT_LINKAGE void V_CRT_CALL _aligned_free(void *memory);'), generated_c assert generated_c.contains('V_CRT_LINKAGE unsigned short * V_CRT_CALL _wgetenv(const unsigned short *varname);'), generated_c assert generated_c.contains('V_CRT_LINKAGE int V_CRT_CALL _wputenv(const unsigned short *envstring);'), generated_c + assert generated_c.contains('#elif (defined(__MINGW32__) || defined(__MINGW64__)) && defined(__V_GCC__)\n// mingw-w64 stdio.h provides fprintf/vfprintf as static inline overrides\n// when __USE_MINGW_ANSI_STDIO is enabled, so use the system declarations\n// instead of the manual formatted-stdio prototypes below.\n#include \n#include \n#elif defined(__MINGW32__) || defined(__MINGW64__) || (defined(__clang__) && (defined(_WIN32) || defined(_WIN64)))'), generated_c assert generated_c.contains('#elif defined(__MINGW32__) || defined(__MINGW64__) || (defined(__clang__) && (defined(_WIN32) || defined(_WIN64)))\ntypedef struct _iobuf FILE;\nFILE* __cdecl __acrt_iob_func(unsigned index);\n#define stdin (__acrt_iob_func(0))\n#define stdout (__acrt_iob_func(1))\n#define stderr (__acrt_iob_func(2))'), generated_c assert generated_c.contains('#elif defined(__TINYC__) && (defined(_WIN32) || defined(_WIN64))'), generated_c assert generated_c.contains('#ifndef _FILE_DEFINED\nstruct _iobuf {\n\tchar *_ptr;\n\tint _cnt;\n\tchar *_base;\n\tint _flag;\n\tint _file;\n\tint _charbuf;\n\tint _bufsiz;\n\tchar *_tmpfname;\n};\ntypedef struct _iobuf FILE;\n#define _FILE_DEFINED'), generated_c @@ -59,7 +60,7 @@ fn test_default_c_prelude_uses_manual_stdio_stdlib_string_and_stdarg_decls() { assert generated_c.contains('#elif defined(__DragonFly__)\ntypedef struct __sFILE FILE;\nextern FILE* __stdinp;\nextern FILE* __stdoutp;\nextern FILE* __stderrp;\n#define stdin __stdinp\n#define stdout __stdoutp\n#define stderr __stderrp'), generated_c assert generated_c.contains('#elif defined(__NetBSD__)\n// NetBSD exposes stdin/stdout/stderr as macros into a single `__sF[3]`\n// array whose element size (sizeof(FILE)) depends on the platform and libc\n// version, so we cannot forward-declare them. The FreeBSD-style\n// `__stdinp/__stdoutp/__stderrp` symbols also do not exist on NetBSD (see\n// vlang/v#27190). Defer to the system headers for FILE, the stdio streams,\n// and the libc prototypes that would otherwise clash with the\n// `__restrict`-qualified declarations in NetBSD libc.\n#include \n#include \n#include \n#include '), generated_c assert generated_c.contains('#elif defined(__TINYC__) && (defined(__FreeBSD__) || defined(__OpenBSD__))\n// TinyCC reports a hard redefinition error if system OpenSSL pulls in\n// after V has provided its own va_start macro. Include it first,\n// but keep V manual FILE declarations on these BSD libc variants.\n#include \n#if defined(__FreeBSD__)\ntypedef struct __sFILE FILE;\nextern FILE* __stdinp;\nextern FILE* __stdoutp;\nextern FILE* __stderrp;\n#define stdin __stdinp\n#define stdout __stdoutp\n#define stderr __stderrp'), generated_c - assert generated_c.contains('#else\ntypedef struct __sFILE FILE;\n#ifndef _STDFILES_DECLARED\n\t#define _STDFILES_DECLARED\nstruct __sFstub { long _stub; };\nextern struct __sFstub __stdin[];\nextern struct __sFstub __stdout[];\nextern struct __sFstub __stderr[];\n#endif\n#define stdin ((struct __sFILE *)__stdin)\n#define stdout ((struct __sFILE *)__stdout)\n#define stderr ((struct __sFILE *)__stderr)\n#endif\n#elif defined(__MINGW32__)'), generated_c + assert generated_c.contains('#else\ntypedef struct __sFILE FILE;\n#ifndef _STDFILES_DECLARED\n\t#define _STDFILES_DECLARED\nstruct __sFstub { long _stub; };\nextern struct __sFstub __stdin[];\nextern struct __sFstub __stdout[];\nextern struct __sFstub __stderr[];\n#endif\n#define stdin ((struct __sFILE *)__stdin)\n#define stdout ((struct __sFILE *)__stdout)\n#define stderr ((struct __sFILE *)__stderr)\n#endif\n#elif (defined(__MINGW32__) || defined(__MINGW64__)) && defined(__V_GCC__)'), generated_c assert generated_c.contains('#if (!defined(_MSC_VER) || defined(__clang__)) && !defined(__cplusplus) && !defined(__NetBSD__)'), generated_c assert generated_c.contains('#elif defined(__OpenBSD__)\ntypedef struct __sFILE FILE;\n#ifndef _STDFILES_DECLARED\n\t#define _STDFILES_DECLARED\nstruct __sFstub { long _stub; };\nextern struct __sFstub __stdin[];\nextern struct __sFstub __stdout[];\nextern struct __sFstub __stderr[];\n#endif\n#define stdin ((struct __sFILE *)__stdin)\n#define stdout ((struct __sFILE *)__stdout)\n#define stderr ((struct __sFILE *)__stderr)'), generated_c assert generated_c.contains('#elif defined(__linux__) && !defined(__GLIBC__) && !defined(__GNU_LIBRARY__) && !defined(__BIONIC__) && !defined(__UCLIBC__)\ntypedef struct _IO_FILE FILE;\n// musl exposes the stdio streams as `FILE *const`, so match that to stay\n// compatible with later includes from headers like miniz.h.\nextern FILE* const stdin;\nextern FILE* const stdout;\nextern FILE* const stderr'), generated_c -- 2.39.5