cmake 在 Cygwin 上为 ffmpeg 安装 x265 - 与其他编解码器不同的可执行位置

cmake installation of x265 for ffmpeg on Cygwin - executable location different from other codecs

TL;DR(预期与实际)

对于 ffmpeg 的 Cygwin 构建,我正在安装 x265,在我看来,可执行文件最终出现在错误的位置。我将展示一些基本的目录结构,然后我将展示 cmake 安装前后预期和真实的 tree 输出。对于我认为这很重要的目录,我将显示 cmake 安装前后的输出。

我的问题分为两部分。我使用了以下 cmakemake 命令,

# pwd => $HOME/programs/ffmpeg/ffmpeg_sources/x265/build/linux
PATH="$HOME/programs/ffmpeg/bin:$PATH" \
  cmake -G "Unix Makefiles" \
        -DCMAKE_INSTALL_PREFIX="$HOME/programs/ffmpeg/ffmpeg_build" \
        -DENABLE_SHARED=OFF \
        -DCMAKE_EXE_LINKER_FLAGS="-static" 
            ../../source
PATH="$HOME/programs/ffmpeg/bin:$PATH" make -j $(nproc)
make install

结果如下,是我的真实与预期的对比,还有一个更详细、更明确、希望更清晰的文件,其中的信息位于 pastebin.com/86wHrtxR。现在,对于我的两部分问题:

  1. 我如何更改我的 cmake 命令,以便我的 x265.exe 文件在 $HOME/programs/ffmpeg/bin 中结束正确链接,而不是$HOME/programs/ffmpeg/ffmpeg_build/bin?

  2. build/linker/whatever 会为 ffmpeg 构建解决问题吗?

我想知道问题 1 的答案,而不管问题 2 的答案。我以前没有使用 cmake-DVAR=var 标志,我想借此机会学习。

为结果:

双花括号括起来的是{{ expected }}.

双尖括号包围的是<< real >>,即安装完成后存在。

如果期望真正匹配,并且 file/directory 是新的,我用双括号将其括起来,即双圆括号。 (( match ))

如果有些东西不是新的(因此前后相同)我没有标记它。

   me@MACHINE ~/programs/ffmpeg
   $ tree --charset=ascii bin
   bin
   |-- lame.exe
   |-- mp3rtp.exe
   |-- mp3x.exe
   `-- x264.exe
{{ `-- x265.exe                     }} ## Expected, not Exists

   me@MACHINE ~/programs/ffmpeg
   $ tree --charset=ascii \
                   ffmpeg_build
   ffmpeg_build
<< |-- bin                          >> ## Not expected, Exists
<< |   `-- x265.exe                 >> ## Not expected, Exists
   |-- include
   |   |-- fdk-aac
   |   |   |-- aacdecoder_lib.h
   |   |   |-- aacenc_lib.h
   |   |   `-- ... <more .h files>
   |   |-- lame
   |   |   `-- lame.h
   |   |-- x264.h
   |   `-- x264_config.h
(( |   |-- x265.h                   )) ## Expected and Exists
(( |   `-- x265_config.h            )) ## Expected and Exists
   |-- lib
   |   |-- libfdk-aac.a
   |   |-- libfdk-aac.la
   |   |-- libmp3lame.a
   |   |-- libmp3lame.la
(( |   |-- libx265.a                )) ## Expected and Exists
   |   `-- pkgconfig
   |       |-- fdk-aac.pc
   |       `-- x264.pc
(( |       `-- x265.pc              )) ## Expected and Exists
   `-- share
       |-- doc
       |   ... <only lame>
       `-- man
           ... <only lame>

关于构建目录结构的其他可能有用的信息。

me@MACHINE ~/programs/ffmpeg
$ tree --charset=ascii -L 1 .
.
|-- bin
|-- ffmpeg_build
`-- ffmpeg_sources

3 directories, 0 files

对于下一个 ffmpeg_sources 目录,我将显示后面的内容(这既是预期的也是 real/exists)被双括号包围,即双圆括号 (( <after> ))

   me@MACHINE ~/programs/ffmpeg
   $ tree --charset=ascii -L 1 ffmpeg_sources
   ffmpeg_sources
   |-- fdk-aac.zip
   |-- lame-svn
   |-- mstorsjo-fdk-aac-e7d8591
   |-- x264-snapshot-20191217-2245
   |-- x264-snapshot-20191217-2245.tar.bz2
   `-- x264-snapshot-20191218-README.txt
