0

I am currently building FFmpeg as an external project. FFmpeg builds correctly and the library is stuck inside an appropriate lib folder. And inside that lib folder a pkgconfig folder is placed inside with all of the .pc files with the information of all of the associated libraries. Of course, I could be thinking about this wrong. However when I built FFmpeg, I had to use a pkg_congig so it could link with the libraries of x264. Here is my ffmpeg_exteral.cmake file:

SET_PROPERTY(DIRECTORY PROPERTY "EP_BASE" ${ep_base})

set( FFmpeg_url "https://github.com/FFmpeg/FFmpeg.git")
set( FFmpeg_TAG "n4.2")
set(FFmpeg_depends "x264_external_download")

set(PATH_DEPENDS "${x264_LIBRARY_DIR}/pkgconfig")

ExternalProject_Add(FFmpeg_external_download
  DEPENDS ${FFmpeg_depends}
  GIT_REPOSITORY ${FFmpeg_url}
  GIT_TAG ${FFmpeg_TAG}
  UPDATE_COMMAND ""
  PATCH_COMMAND ""
  INSTALL_COMMAND ""
  INSTALL_DIR ""
  CONFIGURE_COMMAND PKG_CONFIG_PATH=${PATH_DEPENDS} <SOURCE_DIR>/configure
    --prefix=<BINARY_DIR>/build
    --enable-static
    --extra-cflags=-I${x264_INCLUDE_DIR}\ --static
    --extra-ldflags=-L${x264_LIBRARY_DIR}
    --enable-gpl
    --enable-libx264
  BUILD_COMMAND make
    -j8
)

#CACHE PATH "" seems to write the path to a file that I can set 
#library paths to. 

ExternalProject_Get_Property(FFmpeg_external_download BINARY_DIR)

set(FFmpeg_LIBRARY_DIR ${BINARY_DIR}/build/lib CACHE INTERNAL "")
set(FFmpeg_INCLUDE_DIR ${BINARY_DIR}/build/include CACHE INTERNAL "")

add_library(FFmpeg_external STATIC IMPORTED)

And this links directly with a x264_external.cmake

SET_PROPERTY(DIRECTORY PROPERTY "EP_BASE" ${ep_base})

set( x264_url "https://code.videolan.org/videolan/x264.git")
set( x264_TAG "origin/stable")


##[[
  The configure command is required because FFMPEG will try to build these 
  libraries when x264 static does not need them. 
]]
ExternalProject_Add(x264_external_download
  GIT_REPOSITORY ${x264_url}
  GIT_TAG ${x264_TAG}
  UPDATE_COMMAND ""
  PATCH_COMMAND ""
  INSTALL_COMMAND ""
  INSTALL_DIR ""
  CONFIGURE_COMMAND <SOURCE_DIR>/configure
    --prefix=<BINARY_DIR>/x264_build
    --enable-static
    --disable-opencl 
    --disable-avs 
    --disable-cli 
    --disable-ffms 
    --disable-gpac 
    --disable-lavf 
    --disable-swscale
  BUILD_COMMAND make install
    -j8
)

#CACHE PATH "" seems to write the path to a file that I can set 
#library paths to. 

ExternalProject_Get_Property(x264_external_download BINARY_DIR)

set(x264_LIBRARY_DIR ${BINARY_DIR}/x264_build/lib CACHE INTERNAL "")
set(x264_BINARY_DIR ${BINARY_DIR}/x264_build/bin CACHE INTERNAL "")
set(x264_INCLUDE_DIR ${BINARY_DIR}/x264_build/include CACHE INTERNAL "")

add_library(x264_external STATIC IMPORTED)

As you can see, FFmpeg takes the pkg_config_path from the library directory of x264 and they link together just fine. However, now that I am trying to build a simple example to make sure FFmpeg is linking with my project. I get errors of undefined references to anything from FFmpeg. This is all main.cpp has:

#include <iostream>
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavfilter/avfilter.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavutil/avutil.h>

