window下使用Cygwin编译ffmpeg步骤和问题记录

1. 编译环境搭建

  1. 安装Cygwin
    1. 到Cygwin官网下载Cygwin的可执行程序setup-x86_64.exe
    2. 官网地址:https://cygwin.com/install.html
    3. 安装包地址:https://cygwin.com/setup-x86_64.exe
    4. 安装操作很简单,基本是下一步,下一步就可以
    5. 安装过程中,我们需要将必须的包安装上:
    6. gcc、g++、make、cmake、automake、gdb、nasm、yasm、wget、autoconf
    7. 要在选择安装包的界面里选”Full”选项,然后逐个搜索并且勾选上进行安装
  2. 安装apt-cyg工具
    1. 这是一个开源工具,类似Ubuntu系统中的apt,安装它方便后续安装其他软件包
    2. 第一步:wget -c <https://raw.githubusercontent.com/transcode-open/apt-cyg/master/apt-cyg>
    3. 第二步:install apt-cyg /bin
    4. 后续使用:apt-cyg instal xxx 安装软件包,类似apt-get instal xxx
  3. 安装pkg-config工具
    1. 先确认是否安装了pkg-config,命令行输入:pkg-config
    2. 提示没有安装的,输入安装命令:apt-cyg install pkg-config
    3. 这里就是使用apt-cyg工具安装了pkg-config软件包

2. 源代码下载以及编译

编译过程遇到问题不要慌,建议先看编译问题记录里面有没有记录, 毕竟我的遇到过并且解决了,整个流程都跑通了,对于你来说也是可以的。

  1. 编译安装yasm

    1. wget <http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz>
    2. tar zxvf yasm-1.3.0.tar.gz
    3. cd yasm-1.3.0
    4. ./configure
    5. make && sudo make install
  2. 编译安装fdk-aac

    1. wget <https://jaist.dl.sourceforge.net/project/opencore-amr/fdk-aac/fdk-aac-2.0.2.tar.gz>
    2. tar xvf fdk-aac-2.0.2.tar.gz
    3. cd fdk-aac-2.0.2
    4. ./configure
    5. make && sudo make install
  3. 编译安装lame

    1. wget http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
    2. tar -xzf lame-3.99.5.tar.gz
    3. cd lame-3.99.5
    4. ./configure
    5. make && sudo make install
    6. 编译lame的时候出现一些错误,具体看下面的问题1和问题2
  4. 编译安装nasm

    1. wget https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/nasm-2.13.03.tar.gz
    2. tar xvf nasm-2.13.03.tar.gz
    3. cd nasm-2.13.03
    4. ./configure
    5. make && sudo make install
    6. 编译nasm的时候出现一些错误,具体看下面的问题3
  5. 编译安装x264

    1. wget http://mirror.yandex.ru/mirrors/ftp.videolan.org/x264/snapshots/last_x264.tar.bz2
    2. bunzip2 last_x264.tar.bz2
    3. tar -vxf last_x264.tar
    4. cd last_x264
    5. ./configure --enable-static --enable-shared --disable-asm --disable-avs
    6. make && sudo make install
    7. 如果下载连接无效了,可以自己到http://mirror.yandex.ru/mirrors/ftp.videolan.org/x264/snapshots/下载最新版本
  6. 编译安装ffmpeg

    1. wget -c https://ffmpeg.org/releases/ffmpeg-6.0.1.tar.bz2
    2. bunzip2 ffmpeg-6.0.1.tar.bz2
    3. cd ffmpeg-6.0.1
    4. ./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-small --arch=x86_64 --enable-nonfree --enable-libfdk-aac --enable-libx264 --enable-filter=delogo --enable-debug --disable-optimizations --enable-shared
    5. make && sudo make install
    6. 编译ffmpeg过程会遇到了一些奇奇怪怪的问题,都总结到了下面问题列表了。
    7. 编译了4.x,5.x,6.x几个版本,最后编译成功了6.0.1,看来不同版本还是有些差异的。

3. 编译问题记录

1.问题1:error: cannot guess build type; you must sepcify one

编译lame的时候出现错误:
执行./congfigure的时候出现error: cannot guess build type; you must sepcify one

问题1-解决方法

    1. 安装automake。通过which automake来确认automake是否已经安装。如果没有安装,可以通使用 apt-cyg install automake进行安装,也可以重新运行Cygwin安装程序选择automake进行安装。
    2. 确认automake当前版本。执行automake --version获取当前automake的版本号。
    3. 将lame目录下的config.guess文件替换为/usr/share/automake-version下的config.guess 文件。

问题2:error: ‘_O_BINARY’ undeclared

编译lame的时候出现错误:
lametime.c:139:25: error: ‘_O_BINARY’ undeclared (first use in this function); did you mean ‘O_BINARY’?
  139 |     setmode(fileno(fp), _O_BINARY);

问题2-解决方法

    1. vi frontend/lametime.c  //vi进入编辑lametime.c这个文件
    2. 找到139行将 _O_BINARY 改为 O_BINARY
    3. 保存退出,重新make && make install 即可成功

问题3:error: ‘pure’ attribute on function returning ‘void’

编译nasm的时候出现错误:
In file included from ./include/nasm.h:46,
                 from asm/nasm.c:47:
./include/nasmlib.h:194:1: error: ‘pure’ attribute on function returning ‘void’ [-Werror=attributes]
  194 | void pure_func seg_init(void);
      | ^~~~
cc1: some warnings being treated as errors
make: *** [Makefile:75: asm/nasm.o] Error 1

