使用Win10 + WSL编译FFmpeg时的依赖库处理

Windows 10的Linux子系统WSL安装过程就不做赘述了,网上资料很多。

之前一直认为WSL只是以类似虚拟机或容器化的方式使得能在Windows上运行原生Linux程序,当然,也在WSL上做过如使用ndk交叉编译Android原生程序、动态库的操作,用起来还是挺方便的。直到最近研究FFmpeg的Windows版编译时才发现(参考自:https://www.bilibili.com/read/cv7058269/),原来WSL还有一个“大杀招”:直接运行Windows执行程序exe,如下图所示:

可以看到,在WSL内直接执行VS 2019的编译器程序cl,也是完全没有问题的,基于这种方法,FFmpeg官网上所说的用cygwin,mingw,msys之类的桥接环境构建Win版FFmpeg的麻烦就不复存在了,而且新版FFmpeg源码(博主用的4.3)的configure也做好了对这种编译方式的支持,参考上面的链接,制定上toolchain=msvc等相关参数,剩下的事和nix系统上构建一样就可以顺利完成了,简单方便!

不过,今天要记录的并不是WSL下编译Win版FFmpeg的问题,而是编译时如何引入其它依赖,如openssl,xml2等以获取更多功能支持,尤其是在Win环境下,这些其它依赖库的位置很有可能是一个很随意的位置,而在WSL环境下处理这种依赖的头文件、库文件搜索路径时是有坑的…

开始讲坑之前,先提一个小坑,就是如何启动Developer PowerShell for VS 2019的64位版本,装好VS2019后,会自动创建出一些命令行环境的快捷方式,而传统cmd的是有32位64位之分的:x86 Native Tools Command Prompt for VS 2019 和 x64 Native Tools Command Prompt for VS 2019,而由于脚本编写需要,又需要使用PowerShell时,就会尴尬的发现MS并没有为我们准备32位版本的快捷方式,于是就得自己动手了,复制一个32位的快捷方式,修改其中命令,在Enter-VsDevShell 3b06b8f6(此值可能不同!) 后增加 -DevCmdArguments ‘-arch=x64 -no_logo’ 即可。

回到正题,当需要给WSL编译的Win版FFmpeg增加依赖时,比如要支持DASH所需的libxml2库时,按照Linux下configure时的参考,以如下方式进行configure:

PKG_CONFIG_PATH=/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig ./configure –toolchain=msvc –arch=x86_64 –enable-x86asm –enable-shared –enable-w32threads –enable-gpl –enable-version3 –enable-nonfree –enable-libxml2 –enable-shared –enable-optimizations –disable-static –disable-doc –disable-static –prefix=winbuild

PKG_CONFIG_PATH为指定libxml2的生成路径,这里博主的是F:\3rdparty\build-win\xml2,换成WSL的映射路径,并指定好pkgconfig的路径就是/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig,然后运行configure,会得到如下的提示:

ERROR: libxml-2.0 not found using pkg-config

If you think configure made a mistake, make sure you are using the latest
version from Git. If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file “ffbuild/config.log” produced by configure as this will help
solve the problem.

检查下ffbuild/config.log,发现

check_func_headers libxml2/libxml/xmlversion.h xmlCheckVersion -I/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../include/libxml2 -L/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../lib -lxml2
test_ld cc -I/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../include/libxml2 -L/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../lib -lxml2
test_cc -I/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../include/libxml2 -libpath:/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../lib
BEGIN ./ffconf.4BK7ymB8/test.c
1 #include
2 #include
3 long check_xmlCheckVersion(void) { return (long) xmlCheckVersion; }
4 int main(void) { int ret = 0;
5 ret |= ((intptr_t)check_xmlCheckVersion) & 0xFFFF;
6 return ret; }
END ./ffconf.4BK7ymB8/test.c
cl.exe -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D_WIN32_WINNT=0x0600 -DPIC -nologo -I/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../include/libxml2 -libpath:/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../lib -c -Fo./ffconf.4BK7ymB8/test.o ./ffconf.4BK7ymB8/test.c
cl : Command line warning D9002 : ignoring unknown option ‘-libpath:/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig/../../lib’
test.c
./ffconf.4BK7ymB8/test.c(1): fatal error C1083: Cannot open include file: ‘libxml2/libxml/xmlversion.h’: No such file or directory
ERROR: libxml-2.0 not found using pkg-config

分析、排查过程就不说了,这便是这篇博文要说的坑,可以看到configure已经根据libxml2的pkgconfig正确获取到了include和lib的路径(这里还有个小坑,就是库文件的名字,根据Linux的习惯-l的是xml2,但是windows编译出来的是libxml2.lib,这里需要处理下,改pkgconfig还是重命名lib文件都可以),但是问题在于WSL里执行Windows的程序cl.exe,传递过去的搜索路径不能按照WSL里linux的路径来,还要按照Windows的F:\3rdparty\build-win…这样来,同时还得把斜杠换成反斜杠,否则在WSL里就变成了转义字符串,这个问题可以参考这里:https://github.com/microsoft/WSL/issues/2371,知道了问题所在就好办了,要不修改configure,加上对WSL这种问题的特殊处理,要不就在额外手动增加正确的搜索路径,这里我选择了后者,不倾向对开源项目本身代码、脚本做侵入式修改,修改后的configure命令行如下:

PKG_CONFIG_PATH=/mnt/f/3rdparty/build-win/xml2/lib/pkgconfig ./configure –toolchain=msvc –arch=x86_64 –enable-x86asm –enable-shared –enable-w32threads –enable-gpl –enable-version3 –enable-nonfree –enable-libxml2 –enable-shared –enable-optimizations –disable-static –disable-doc –disable-static –prefix=winbuild –extra-cflags=”-IE:/CTVITGitLab/ctv_3rdparty/build-win/xml2/include -IF:/3rdparty/build-win/xml2/include/libxml2″ –extra-ldflags=”-libpath:F:/3rdparty/build-win/xml2/lib”

通过–extra-cflags和–extra-ldflags这两个参数,传递符合cl.exe标准的windows头文件、库文件搜索路径进编译链接参数,这样就可以configure通过并顺利make了,虽然看起来会有点不干净,但确实可以解决这个问题。

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。