(( `-- x265                         ))

   3 directories, 3 files
(( 4 directories, 3 files ))

现在,了解更多详情


我在做什么

我正在开发 ffmpeg 的 Cygwin 版本(相对于 Windows/mingw 版本)。我正在关注 an older guide by koohiimaster (archived)。该指南说,

[W]e are not cross-compiling for windows; we are compiling for Cygwin.

这份 2014 年指南没有我想要的所有编解码器 - 我想要尽可能完整的构建 - 所以我也一直在参考 this ffmpeg-for-Ubuntu guide (archived),我希望它能保持下去 -迄今为止。它是由 koohiimaster 提到的。

另外,为了检查我是否获得了我想要的所有编解码器,我一直在查看这个 FFmpeg for Windows guide from SuperUser

我将在下面给出我的步骤的基础知识。更多详细信息以及所有输出位于 pastebin.com/suL1nU6Z.

查看构建的目录结构

me@MACHINE ~/programs/ffmpeg
$ cd $HOME/programs/ffmpeg

me@MACHINE ~/programs/ffmpeg
$ tree --charset=ascii -d -L 1
.
|-- bin
|-- ffmpeg_build
`-- ffmpeg_sources

3 directories

正在获取源代码。请注意,我必须 apt-cyg install mercurial,尽管(在我的 Cygwin 根目录中使用我的 Cygwin 设置 GUI/EXE,即 C:\cygwin64\setup-x86_64.exe),我也可以完成 /setup-x86_64.exe install -q -P mercurial.

cd ffmpeg_sources
hg clone https://bitbucket.org/multicoreware/x265

运行 cmakemake 命令

cd x265/build/linux
PATH="$HOME/programs/ffmpeg/bin:$PATH" \
  cmake -G "Unix Makefiles" \
        -DCMAKE_INSTALL_PREFIX="$HOME/programs/ffmpeg/ffmpeg_build" \
        -DENABLE_SHARED=OFF \
        -DCMAKE_EXE_LINKER_FLAGS="-static" \
            ../../source
PATH="$HOME/programs/ffmpeg/bin:$PATH" make -j $(nproc)
make install

让我担心的是 make install 输出的最后一部分(实际上是最后一行)。这是整个输出 - 它不是很长。

make[1]: Entering directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
make[2]: Entering directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
make[2]: Leaving directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
[ 20%] Built target encoder
make[2]: Entering directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
make[2]: Leaving directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
[ 83%] Built target common
make[2]: Entering directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
make[2]: Leaving directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
[ 84%] Built target x265-static
make[2]: Entering directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
make[2]: Leaving directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
[100%] Built target cli
make[1]: Leaving directory '/home/me/programs/ffmpeg/ffmpeg_sources/x265/build/linux'
Install the project...
-- Install configuration: "Release"
-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/lib/libx265.a
-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/include/x265.h
-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/include/x265_config.h
-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/lib/pkgconfig/x265.pc
-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/bin/x265.exe

TL;DR 部分所述,我希望在

看到 x265.exe

home/me/programs/ffmpeg/bin/x265.exe

而不是输出最后一行给出的路径,

/home/me/programs/ffmpeg/ffmpeg_build/bin/x265.exe

这让我特别担心,因为我的说明告诉我运行 ffmpeg 安装命令的第一部分是

PATH="$HOME/programs/ffmpeg/bin:$PATH" \
PKG_CONFIG_PATH="$HOME/programs/ffmpeg/ffmpeg_build/lib/pkgconfig" \
  ./configure \
    --prefix="$HOME/programs/ffmpeg/ffmpeg_build" \
    --extra-cflags="-I$HOME/programs/ffmpeg/ffmpeg_build/include" \
    --extra-ldflags="-L$HOME/programs/ffmpeg/ffmpeg_build/lib" \
    --bindir="$HOME/programs/ffmpeg/bin" \

... and on it goes ...

在我看来,ffmpeg.configure 脚本找不到 x265 可执行文件,因为它不在 bindir.

我将重复之前的两部分问题:

  1. 如何更改我的 cmake 命令,以便我的 x265.exe 文件以 $HOME/programs/ffmpeg/bin 的正确链接结束,而不是 $HOME/programs/ffmpeg/ffmpeg_build/bin?

我在这里寻找的是类似于 make./confiure.

中的 --bindir 标志的东西
  1. build/linker/whatever 会为 ffmpeg 构建解决问题吗?

我想知道问题 1 的答案,而不管问题 2 的答案。我以前没有使用 cmake-DVAR=var 标志,我想借此机会学习。


我看过的地方和我尝试过的东西

我首先从 man 页面和 cmake--help 页面开始。那太可怕了。我希望我能在 CMAKE_INSTALL_PREFIX 的东西周围找到一些有用的东西,但我不确定该怎么做。

我尝试了 grep 遍历 cmake --help-full(在我要搜索的内容之前和之后有 50 行),但被复杂性绊倒了。我以前只使用过基本的 cmake 东西,但我迷路了很多。

即使有了--help,也不知道要不要看help-manualhelp-commandhelp-modulehelp-policyhelp-variable 或其他。

在我看来,在阅读中,"binary directory" 是 "build" 的顶部,而我认为它将是名为 bin 的目录...我不能'告诉创建包的人而不是我试图从命令行 make/build 包使用什么东西。

我查看了似乎是 cmake wiki 的 Useful Variables page (archived), as well as at this thread at cmake.org (archived), which, along with this SO source and this and and this and this SO 来源,似乎建议使用 CMAKE_RUNTIME_OUTPUT_DIRECTORY 变量(因为 EXECUTABLE_OUTPUT-DIRECTORY 变量已被取代通过它)。顺便说一下,我不知道包的创建者和包的消费者应该使用哪些东西——消费者就是我。我试过

PATH="$HOME/programs/ffmpeg/bin:$PATH" \
  cmake -G "Unix Makefiles" \
        -DCMAKE_INSTALL_PREFIX="$HOME/programs/ffmpeg/ffmpeg_build" \
        -DCMAKE_RUNTIME_OUTPUT_DIRECTORY="$HOME/programs/ffmpeg/bin" \
        -DENABLE_SHARED=OFF \
        -DCMAKE_EXE_LINKER_FLAGS="-static" 
            ../../source
PATH="$HOME/

并考虑了五十个左右的其他 -DVAR 变量,但是对于我尝试过的任何变量,我仍然得到相同的结果。我仍然在似乎错误的地方获得了可执行文件。


系统详细信息

$ date && date +'%s'
Tue, May  5, 2020 11:14:40 AM
1588698880
$ uname -a
CYGWIN_NT-10.0 MACHINE 3.1.4(0.340/5/3) 2020-02-19 08:49 x86_64 Cygwin
$ cmake --version
cmake version 3.14.5

CMake suite maintained and supported by Kitware (kitware.com/cmake).
$ bash --version | head -n 1
GNU bash, version 4.4.12(3)-release (x86_64-unknown-cygwin)
$ gcc --version | head -n 1
gcc (GCC) 9.3.0
$ g++ --version | head -n 1
g++ (GCC) 9.3.0
$ make --version | head -n 2
GNU Make 4.3
Built for x86_64-pc-cygwin

在 $HOME/programs/ffmpeg/bin

中有 x286.exe 个文件
    --prefix="$HOME/programs/ffmpeg" \
    --extra-cflags="-I$HOME/programs/ffmpeg/include" \
    --extra-ldflags="-L$HOME/programs/ffmpeg/lib" \

对于 cmake :

-DCMAKE_INSTALL_PREFIX="$HOME/programs/ffmpeg"

与@Philippe 关系密切

@Philippe 的回答让我找到了正确的方向。我对那个答案的评论,有一些变化表明它离我有多近。

That's helpful - with

-DCMAKE_INSTALL_PREFIX="$HOME/programs/ffmpeg"

I went all the way through the make install. Doing so, I ended up quite close. The last part of the make install output was

-- Installing: /home/me/programs/ffmpeg/lib/libx265.a
-- Installing: /home/me/programs/ffmpeg/include/x265.h
-- Installing: /home/me/programs/ffmpeg/include/x265_config.h
-- Installing: /home/me/programs/ffmpeg/lib/pkgconfig/x265.pc
-- Installing: /home/me/programs/ffmpeg/bin/x265.exe

The x265.exe is where I want it, but now the other five files (libx265.a, x265.h, x265_config.h, and x265.pc) are not where it seems that the pattern of other installs would like them, e.g., I would like /home/me/programs/ffmpeg/ffmpeg_build/lib/libx265.a - it seems the eventual ffmpeg build wants them there.

最后一段描述了原始问题的期望输出。换句话说,为了清楚起见,我希望输出的最后几行是

-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/lib/libx265.a
-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/include/x265.h
-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/include/x265_config.h
-- Installing: /home/me/programs/ffmpeg/ffmpeg_build/lib/pkgconfig/x265.pc
-- Installing: /home/me/programs/ffmpeg/bin/x265.exe

答案匹配 'Desired Output'

@Philippe 的回答中的想法组合让我到达了我需要去的地方。首先,需要对 CMakeLists.txt 进行一些小改动。克隆的文件已经设置为允许从 command-line 更改“*.exe”文件的位置(在任何需要的 bin 目录中)。库 (lib) 文件也是如此。而不是 hard-code header (include) 文件的位置,我进行了此更改。

me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ cp CMakeLists.txt CMakeLists.txt.$(date +'%s').bak

me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ cat -n CMakeLists.txt.1588732600.bak | head -n 386 | tail -16   ### BEFORE
   371
   372  # Build options
   373  set(LIB_INSTALL_DIR lib CACHE STRING "Install location of libraries")
   374  set(BIN_INSTALL_DIR bin CACHE STRING "Install location of executables")
   375  set(EXTRA_LIB "" CACHE STRING "Extra libraries to link against")
   376  set(EXTRA_LINK_FLAGS "" CACHE STRING "Extra link flags")
   377  if(EXTRA_LINK_FLAGS)
   378      list(APPEND LINKER_OPTIONS ${EXTRA_LINK_FLAGS})
   379  endif()
   380  if(EXTRA_LIB)
   381      option(LINKED_8BIT  "8bit libx265 is being linked with this library" OFF)
   382      option(LINKED_10BIT "10bit libx265 is being linked with this library" OFF)
   383      option(LINKED_12BIT "12bit libx265 is being linked with this library" OFF)
   384  endif(EXTRA_LIB)
   385  mark_as_advanced(EXTRA_LIB EXTRA_LINK_FLAGS)
   386

me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ vim CMakeLists.txt   ### Making the change

me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ cat -n CMakeLists.txt | head -n 389 | tail -19   ### AFTER
   371
   372  # Build options
   373  set(LIB_INSTALL_DIR lib CACHE STRING "Install location of libraries")
   374  set(BIN_INSTALL_DIR bin CACHE STRING "Install location of executables")
   375  # Start DWB insert 2020-05-05
   376  set(INCLUDE_INSTALL_DIR include CACHE STRING "Install location of headers")
   377  #   End DWB insert 2020-05-05
   378  set(EXTRA_LIB "" CACHE STRING "Extra libraries to link against")
   379  set(EXTRA_LINK_FLAGS "" CACHE STRING "Extra link flags")
   380  if(EXTRA_LINK_FLAGS)
   381      list(APPEND LINKER_OPTIONS ${EXTRA_LINK_FLAGS})
   382  endif()
   383  if(EXTRA_LIB)
   384      option(LINKED_8BIT  "8bit libx265 is being linked with this library" OFF)
   385      option(LINKED_10BIT "10bit libx265 is being linked with this library" OFF)
   386      option(LINKED_12BIT "12bit libx265 is being linked with this library" OFF)
   387  endif(EXTRA_LIB)
   388  mark_as_advanced(EXTRA_LIB EXTRA_LINK_FLAGS)
   389

通过 diff

看到
me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ diff CMakeLists.txt CMakeLists.txt.1588732600.bak
375,377d374
< # Start DWB insert 2020-05-05
< set(INCLUDE_INSTALL_DIR include CACHE STRING "Install location of headers")
< #   End DWB insert 2020-05-05
599,604c596,597

下一个变化:

me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ cat -n CMakeLists.txt.1588732600.bak | head -n 602 | tail -9   ### BEFORE
   594
   595  if(SVTHEVC_FOUND)
   596      install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbApi.h" DESTINATION include)
   597      install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbErrorCodes.h" DESTINATION include)
   598      install(FILES "${SVT_HEVC_LIBRARY}" DESTINATION ${LIB_INSTALL_DIR})
   599  endif()
   600
   601  install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION include)
   602  if((WIN32 AND ENABLE_CLI) OR (WIN32 AND ENABLE_SHARED))

me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ vim CMakeLists.txt   ### Making the change

me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ cat -n CMakeLists.txt | head -n 611 | tail -15   ### AFTER
   597
   598  if(SVTHEVC_FOUND)
   599      # DWB change 2020-05-05, original is next (cmt) line, new is the line after
   600      #install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbApi.h" DESTINATION include)
   601      install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbApi.h" DESTINATION ${INCLUDE_INSTALL_DIR})
   602      # DWB change 2020-05-05, original is next (cmt) line, new is the line after
   603      #install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbErrorCodes.h" DESTINATION include)
   604      install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbErrorCodes.h" DESTINATION ${INCLUDE_INSTALL_DIR})
   605      install(FILES "${SVT_HEVC_LIBRARY}" DESTINATION ${LIB_INSTALL_DIR})
   606  endif()
   607
   608  # DWB change 2020-05-05, original is next (comment) line, new is the line after
   609  #install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION include)
   610  install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION ${INCLUDE_INSTALL_DIR})
   611  if((WIN32 AND ENABLE_CLI) OR (WIN32 AND ENABLE_SHARED))