问题3-解决方法

    1. vi ./include/nasmlib.h  //vi进入编辑
    2. //void pure_func seg_init(void); //注释掉这行
    3. 保存退出,重新make && make install 即可成功

问题4:ERROR: libfdk_aac not found

$ ./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-small --arch=x86_64 --enable-nonfree --enable-libfdk-aac --enable-libx264 --enable-filter=delogo --enable-debug --disable-optimizations --enable-shared
ERROR: libfdk_aac not found

问题4-解决方法

//步骤1:可以命令行使用pkg-config --static --exists --print-errors fdk-aac 判断pkg-config是否可以找到fdk-aac,没有报错说明成功

//解决方法1:Cygwin命令行添加PKG_CONFIG_PATH配置,配置了还是不行,还是提示找不到ERROR: libfdk_aac not found,如下:
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

//正常情况下方法1是可以解决的,折腾了半天,发现我的电脑安装了msys2系统并且在window环境变量配置了path,所以执行pkg-config的时候去查找了msys2系统下的pkgconfig文件

//然后我去掉了msys2系统在window环境变量path配置,执行pkg-config的时候提示找不到,也间接验证了查找的是这个msys2的pkg-config。然后重新运行Cygwin安装程序setup-x86_64.exe重新安装了一下pkgconfig。

//最后我同样在window环境变量配置了PKG_CONFIG_PATH变量,然后执行pkg-config --static --exists --print-errors fdk-aac没有报错,同时执行pkg-config --list-all成功列出了fdk-aac和x264,表示pkgconfig总算配置成功了。

问题5:ERROR: x264 not found using pkg-config

ERROR: x264 not found using pkg-config

问题5-解决方法

//方法1:Cygwin命令行添加PKG_CONFIG_PATH配置
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

//方法2:同样最好也在window环境变量配置PKG_CONFIG_PATH

问题6:error: implicit declaration of function ‘utf8towchar’

libavdevice/gdigrab.c: In function ‘gdigrab_read_header’:
libavdevice/gdigrab.c:252:12: error: implicit declaration of function ‘utf8towchar’ [-Werror=implicit-function-declaration]
  252 |         if(utf8towchar(name, &name_w)) {

问题6-解决方法

//修改,将 #ifdef _WIN32 修改为 #if defined(_WIN32) || defined(__CYGWIN__)
libavutil/wchar_filename.h
  #if defined(_WIN32) || defined(__CYGWIN__)
  #include <windows.h>
  #include "mem.h"

问题7:Error: operand type mismatch for `shr’

/tmp/cc3YzhYO.s: Assembler messages:
/tmp/cc3YzhYO.s:131: Error: operand type mismatch for `shr'
/tmp/cc3YzhYO.s:216: Error: operand type mismatch for `shr'
/tmp/cc3YzhYO.s:288: Error: operand type mismatch for `shr'
make: *** [ffbuild/common.mak:78: libavformat/shortendec.o] Error 1

问题7-解决方法

方法1:旧版本ffmpeg可能有这个问题,5.0.1版本的有,换为6.0.1版本没有这个问题
方法2就是在新版本的ffmpeg里拷贝一个mathops.h头文件内容过来,自行替换修复MULL、NEG_SSR32、NEG_USR32方法
  可以参考这个文章:https://blog.csdn.net/qq_47733361/article/details/132901423

问题8:error: implicit declaration of function ‘wcslen’

./libavutil/wchar_filename.h: In function ‘add_extended_prefix’:
./libavutil/wchar_filename.h:198:43: error: implicit declaration of function ‘wcslen’ [-Werror=implicit-function-declaration]
  198 |     const size_t len                    = wcslen(path_w);
      |                                           ^~~~~~
./libavutil/wchar_filename.h:215:9: error: implicit declaration of function ‘wcscpy’ [-Werror=implicit-function-declaration]
  215 |         wcscpy(temp_w, unc_prefix);
      |         ^~~~~~
./libavutil/wchar_filename.h:216:9: error: implicit declaration of function ‘wcscat’ [-Werror=implicit-function-declaration]
  216 |         wcscat(temp_w, path_w + 2);

问题8-解决方法

//同样是修改wchar_filename.h头文件,添加 #include <wchar.h>头文件
libavutil/wchar_filename.h
  #if defined(_WIN32) || defined(__CYGWIN__)  //问题5的解决方法
  #define WIN32_LEAN_AND_MEAN
  #include <wchar.h>  //新增<wchar.h>头文件
  #include <windows.h>
  #include "mem.h"

问题9:编译成功后window窗口执行ffmpeg提示找不到dll动态库

//编译成功后,ffmpeg产物在/usr/local/ffmpeg下,其bin目录下有dll动态库和ffmpeg可执行文件

//当直接双击执行ffmpeg或者在bin目录下开个cmd窗口执行ffmpeg的时候,提示找不到各种dll动态库,包括cygwin1.dll、cygfdk-aac-1.dll、cyggcc_s-seh-1.dll、libx264-164.dll。

问题9-解决方法

//这些dll库在/usr/local/bin或者/bin目录下都有,自己找一下拷贝一份到ffmpeg.exe同级目录下即可。

//如果需要在任何地方都可以执行ffmpeg.exe,可以将ffmpeg.exe所在目录配置到window环境变量path里面。
libx264-164.dll。

参考连接

  1. https://www.cnblogs.com/renhui/p/10331924.html
  2. https://blog.csdn.net/yan822/article/details/90763376