【问题标题】:CMake configuration for ffmpeg in C++ projectC++项目中ffmpeg的CMake配置
【发布时间】:2018-11-18 11:28:50
【问题描述】:

我已经使用 Homebrew 安装了 ffmpeg(第 4 版),我正在尝试在 C++ 项目中使用各种 ffmpeg 库,但在链接过程中出现多个错误。

Undefined symbols for architecture x86_64:
  "_av_free", referenced from:
      _main in main.cpp.o
  "_av_packet_alloc", referenced from:
      _main in main.cpp.o
  "_av_parser_init", referenced from:
And so on ... 

我已包含以下库

extern "C" {
    #include <libavutil/frame.h>
    #include <libavutil/mem.h>
    #include <libavcodec/avcodec.h>
}

但是,这仍然行不通。我想我可能遗漏了我的CMakeLists.txt 文件中的某些内容,目前看起来是这样的:

cmake_minimum_required(VERSION 2.6)
project(decode_encode)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "-D__STDC_CONSTANT_MACROS")

add_executable(decode_encode main.cpp)

我很可能需要指定额外的链接标志,但有没有更好的方法来处理 CMakeLists.txt 文件中的链接部分?

【问题讨论】:

标签: c++ ffmpeg cmake


【解决方案1】:

如评论中所述,PkgConfig 可用于更方便地链接库。使用 CMake 3.17,这将链接所有 libav 库:

cmake_minimum_required(VERSION 3.17)

project(Foo)

find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET
    libavdevice
    libavfilter
    libavformat
    libavcodec
    libswresample
    libswscale
    libavutil
)

add_executable(${PROJECT_NAME}
    main.cpp
)

target_link_libraries(${PROJECT_NAME}
    PkgConfig::LIBAV
)

【讨论】:

    【解决方案2】:

    好的,我找到了解决方案。看来 FFmpeg 不支持 CMake 中的 find_package 。我不得不按照here 的建议手动链接库。

    最终的 CMakeLists.txt 看起来像这样

    cmake_minimum_required(VERSION 2.6)
    project(decode_encode)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_FLAGS "-D__STDC_CONSTANT_MACROS")
    
    find_path(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)
    find_library(AVCODEC_LIBRARY avcodec)
    
    find_path(AVFORMAT_INCLUDE_DIR libavformat/avformat.h)
    find_library(AVFORMAT_LIBRARY avformat)
    
    find_path(AVUTIL_INCLUDE_DIR libavutil/avutil.h)
    find_library(AVUTIL_LIBRARY avutil)
    
    find_path(AVDEVICE_INCLUDE_DIR libavdevice/avdevice.h)
    find_library(AVDEVICE_LIBRARY avdevice)
    
    add_executable(decode_encode main.cpp)
    target_include_directories(decode_encode PRIVATE ${AVCODEC_INCLUDE_DIR} ${AVFORMAT_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR} ${AVDEVICE_INCLUDE_DIR})
    target_link_libraries(decode_encode PRIVATE ${AVCODEC_LIBRARY} ${AVFORMAT_LIBRARY} ${AVUTIL_LIBRARY} ${AVDEVICE_LIBRARY})
    

    不过,我确信有更好的方法来聚合所有库。

    【讨论】:

    • 我的 cmake 找不到 avcodec 也找不到其他库。你知道发生了什么吗?
    • 可能你需要给它一个提示。到目前为止,最简单的方法是对路径进行硬编码。在 Linux 上,您可以使用 find / -name avcodec.h 找到文件的位置。在 Ubuntu 上,它似乎安装在 /usr/include/x86_64-linux-gnu/libavcodec/avcodec.h
    【解决方案3】:

    您需要告诉CMAKE 在您的系统中哪里可以找到ffmpeg 的标头和库。 您可以使用find_package(ffmpeg 为您查看系统,然后使用它定义的 CMAKE 变量来正确设置编译器的头文件和链接器的库。

    • 标头:include_directories(${FFMPEG_INCLUDE_DIRS})
    • 库:target_link_libraries(decode_encode ${FFMPEG_LIBRARIES})

    类似以下的内容应该可以达到目的。

     cmake_minimum_required(VERSION 2.6)
    project(decode_encode)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_FLAGS "-D__STDC_CONSTANT_MACROS")
    
    
    find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL AVDEVICE REQUIRED) #add here the list of ffmpeg components required
    
    if(FFMPEG_FOUND)
    #  FFMPEG_INCLUDE_DIRS  - Include directory necessary for using the required components headers.
    #  FFMPEG_LIBRARIES     - Link these to use the required ffmpeg components.
    #  FFMPEG_DEFINITIONS   - Compiler switches required for using the required ffmpeg components.
        message("FFMPEG_INCLUDE_DIRS = ${FFMPEG_INCLUDE_DIRS} ")
        message("FFMPEG_LIBRARIES = ${FFMPEG_LIBRARIES} ")
        message("FFMPEG_DEFINITIONS = ${FFMPEG_DEFINITIONS} ")
    
        include_directories(${FFMPEG_INCLUDE_DIRS})
    
    endif()
    
    
    add_executable(decode_encode main.cpp)
    target_link_libraries(decode_encode ${FFMPEG_LIBRARIES})
    

    注意我没有试过这个,所以你可能需要调整一下。

    【讨论】:

    • find_package(XXX REQUIRED) 之后检查XXX_FOUND 变量是否无用:如果找不到包,CMake 将打印相应的错误日志并终止。
    • 是的,但是如果确实找到了组件,则会打印消息。 else 部分肯定是没用的。谢谢!
    • 感谢您的帮助,但我在尝试重新生成项目时遇到了一个新问题By not providing "FindFFmpeg.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "FFmpeg", but CMake did not find one.
    • 这对我不起作用。后来我由PkgConfigpkg_check_modules 制作。
    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    相关资源
    最近更新 更多