或者,再次通过 diff 看到(两个更改都已完成),

me@MACHINE ~/programs/ffmpeg/ffmpeg_sources/x265/source
$ diff CMakeLists.txt CMakeLists.txt.1588732600.bak
375,377d374
< # Start DWB insert 2020-05-05
< set(INCLUDE_INSTALL_DIR include CACHE STRING "Install location of headers")
< #   End DWB insert 2020-05-05
599,604c596,597
<     # DWB change 2020-05-05, original is next (cmt) line, new is the line after
<     #install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbApi.h" DESTINATION include)
<     install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbApi.h" DESTINATION ${INCLUDE_INSTALL_DIR})
<     # DWB change 2020-05-05, original is next (cmt) line, new is the line after
<     #install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbErrorCodes.h" DESTINATION include)
<     install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbErrorCodes.h" DESTINATION ${INCLUDE_INSTALL_DIR})
---
>     install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbApi.h" DESTINATION include)
>     install(FILES "${SVT_HEVC_INCLUDE_DIR}/EbErrorCodes.h" DESTINATION include)
608,610c601
< # DWB change 2020-05-05, original is next (comment) line, new is the line after
< #install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION include)
< install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION ${INCLUDE_INSTALL_DIR})
---
> install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION include)

`cmake` 命令和 `make` 命令

