14

I have installed ffmpeg (version 4) with Homebrew and I am trying to use the various ffmpeg libraries in a C++ project, but I am getting multiple errors during linking.

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 ... 

I have included the libraries as follow

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

But still, this doesn't work. I think I might have missed something in my CMakeLists.txt file, which at the moment looks like that :

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) 

I most likely need to specify additional linking flags, but is there is a better way to handle the linking part in a CMakeLists.txt file?

1

4 Answers 4

30

PkgConfig can be used to link the libraries more conveniently, as mentioned in a comment. With CMake 3.17, this links all libav libraries:

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 ) 
Sign up to request clarification or add additional context in comments.

2 Comments

How do you export this as a dependency to consuming packages in an install?
I have a similar problem as well and I can't find any solution.
23

Ok, I've found the solution. It appears that FFmpeg doesn't support find_package in CMake. I had to manually link the libraries as suggested here.

Final CMakeLists.txt looks like this

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}) 

I am sure there is a better way to aggregate all the libraries, though.

3 Comments

my cmake wont find the avcodec neither other libraries. Do you have any idea of whats happening?
Probably you will need to give it a hint. By far the simplest method would be to just hardcode the path. On Linux, you could find the file's location with find / -name avcodec.h. On Ubuntu it seems that this is installed in /usr/include/x86_64-linux-gnu/libavcodec/avcodec.h
Using pkgconfig is a cleaner option than manually giving the path.
4

You need to tell CMAKE where to find headers and libraries for ffmpeg in your system. You can use the find_package(ffmpeg to look into your system for you and then use the CMAKE variables it defines to set up the headers for the compiler and the libraries for the linker correctly.

  • header: include_directories(${FFMPEG_INCLUDE_DIRS})
  • libraries: target_link_libraries(decode_encode ${FFMPEG_LIBRARIES})

Something like the following should serve the purpouse.

 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}) 

NOTE I have not tried this, so you might need to tweak it.

4 Comments

Checking XXX_FOUND variable after find_package(XXX REQUIRED) is useless: If the package won't be found, CMake will print appropriate error log and will terminate.
Yes, but if the components are found indeed, then the message are printed. The else part is definitely useless. Thanks!
Thanks for your help, yet I have a new issue when trying to regenerate the project 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.
it's not work for me .Latter I made it by PkgConfig and pkg_check_modules.
0

there are some unofficial findFFmpeg scripts: eg:

https://github.com/snikulov/cmake-modules/blob/master/FindFFmpeg.cmake

but nothing official (yet?) at least in cmake 3.27.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.