diff options
author | Piotr Srebrny <piotr.srebrny@qt.io> | 2022-03-25 14:53:19 +0100 |
---|---|---|
committer | Piotr Srebrny <piotr.srebrny@qt.io> | 2022-03-29 17:28:19 +0200 |
commit | 3b9c6202a188645123f36479ee39c0c5e5e5f950 (patch) | |
tree | c8e46a5a4dbe034689705f65da2c78cb01a71e13 /cmake | |
parent | 980c145069c589085b4dee4b4c2b69e3b1a0adc3 (diff) | |
download | qtmultimedia-3b9c6202a188645123f36479ee39c0c5e5e5f950.tar.gz |
Link static ffmpeg library to ffmpeg multimedia plugin
This patch enables linking of the static FFmpeg library.
When linking the static library we have to provide the library
dependencies. These are found in the pkgconfig files generated during
the library build and are parsed with
the __ffmpeg_internal_set_dependencies function. The function adds
dependencies listed in lines starting with Libs and Libs.private.
While dependencies from Libs.private should suffice this is not
the case on Windows where dependencies are listed in the Libs line.
The -Wl,--exclude-libs=libavcodec flag fixes linking on Linux which
otherwise fails with relocation problems on ff_pw_9 symbol in
libavcodec. The flag prevents export of the libavcodec symbols, thus
linker can optimize access to the static variables (including ff_pw_9)
which otherwise are bound to the shared library GOT.
The patch fixes the order of FFmpeg libraries linked to FFmpeg plugin
to correctly display the dependencies between FFmpeg libraries.
Change-Id: I119d975fcff2b610280e27478ad186b4ffbc2b25
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/FindFFmpeg.cmake | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake index 31f160e14..650f200f3 100644 --- a/cmake/FindFFmpeg.cmake +++ b/cmake/FindFFmpeg.cmake @@ -158,6 +158,37 @@ set(FFMPEG_LIBRARIES "") set(FFMPEG_DEFINITIONS "") set(FFMPEG_LIBRARY_DIRS "") +# Function parses package config file to find the static library dependencies +# and adds them to the target library. +function(__ffmpeg_internal_set_dependencies lib) + set(PC_FILE ${FFMPEG_DIR}/lib/pkgconfig/lib${lib}.pc) + if(EXISTS ${PC_FILE}) + file(READ ${PC_FILE} pcfile) + + string(REGEX REPLACE ".*Libs:([A-Za-z0-9_. \${}-]+).*" "\\1" out "${pcfile}") + string(REGEX MATCHALL "\\-l[a-z0-9_-]+" libs_dependency ${out}) + string(REGEX MATCHALL "[A-Za-z0-9_-]+\\.lib" libs_dependency_lib ${out}) + + string(REGEX REPLACE ".*Libs.private:([A-Za-z0-9_. \${}-]+).*" "\\1" out "${pcfile}") + string(REGEX MATCHALL "\\-l[a-z0-9_-]+" libs_private_dependency ${out}) + string(REGEX MATCHALL "[A-Za-z0-9_-]+\\.lib" libs_private_dependency_lib ${out}) + + list(APPEND no_sufix ${libs_dependency} ${libs_private_dependency}) + list(APPEND lib_sufix ${libs_dependency_lib} ${libs_private_dependency_lib}) + + foreach(d ${no_sufix}) + string(REGEX REPLACE "\\-l" "" d ${d}) + if(NOT ${lib} MATCHES ${d}) + target_link_libraries(FFmpeg::${lib} INTERFACE ${d}) + endif() + endforeach() + foreach(d ${lib_sufix}) + string(REGEX REPLACE "\\.lib" "" d ${d}) + target_link_libraries(FFmpeg::${lib} INTERFACE ${d}) + endforeach() + endif() +endfunction() + # Check for cached results. If there are skip the costly part. #if (NOT FFMPEG_LIBRARIES) @@ -192,7 +223,9 @@ set(FFMPEG_LIBRARY_DIRS "") INTERFACE_LINK_LIBRARIES "${${_component}_LIBRARIES}" INTERFACE_LINK_DIRECTORIES "${${_component}_LIBRARY_DIRS}" ) - endif() + __ffmpeg_internal_set_dependencies(${_lowerComponent}) + target_link_libraries(FFmpeg::${_lowerComponent} INTERFACE "${${_component}_LIBRARY}") + endif() else() # message(STATUS "Required component ${_component} missing.") endif() @@ -226,6 +259,10 @@ if (NOT TARGET FFmpeg::FFmpeg) add_library(FFmpeg::FFmpeg ALIAS FFmpeg) endif() +if (TARGET FFmpeg::avcodec AND UNIX AND NOT APPLE) + target_link_options(FFmpeg::avcodec INTERFACE "-Wl,--exclude-libs=libavcodec") +endif () + # Now set the noncached _FOUND vars for the components. foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE) set_component_found(${_component}) |