MinGW GCC生成VS可用.lib时配置异常及函数定义疑问
我在WSL中使用x86_64-w64-mingw32-gcc(版本为x86_64-w64-mingw32-gcc (GCC) 10-win32 20220113),想要生成能在Windows的MSVC中使用的.lib文件。当库文件中使用printf函数时,MSVC链接失败,调试后发现除printf外,还引入了MinGW专属函数__imp___acrt_iob_func和__mingw_vfprintf。
根据文档及_mingw.h的说明,用户应通过设置__MINGW_FEATURES__=0来禁用MinGW专属扩展特性,不应直接修改__USE_MINGW_ANSI_STDIO为0。但设置__MINGW_FEATURES__=0并未生效,甚至添加编译参数-std=c11也无法解决问题。目前可行的解决方案是在编译时传入参数-D__USE_MINGW_ANSI_STDIO=0(在库内部设置该值无效),具体编译命令如下:
x86_64-w64-mingw32-gcc -D__USE_MINGW_ANSI_STDIO=0 -c File.c -o File.obj x86_64-w64-mingw32-ar rcs File.lib File.obj
疑问解答
1. __MINGW_FEATURES__设置无效是Bug还是预期行为?
这属于预期行为。在MinGW-w64的实现逻辑里,__MINGW_FEATURES__是用于控制宽泛的MinGW扩展集合的宏,但它并不直接覆盖__USE_MINGW_ANSI_STDIO的默认值。__USE_MINGW_ANSI_STDIO是单独管控stdio函数是否使用MinGW专属实现的开关,优先级高于__MINGW_FEATURES__。在你使用的GCC 10版本MinGW-w64中,__USE_MINGW_ANSI_STDIO默认被定义为1,即便设置__MINGW_FEATURES__=0,也不会自动将其置为0,因此必须显式传递-D__USE_MINGW_ANSI_STDIO=0来强制切换到MSVC兼容的stdio实现。
2. __imp___acrt_iob_func和__mingw_vfprintf的定义位置在哪里?
__imp___acrt_iob_func:这是MSVC CRT的导入符号,定义在MSVC的ucrtbase.dll中,MinGW通过导入库libucrtbase.a或ucrt.lib来引用它,主要用于获取标准I/O流(如stdin、stdout)的结构体地址。__mingw_vfprintf:这是MinGW专属的vfprintf实现,定义在MinGW的CRT库libmingwex.a中,是MinGW为提供ANSI标准兼容的stdio功能开发的替代函数,和MSVC的vfprintf实现不兼容。
内容的提问来源于stack exchange,提问作者A.M

