无法解析的外部符号 __mingw_vsprintf

windows下的ffmpeg是采取mingw平台上编译,本人采用的是msys2,本人需要h264,于是先在msys2里面编译了x264静态库,注意这里是静态库,动态库经过了链接,不会出现下面的问题,然后在ffmpeg里面用下面配置命令生成Makefile。
./configure --toolchain=msvc --arch=x86_64 --disable-debug --enable-gpl --enable-libx264 --extra-cflags=-I/usr/local/x264/include --extra-ldflags=‘-LIBPATH:/usr/local/x264/lib’ --prefix=/home/ffmpeg_x264_static
注意,编译ffmpeg时,–toolchain=msvc表示用微软编译器编译。

结果configure报错,信息如下:
在这里插入图片描述
打开ffbuild/config.log,有下列报错
在这里插入图片描述

符号__mingw_vsprintf找不到,本人很好奇,在x264的代码里面搜索__mingw_vsprintf调用的地方,很明显没有直接搜找到,于是到msys2里面的stdio.h,搜寻此符号,还真找到了,如下图所示
在这里插入图片描述
其实像x264这种跨平台的开源代码,外层调用的是sprintf,然后sprintf由运行时库实现,不同的运行时库,里面的内部函数不一样,本人曾经用clang编译过webrtc,里面的运行时库前缀是另外一套,具体忘记了。

所以若想将ffmpeg configure通过,需要找到__mingw_vsprintf的实现库,读者也可以理解为需要找到mingw的运行时库,为此本人专门写了一个例子,在mingw里面写一个1.c。
在这里插入图片描述
gcc -c 1.c生成目标文件1.o。

然后用vs2017调用这个mysprintf函数,如下所示:
在这里插入图片描述

// mingwruntimetest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

extern "C" void mysprintf();

int main()
{
    
    
	mysprintf();
    std::cout << "Hello World!\n";
	return 0;
}

由于需要符号mysprintf的定义地方,为此需要将在mingw编译的1.o链接进来,链接器配置如下:
在这里插入图片描述

编译,报如下错误:
在这里插入图片描述

此时跟在ffmpeg里面configure报错时的情况一样了,找到符号__mingw_vsprintf定义的文件libmingwex.a,拷贝到工程目录下,然后配置链接,如下所示:
在这里插入图片描述
编译,报如下错误:
在这里插入图片描述
符号___chkstk_ms未能找到,于是再次找到了此符号所在静态库文件libgcc.a,并拷贝到工程目录下,配置工程链接如下:
在这里插入图片描述
再次编译,编译通过。
读者可能有一些疑惑,如何得知__mingw_vsprintf符号在libmingwex.a里面定义,___chkstk_ms在libgcc.a里面定义,读者可以将__mingw_vsprintf在msys2的lib目录下搜索,包含此符号的文件会被搜索出来。

最后说明下:像ffmpeg这样的大型软件,依赖的插件特别多,若插件用静态库编译,则请保持这些静态库和最后的ffmpeg都用同一个编译器编译,免得最后需要各个编译器的运行时库都包含进来,给自己找罪受。

所以最后的解决方法是x264的静态库用vs2017编译,若x264是动态库,则可以直接用mingw编译,不过最终的成果物里面也会多一个x264.dll。

试想下,若ffmpeg本身,以及ffmpeg依赖的各种插件都用静态库编译,则在windows下面,编译其实是在很费劲的事情,本人曾见过一个博主专门写windows下的ffmpeg编译,意外发现ffmpeg编译之73,相当于ffmpeg的编译起码写了73篇博客。

扫描二维码关注公众号,回复: 14985601 查看本文章

linux下的ffmpeg编译相对而言,要简单太多

猜你喜欢

转载自blog.csdn.net/tusong86/article/details/130312420