首先你得准备好msys2环境,安装好对应的工具链,msys2他本身提供了三个环境,但是这次我们是用msvc去编译用哪个环境都无所谓,但是你在哪个环境装的工具链就进入到哪个环境,msys2是环境隔离的。然后下载好对应的ffmpeg源码,x264源码,x265源码,fdk-aac源码,openssl源码,openssl我是用的1.1.1的。还有最重要要安装vs
首先我们先进入到msys2环境里,但是要通过vs命令行工具打开命令行,因为这样才能访问 cl.exe 这个vc的编译器,以及一些编译套件比如 nmake 。也可以不用从vs命令行工具进入,只要把vs这些对应的工具配置到环境变量里也行,这里我们选择x64的命令工具进入,因为我们要编译 ffmpeg 64位库,如果要编译32位的就选择x86。
然后我们进入到安装好的msys2文件夹下面,找到一个msys2_shell.cmd的文件执行 msys2_shell.cmd -help 命令查看他的帮助文档,然后我们以 msys2_shell.cmd -defterm -full-path -no-start -here -mingw64 进入到msys2的环境里,这话代表的意思是 以默认终端,不打开新的新的命令行窗口(就是msys2提供的终端),然后继承当前环境的系统变量进入到当前目录,在mingw64的环境里 这里我说一句不是非得进入到mingw64的环境里,因为我们是用msvc的编译器去编译,用msys2是为了可以用他提供的linux的工具套件,以帮助我们编译ffmpeg,你的工具安装到哪个环境进入到哪个环境都行,如果我们是用mingw去编译ffmpeg的话,就要选择对应的环境去编译了,比如说你用clang去编译ffmpeg,就进入到clang的环境里,就像msys2为不同的环境提供了不同的类gcc的套件
然后我们就原地进入到了msys2环境里,然后我们验证一下环境变量有没有继承过来输入 cl.exe 我们就看到了msvc这个c++的编译器已经正常集成过来了。
接下来我们编译 x264 进入x264源码目录,输入 configure -help 查看帮助,选择对应的选项,这里x264编译的时候他会默认选择 CC 这个编译器,这个编译器就是mingw64的编译器,但是我们要编译MSVC的,编写一个脚本,最重要的是 CC=cl 因为x264的编译选项没有提供CC的选项,这里我们就创建一个临时变量让CC=MSVC这个编译器,然后正常 make&&make install
OPTIONS="--enable-static --disable-cli"
BUILD_DIR="/home/X264msvc64"
CC=cl ./configure $OPTIONS --prefix=$BUILD_DIR/
然后我们编译 x265 ,x265 是个cmake工程并且提供了各种环境编译的脚本,就更简单了,进入build目录,可以看到各种环境的脚本,我们现在实在msys2上编译msvc版本的x265,我们进入到 msys-cl 这个目录可以看到两个sh脚本一个是编译32位的,一个是64位,其实两个脚本没差别,只不过64的脚本会检查你的 cl.exe 是不是64的,如果不是会直接退出,这里会生成 nmake 然后用nmake工具去编译安装就行了,具体我已经写了注释。
#!/bin/sh
# This is to generate visual studio builds with required environment variables set in this shell, useful for ffmpeg integration
# Run this from within an MSYS bash shell
INSTALL_DIR="/home/x265Msvc64"
if cl; then
echo
else
echo "please launch msys from 'visual studio command prompt'"
exit 1
fi
#选择使用生成nmake
#/W4 显示级别1、级别2和3级警告,并显示默认情况下不关闭的所有级别 4 (信息) 警告
#启用 /GR 时,编译器定义 _CPPRTTI 预处理器宏。 默认情况下, /GR 为打开状态。 /GR- 禁用运行时类型信息
#EH指定编译器生成的异常处理模型支持
#其余具体去查看微软文档
cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR -DCMAKE_CXX_FLAGS="-DWIN32 -D_WINDOWS -W4 -GR -EHsc" -DCMAKE_C_FLAGS="-DWIN32 -D_WINDOWS -W4" ../../source
if [ -e Makefile ]; then
nmake
fi
然后我们编译 fdk-aac 进入到源码目录,因为fdk-aac2.0.2只给了automake生成makefile的部分文件,而没有直接给出可用的configue,所以我们需要生成 configure ,不过源码码录下面有个 sh 文件 ./autogen.sh ,执行一下就会生成更新 configure,然后我们 configure -h 查看帮助,除了上面的编译选项,它还告诉我们可以覆盖这些变量做对应处理,首先CC肯定是他的C编译器了,他的注释写的很清楚了,CFLAGS是他的编译选项,CXX是C++编译器,等等,我们可以覆盖这些变量对生成的makefile做修改。
OPTIONS="CC=cl CXX=cl --enable-static"
BUILD_DIR="/home/fdk-aacMsvc64"
./configure $OPTIONS --prefix=$BUILD_DIR/
这里给出对应的sh脚本,编译安装就生成对应的库文件了
首先我们先查看openssl文档,进入openssl源码目录,打开 INSTALL 文件,里面描述了在各个环境编译要注意的事项,这里我们编译 win 上的openssl,步骤很简单,用perl生成对应架构的nmake(makefile)文件,然后用nmake去编译。
但是这里我试了很多次都不成功,后来我查到是不同平台上的perl的路径,换行符那些不一样,要编译win版的openssl要安装win上面的perl,具体查看openssl文档 NOTES.PERL ,这里叫我们去安装ActiveState Perl,这样我们就能正常生成makefile了,然后执行 nmake test去测试,然后安装
#看你是什么平台,如果是IA64平台选择VC-WIN64I
#如果构建vc 使用ActiveState Perl,msys的perl不行
#具体看openssl文档
perl Configure VC-WIN64A --prefix=/home/local/opensslMsvc64
nmake && nmake test && nmake install
对应openssl脚本文件
我们的前置工作终于做好了,终于可以编译ffmpeg了,我们进入到ffmpeg源码目录,查看configure -h帮助选项,这次ffmpeg提供了对应的编译器选项,这下更简单了
X264_INSTALL="/home/X264msvc64"
X265_INSTALL="/home/x265Msvc64"
aac_INSTALL="/home/fdk-aacMsvc64"
openssl_INSTALL="/home/opensslMsvc64"
X264_LIB=$X264_INSTALL/lib
X265_LIB=$X265_INSTALL/lib
aac_LIB=$aac_INSTALL/lib
openssl_LIB=$openssl_INSTALL/lib
#PKG_CONFIG_PATH是一个环境变量,它指定pkg-config将在其中搜索其.pc文件的其他路径,扩展pkg-config的默认搜索路径
export PKG_CONFIG_PATH=$X264_LIB/pkgconfig:$X265_LIB/pkgconfig:$aac_LIB/pkgconfig:$openssl_LIB/pkgconfig:$PKG_CONFIG_PATH
echo $PKG_CONFIG_PATH
BUILD_DIR="/home/ffmpeg4.x/ffmpegInstall"
OPTIONS="--enable-shared
--enable-libx264
--enable-libx265
--enable-libfdk-aac
--enable-gpl
--toolchain=msvc
--enable-nonfree
--cc=cl
--cxx=cl
--enable-openssl
"
# --disable-programs 不构建命令行程序
# --enable-gpl //链接x264 x265需要同意这个协议
# --enable-nonfree //链接fdk-aac需要同意这个协议
./configure $OPTIONS --prefix=$BUILD_DIR
这里给出脚本文件,openssl我是在win上编译的所以没有生成对应的.pc文件,这里手动编写一下,下面给出配置文件,替换成你安装openssl的路径。
prefix=D:/softwares/msys2/home/opensslMsvc64
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: GNU openssl
Description: openssl
#Requires:
Version: 1.1.1n
Libs: -L${libdir} -llibssl -llibcrypto
Cflags: -I${includedir}
这里还有个坑,如果你x264想静态链接到ffmpeg,找到ffmpeg源码目录在 libavcodec 文件夹下 libx264.c 文件修改代码,把这一行注释掉,不然ffmpeg默认是动态链接的,会报找不到对应函数的错误,如果你是动态链接x264,则不需要修改代码,正常编译就行。至于x265,我现在只能动态链接到ffmepg,静态链接会报找不到函数的问题,把libx265.c文件下面对应的 X265_API_IMPORTS 这个宏注释掉也不行,具体我现在也不知道怎么解决,希望大佬们有解决方法
这里还有一个问题,如果你要生成ffmpeg命令行工具,configure会在目录下面生成一个 config.h 的文件,打开这个文件会有msvc这个编译器生成的中文,这里原本是这样的,但是ffmpeg用到了这个宏,这里会乱码,会报语法错误,所以在make之前先手动把这一行替换为英文 “Microsoft®C/C++” ,内容随便,不产生乱码就行。
#define "用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.27.29111 版"