让我们进入正确的构建目录然后 运行 cmake

cd $HOME/programs/ffmpeg/ffmpeg_sources/x265/build/linux

PATH="$HOME/programs/ffmpeg/bin:$PATH" \
  cmake -G "Unix Makefiles" \
        -DCMAKE_INSTALL_PREFIX="$HOME/programs/ffmpeg" \
        -DBIN_INSTALL_DIR="bin" \
        -DLIB_INSTALL_DIR="ffmpeg_build/lib" \
        -DINCLUDE_INSTALL_DIR="ffmpeg_build/include" \
        -DENABLE_SHARED=OFF \
        -DCMAKE_EXE_LINKER_FLAGS="-static" \
            ../../source

这给出了一些我们不需要担心的弃用警告。现在,对于 make 部分。

PATH="$HOME/programs/ffmpeg/bin:$PATH" make -j $(nproc)

make install

这导致了预期的结果。 make install 输出的最后几行是

-- Installing: /home/13852/programs/ffmpeg/ffmpeg_build/lib/libx265.a
-- Installing: /home/13852/programs/ffmpeg/ffmpeg_build/include/x265.h
-- Installing: /home/13852/programs/ffmpeg/ffmpeg_build/include/x265_config.h
-- Installing: /home/13852/programs/ffmpeg/ffmpeg_build/lib/pkgconfig/x265.pc
-- Installing: /home/13852/programs/ffmpeg/bin/x265.exe