summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2023-12-06 13:08:09 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-12-22 10:25:41 +0000
commit6290ad911e4eafd255b86606d2edd6de2fa2846d (patch)
tree69869c07317c3017ab29b320f5a3e2fbd7732970 /cmake
parent24a43429e215a7bfc9c6cecf8f236fdec945dccf (diff)
Implement shipping of dynamic ffmpeg together with the ffmpeg plugin
This is the first patch that implements ffmpeg shipping for both cases, building and installation. * deploy ffmpeg to plugins/multimedia/ffmpeg, as it should go together with the ffmpeg plugin. * ffmpeg deployment should be explicitly enquired via the option: -DQT_DEPLOY_FFMPEG=TRUE. The idea is to turn it on only when we or users need it, as users might have other compilation environments (e.g. it's so with boot2qt). Setting the flag for static qt builds is to be implemented later on. * Tested on Windows, Linux, macOS, some platform-specific details - On Unix platforms, ffmpeg libs might be put to plugins/multimedia/ffmpeg, closer to the ffmpeg plugin. However, on the current step, it was decided to deploy to the library directory. - On Windows, ffmpeg shared libs are linked through auxiliary static ones, it's handled in cmake scripts in the patch. - On Linux and Android, we will compile openssl and maybe vaapi stub shared libs and deploy the together with ffmpeg. - For Unix platforms, we will need to implement fixing of rpaths e.g. set 'ORIGIN' and hardcoded dylib deps (macOS). It will be done on the level of ffmpeg building on CI (install-ffmpeg.sh). Pick-to: 6.6 6.5 Change-Id: Ib7ce480b5412302f5d7ae9b247d5a5e87406a806 Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> (cherry picked from commit 545ffc25a7d8b544c6257892c24fe4f433c1e5cf) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'cmake')
-rw-r--r--cmake/FindFFmpeg.cmake160
1 files changed, 84 insertions, 76 deletions
diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake
index 554788a31..44a70ec8f 100644
--- a/cmake/FindFFmpeg.cmake
+++ b/cmake/FindFFmpeg.cmake
@@ -69,14 +69,19 @@ if (NOT FFmpeg_FIND_COMPONENTS)
set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL)
endif ()
+if (QT_DEPLOY_FFMPEG AND BUILD_SHARED_LIBS)
+ set(shared_libs_required TRUE)
+endif()
+
#
### Macro: set_component_found
#
-# Marks the given component as found if both *_LIBRARIES AND *_INCLUDE_DIRS is present.
+# Marks the given component as found if both *_LIBRARY_NAME AND *_INCLUDE_DIRS is present.
#
-macro(set_component_found _component )
- if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS)
- # message(STATUS " - ${_component} found.")
+macro(set_component_found _component)
+ if (${_component}_LIBRARY_NAME AND ${_component}_INCLUDE_DIRS AND
+ (${_component}_SHARED_LIBRARIES OR NOT shared_libs_required))
+ # message(STATUS " - ${_component} found.")
set(${_component}_FOUND TRUE)
set(${CMAKE_FIND_PACKAGE_NAME}_${_component}_FOUND TRUE)
else ()
@@ -125,7 +130,12 @@ macro(find_component _component _pkgconfig _library _header)
ffmpeg include
)
- find_library(${_component}_LIBRARY NAMES ${PC_${_component}_LIBRARIES} ${_library}
+ if (shared_libs_required AND NOT WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
+ endif()
+
+ find_library(${_component}_LIBRARY
+ NAMES ${PC_${_component}_LIBRARIES} ${_library}
HINTS
${PC_${_component}_LIBDIR}
${PC_${_component}_LIBRARY_DIRS}
@@ -133,64 +143,61 @@ macro(find_component _component _pkgconfig _library _header)
PATHS
${FFMPEG_DIR}
PATH_SUFFIXES
- lib
+ lib bin
)
if(FFMPEG_DIR OR FFMPEG_ROOT)
set(CMAKE_FIND_ROOT_PATH "${__find_ffmpeg_backup_root_dir}")
endif()
- get_filename_component(${_component}_LIBRARY_DIR_FROM_FIND ${${_component}_LIBRARY} DIRECTORY)
- get_filename_component(${_component}_LIBRARY_FROM_FIND ${${_component}_LIBRARY} NAME)
+ if (${_component}_LIBRARY)
+ get_filename_component(${_component}_LIBRARY_DIR ${${_component}_LIBRARY} DIRECTORY)
+ get_filename_component(${_component}_LIBRARY_NAME ${${_component}_LIBRARY} NAME)
- set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.")
- set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.")
- set(${_component}_LIBRARY_DIRS ${${_component}_LIBRARY_DIR_FROM_FIND} CACHE STRING "The ${_component} library dirs.")
- set(${_component}_LIBRARIES ${${_component}_LIBRARY_FROM_FIND} CACHE STRING "The ${_component} libraries.")
+ # On Windows, shared linking goes through 'integration' static libs, so we should look for shared ones anyway
+ # On Unix, we gather symlinks as well so that we could install them.
+ if (WIN32 OR ${${_component}_LIBRARY_NAME} MATCHES "\\${CMAKE_SHARED_LIBRARY_SUFFIX}$")
+ # the searching pattern is pretty rough but it seems to be sufficient to gather dynamic libs
+ get_filename_component(name_we ${${_component}_LIBRARY} NAME_WE)
-# message("Libs" ${FFMPEG_DIR} ${${_component}_LIBRARIES} ${${_component}_LIBRARY_DIRS})
+ file(GLOB ${_component}_SHARED_LIBRARIES "${${_component}_LIBRARY_DIR}/${name_we}*${CMAKE_SHARED_LIBRARY_SUFFIX}*")
+ endif()
-# message(STATUS "L0: ${${_component}_LIBRARIES}")
-# message(STATUS "L1: ${PC_${_component}_LIBRARIES}")
-# message(STATUS "L2: ${_library}")
-# message(STATUS "L3: ${${_component}_LIBRARY}")
-# message(STATUS "L4: ${${_component}_LIBRARY_DIRS}")
+ endif()
+ set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER})
set_component_found(${_component})
- mark_as_advanced(
- ${_component}_LIBRARY
- ${_component}_INCLUDE_DIRS
- ${_component}_LIBRARY_DIRS
- ${_component}_LIBRARIES
- ${_component}_DEFINITIONS
- ${_component}_VERSION)
-
endmacro()
# Clear the previously cached variables, because they are recomputed every time
# the Find script is included.
-set(FFMPEG_INCLUDE_DIRS "")
-set(FFMPEG_LIBRARIES "")
-set(FFMPEG_DEFINITIONS "")
-set(FFMPEG_LIBRARY_DIRS "")
-
-# Check for all possible component.
-find_component(AVCODEC libavcodec avcodec libavcodec/avcodec.h)
-find_component(AVFORMAT libavformat avformat libavformat/avformat.h)
-find_component(AVDEVICE libavdevice avdevice libavdevice/avdevice.h)
-find_component(AVUTIL libavutil avutil libavutil/avutil.h)
-find_component(AVFILTER libavfilter avfilter libavfilter/avfilter.h)
-find_component(SWSCALE libswscale swscale libswscale/swscale.h)
-find_component(POSTPROC libpostproc postproc libpostproc/postprocess.h)
-find_component(SWRESAMPLE libswresample swresample libswresample/swresample.h)
-
-# Linking to private FFmpeg libraries is only needed if it was built statically
-# Only one of the components needs to be tested
-if(AVCODEC_LIBRARY AND ${AVCODEC_LIBRARY} MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$")
- set(FFMPEG_IS_STATIC TRUE CACHE INTERNAL "")
-endif()
+unset(FFMPEG_INCLUDE_DIRS)
+unset(FFMPEG_LIBRARIES)
+unset(FFMPEG_SHARED_LIBRARIES)
+unset(FFMPEG_DEFINITIONS)
+unset(FFMPEG_LIBRARY_DIRS)
-if (FFMPEG_IS_STATIC AND (ANDROID OR LINUX))
+# Check for components.
+foreach (_component ${FFmpeg_FIND_COMPONENTS})
+ string(TOLOWER ${_component} library)
+ find_component(${_component} "lib${library}" ${library} "lib${library}/${library}.h")
+
+ if (${_component}_FOUND)
+ list(APPEND FFMPEG_LIBRARIES ${${_component}_LIBRARY_NAME})
+ list(APPEND FFMPEG_DEFINITIONS ${${_component}_DEFINITIONS})
+ list(APPEND FFMPEG_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS})
+ list(APPEND FFMPEG_LIBRARY_DIRS ${${_component}_LIBRARY_DIR})
+
+ if (${_component}_SHARED_LIBRARIES)
+ list(APPEND FFMPEG_SHARED_LIBRARIES ${${_component}_SHARED_LIBRARIES})
+ list(APPEND FFMPEG_SHARED_COMPONENTS ${_component})
+ else()
+ list(APPEND FFMPEG_STATIC_COMPONENTS ${_component})
+ endif()
+ endif()
+endforeach()
+
+if (NOT FFMPEG_SHARED_COMPONENTS AND (ANDROID OR LINUX))
set(ENABLE_DYNAMIC_RESOLVE_OPENSSL_SYMBOLS TRUE CACHE INTERNAL "")
endif()
@@ -254,56 +261,61 @@ endfunction()
#if (NOT FFMPEG_LIBRARIES)
# Check if the required components were found and add their stuff to the FFMPEG_* vars.
- foreach (_component ${FFmpeg_FIND_COMPONENTS})
- if (${_component}_FOUND)
- # message(STATUS "Libs: ${${_component}_LIBRARIES} | ${PC_${_component}_LIBRARIES}")
-
- # message(STATUS "Required component ${_component} present.")
- set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${${_component}_LIBRARY} ${${_component}_LIBRARIES})
- set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} ${${_component}_DEFINITIONS})
- list(APPEND FFMPEG_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS})
- list(APPEND FFMPEG_LIBRARY_DIRS ${${_component}_LIBRARY_DIRS})
+ foreach (_component ${FFmpeg_FIND_COMPONENTS})
+ if (${_component}_FOUND)
string(TOLOWER ${_component} _lowerComponent)
if (NOT TARGET FFmpeg::${_lowerComponent})
add_library(FFmpeg::${_lowerComponent} INTERFACE IMPORTED)
set_target_properties(FFmpeg::${_lowerComponent} PROPERTIES
INTERFACE_COMPILE_OPTIONS "${${_component}_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES ${${_component}_INCLUDE_DIRS}
- INTERFACE_LINK_LIBRARIES "${${_component}_LIBRARIES}"
- INTERFACE_LINK_DIRECTORIES "${${_component}_LIBRARY_DIRS}"
+ INTERFACE_LINK_LIBRARIES "${${_component}_LIBRARY_NAME}"
+ INTERFACE_LINK_DIRECTORIES "${${_component}_LIBRARY_DIR}"
)
- if(FFMPEG_IS_STATIC)
- __ffmpeg_internal_set_dependencies(${_lowerComponent})
+ if(NOT ${_component}_SHARED_LIBRARIES)
+ __ffmpeg_internal_set_dependencies(${_lowerComponent})
endif()
- target_link_libraries(FFmpeg::${_lowerComponent} INTERFACE "${${_component}_LIBRARY}")
+ target_link_libraries(FFmpeg::${_lowerComponent} INTERFACE "${${_component}_LIBRARY_NAME}")
if (UNIX AND NOT APPLE)
target_link_options(FFmpeg::${_lowerComponent} INTERFACE "-Wl,--exclude-libs=lib${_lowerComponent}")
endif ()
- endif()
- else()
- # message(STATUS "Required component ${_component} missing.")
+ endif()
endif()
endforeach ()
# Build the include path with duplicates removed.
- if (FFMPEG_INCLUDE_DIRS)
- list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS)
- endif ()
+ list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS)
+ list(REMOVE_DUPLICATES FFMPEG_LIBRARY_DIRS)
+ list(REMOVE_DUPLICATES FFMPEG_SHARED_LIBRARIES)
# cache the vars.
set(FFMPEG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS} CACHE STRING "The FFmpeg include directories." FORCE)
set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} CACHE STRING "The FFmpeg libraries." FORCE)
set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE)
set(FFMPEG_LIBRARY_DIRS ${FFMPEG_LIBRARY_DIRS} CACHE STRING "The FFmpeg library dirs." FORCE)
+ set(FFMPEG_SHARED_LIBRARIES ${FFMPEG_SHARED_LIBRARIES} CACHE STRING "The FFmpeg dynamic libraries." FORCE)
mark_as_advanced(FFMPEG_INCLUDE_DIRS
FFMPEG_LIBRARIES
FFMPEG_DEFINITIONS
- FFMPEG_LIBRARY_DIRS)
+ FFMPEG_LIBRARY_DIRS
+ FFMPEG_SHARED_LIBRARIES
+ )
+# endif ()
+
+list(LENGTH FFMPEG_LIBRARY_DIRS DIRS_COUNT)
+if (${DIRS_COUNT} GREATER 1)
+ message(WARNING "One ffmpeg library dir is expected, found dirs: ${FFMPEG_LIBRARY_DIRS}")
+endif()
-#endif ()
+if(FFMPEG_SHARED_COMPONENTS AND FFMPEG_STATIC_COMPONENTS)
+ message(WARNING
+ "Only static or shared components are expected\n"
+ " static components: ${FFMPEG_STATIC_COMPONENTS}\n"
+ " static components: ${FFMPEG_SHARED_COMPONENTS}")
+endif()
if (NOT TARGET FFmpeg::FFmpeg)
add_library(FFmpeg INTERFACE)
@@ -311,19 +323,15 @@ if (NOT TARGET FFmpeg::FFmpeg)
INTERFACE_COMPILE_OPTIONS "${FFMPEG_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${FFMPEG_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${FFMPEG_LIBRARIES}"
- INTERFACE_LINK_DIRECTORIES "${FFMPEG_LIBRARY_DIRS}")
+ INTERFACE_LINK_DIRECTORIES "${FFMPEG_LIBRARY_DIRS}"
+ )
add_library(FFmpeg::FFmpeg ALIAS FFmpeg)
endif()
-# Now set the noncached _FOUND vars for the components.
-foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE)
- set_component_found(${_component})
-endforeach ()
-
# Compile the list of required vars
set(_FFmpeg_REQUIRED_VARS FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIRS)
foreach (_component ${FFmpeg_FIND_COMPONENTS})
- list(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARIES ${_component}_INCLUDE_DIRS)
+ list(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARY ${_component}_INCLUDE_DIRS)
endforeach ()
# Give a nice error message if some of the required vars are missing.