Fix wchar.h circular include: define types before stdio.h

relibc's wchar.h included <stdio.h> before defining wint_t and
mbstate_t. The circular chain wchar.h → stdio.h → inttypes.h →
wchar.h caused gnulib's wchar.h wrapper (used by m4, bison, etc.)
to see 'unknown type name wint_t' and 'unknown type name mbstate_t'.

Fix: Move stdio.h and time.h from sys_includes (which cbindgen
emits before type definitions) into after_includes, after wchar_t,
wint_t, and mbstate_t are defined. Also define mbstate_t manually
in after_includes with a guard, and exclude it from cbindgen export
to prevent duplicate definitions.
This commit is contained in:
Red Bear OS
2026-06-27 14:22:45 +03:00
parent 047e7c09da
commit d28963d88e
+19 -5
View File
@@ -1,8 +1,4 @@
sys_includes = [
"stdio.h",
"time.h",
"features.h",
]
sys_includes = ["features.h"]
after_includes = """
// int32_t, uint32_t, WCHAR_MIN, WCHAR_MAX
#include <stdint.h>
@@ -25,6 +21,21 @@ after_includes = """
typedef __WINT_TYPE__ wint_t;
#endif // _WINT_T
// Define mbstate_t before headers that may transitively re-include wchar.h.
// The circular chain wchar.h → stdio.h → inttypes.h → wchar.h (and also
// stdlib.h → wchar.h) would otherwise cause wint_t and mbstate_t to be
// undefined in gnulib's wchar.h wrapper, breaking m4, bison, and other
// gnulib-based packages.
#ifndef _RELIBC_MBSTATE_T
#define _RELIBC_MBSTATE_T
typedef struct {} mbstate_t;
#endif
// Now include headers that depend on wchar_t/wint_t/mbstate_t.
// These must come after the type definitions to break circular includes.
#include <stdio.h>
#include <time.h>
// NULL, size_t, must come after wchar_t and wint_t
#define __need_size_t
#define __need_NULL
@@ -38,6 +49,9 @@ style = "Type"
no_includes = true
cpp_compat = true
[export]
exclude = ["mbstate_t"]
[export.rename]
"tm" = "struct tm"