int main()
{
  std::cout << "It compiled." << std::endl;

  avformat_network_init();

  std::cout << "It worked." << std::endl;

  avformat_network_deinit();

}

And in the cmake file that uses it, all it has is:

set(CMAKE_PREFIX_PATH ${FFmpeg_LIBRARY_DIR}/pkgconfig)

include_directories(${FFmpeg_INCLUDE_DIR})
link_directories(${FFmpeg_LIBRARY_DIR})

add_executable(Main main.cpp)

add_dependencies(Main FFmpeg_external_download)

I read that CMAKE_PREFIX_PATH will find and read in .pc files, however it doesn't seem to be doing much here, and as far as I can tell, I am not really sure how to set PkgConfig to find a custom path for a package. And maybe this is linking correctly because I am doing this wrong. Any help on how to get these to link together would be tremendous help.

EDIT: I forgot to say that FFmpeg builds 8 libraries that I am trying to link to in the lib folder. I have tried creating a library for each of them, setting their target properties to their libraries, and linking them to main using target_link_libraries and that hasn't seemed to work either.

EDIT 2: Error message

CMakeFiles/Main.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x2d): undefined reference to `avformat_network_init()'
main.cpp:(.text+0x5a): undefined reference to `avformat_network_deinit()'
collect2: error: ld returned 1 exit status
Source/CMakeFiles/Main.dir/build.make:91: recipe for target 'bin/Main' failed
make[2]: *** [bin/Main] Error 1
CMakeFiles/Makefile2:242: recipe for target 'Source/CMakeFiles/Main.dir/all' failed
make[1]: *** [Source/CMakeFiles/Main.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

EDIT 3: Verbose output

-L/home/sailanarmo/reeee/Superbuild/Build/FFmpeg_external_download/build/lib -Wl,-rpath,/home/sailanarmo/reeee/Superbuild/Build/FFmpeg_external_download/build/lib -lpthread ../Superbuild/Build/FFmpeg_external_download/build/lib/libavcodec.a ../Superbuild/Build/FFmpeg_external_download/build/lib/libavdevice.a ../Superbuild/Build/FFmpeg_external_download/build/lib/libavfilter.a ../Superbuild/Build/FFmpeg_external_download/build/lib/libavformat.a ../Superbuild/Build/FFmpeg_external_download/build/lib/libavutil.a ../Superbuild/Build/FFmpeg_external_download/build/lib/libpostproc.a ../Superbuild/Build/FFmpeg_external_download/build/lib/libswresample.a ../Superbuild/Build/FFmpeg_external_download/build/lib/libswscale.a

Sailanarmo
  • 1,139
  • 15
  • 41
  • In your `CMakeLists.txt` I see neither **linking** (`target_link_libraries` calls) nor even assigning **libraries paths** to the IMPORTED targets (via `IMPORTED_LOCATION` property). – Tsyvarev Aug 20 '19 at 20:09
  • @Tsyvarev That is another method that I did do. For example, I did `add_library(libavcodec STATIC IMPORTED)` then `set_target_properties(libavcodec PROPERTIES IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}/libavcodec.a) And then in CmakeLists.txt I did `target_link_libraries(Main libavcodec)` however I did that with each library that was created and I still get the error. – Sailanarmo Aug 20 '19 at 20:13
  • Please, **show the error message** (exactly as it is written). And show the code, which follows that way for link the library: https://stackoverflow.com/a/10550334/3440745. Note, that as you use static libraries, you need to link with exact library which defines required symbols. Unlike to shared libraries, static ones by themselves do not contain information about dependent libraries. – Tsyvarev Aug 20 '19 at 20:18
  • @Tsyvarev I have supplied the error message. – Sailanarmo Aug 20 '19 at 21:08
  • With `make VERBOSE=1` you may see the exact command line which calls the linker. Check that this command line contains linking with `libavformat` library. – Tsyvarev Aug 20 '19 at 21:16
  • @Tsyvarev I have posted what the verbose output has. And it looks like it is there. But I am not sure if that is linking? – Sailanarmo Aug 20 '19 at 21:20

0 Answers0