summaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorPiotr Srebrny <piotr.srebrny@qt.io>2022-03-25 14:53:19 +0100
committerPiotr Srebrny <piotr.srebrny@qt.io>2022-03-29 17:28:19 +0200
commit3b9c6202a188645123f36479ee39c0c5e5e5f950 (patch)
treec8e46a5a4dbe034689705f65da2c78cb01a71e13 /cmake
parent980c145069c589085b4dee4b4c2b69e3b1a0adc3 (diff)
downloadqtmultimedia-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.cmake39
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})