#[=======================================================================[.rst FindFFmpeg ---------- FindModule for FFmpeg and associated libraries .. versionchanged:: 3.0 Updated FindModule to CMake standards Components ^^^^^^^^^^ .. versionadded:: 1.0 This module contains provides several components: ``avcodec`` ``avdevice`` ``avfilter`` ``avformat`` ``avutil`` ``postproc`` ``swscale`` ``swresample`` Import targets exist for each component. Imported Targets ^^^^^^^^^^^^^^^^ .. versionadded:: 2.0 This module defines the :prop_tgt:`IMPORTED` targets: ``FFmpeg::avcodec`` AVcodec component ``FFmpeg::avdevice`` AVdevice component ``FFmpeg::avfilter`` AVfilter component ``FFmpeg::avformat`` AVformat component ``FFmpeg::avutil`` AVutil component ``FFmpeg::postproc`` postproc component ``FFmpeg::swscale`` SWscale component ``FFmpeg::swresample`` SWresample component Result Variables ^^^^^^^^^^^^^^^^ This module sets the following variables: ``FFmpeg_FOUND`` True, if all required components and the core library were found. ``FFmpeg_VERSION`` Detected version of found FFmpeg libraries. ``FFmpeg_INCLUDE_DIRS`` Include directories needed for FFmpeg. ``FFmpeg_LIBRARIES`` Libraries needed to link to FFmpeg. ``FFmpeg_DEFINITIONS`` Compiler flags required for FFmpeg. ``FFmpeg__VERSION`` Detected version of found FFmpeg component library. ``FFmpeg__INCLUDE_DIRS`` Include directories needed for FFmpeg component. ``FFmpeg__LIBRARIES`` Libraries needed to link to FFmpeg component. ``FFmpeg__DEFINITIONS`` Compiler flags required for FFmpeg component. Cache variables ^^^^^^^^^^^^^^^ The following cache variables may also be set: ``FFmpeg__LIBRARY`` Path to the library component of FFmpeg. ``FFmpeg__INCLUDE_DIR`` Directory containing ``.h``. #]=======================================================================] # cmake-format: off # cmake-lint: disable=C0103 # cmake-lint: disable=C0307 # cmake-format: on include(FindPackageHandleStandardArgs) set(_DEFAULT_COMPONENTS avcodec avdevice avformat avfilter avresample avutil postproc swscale swresample) set(component_avcodec libavcodec avcodec avcodec.h) set(component_avdevice libavdevice avdevice avdevice.h) set(component_avformat libavformat avformat avformat.h) set(component_avfilter libavfilter avfilter avfilter.h) set(component_avresample libavresample avresample avresample.h) set(component_avutil libavutil avutil avutil.h) set(component_postproc libpostproc postproc postprocess.h) set(component_swscale libswscale swscale swscale.h) set(component_swresample libswresample swresample swresample.h) if(NOT FFmpeg_FIND_COMPONENTS) set(FFmpeg_FIND_COMPONENTS ${_DEFAULT_COMPONENTS}) endif() # FFmpeg_find_component: Find and set up requested FFmpeg component macro(FFmpeg_find_component component) list(GET component_${component} 0 component_libname) list(GET component_${component} 1 component_name) list(GET component_${component} 2 component_header) if(NOT CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") find_package(PkgConfig QUIET) if(PKG_CONFIG_FOUND) pkg_search_module(PC_FFmpeg_${component} QUIET ${component_libname}) endif() endif() find_path( FFmpeg_${component}_INCLUDE_DIR NAMES ${component_libname}/${component_header} ${component_libname}/version.h HINTS ${PC_FFmpeg_${component}_INCLUDE_DIRS} PATHS /usr/include /usr/local/include DOC "FFmpeg component ${component_name} include directory") ffmpeg_check_version() if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") find_library( FFmpeg_${component}_IMPLIB NAMES ${component_libname} ${component_name} DOC "FFmpeg component ${component_name} import library location") ffmpeg_find_dll() else() find_library( FFmpeg_${component}_LIBRARY NAMES ${component_libname} ${component_name} HINTS ${PC_FFmpeg_${component}_LIBRARY_DIRS} PATHS /usr/lib /usr/local/lib DOC "FFmpeg component ${component_name} location") endif() if(FFmpeg_${component}_LIBRARY AND FFmpeg_${component}_INCLUDE_DIR) set(FFmpeg_${component}_FOUND TRUE) set(FFmpeg_${component}_LIBRARIES ${${_library_var}}) set(FFmpeg_${component}_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIR}) set(FFmpeg_${component}_DEFINITIONS ${PC_FFmpeg_${component}_CFLAGS_OTHER}) mark_as_advanced(FFmpeg_${component}_LIBRARY FFmpeg_${component}_INCLUDE_DIR FFmpeg_${component}_IMPLIB) endif() endmacro() # FFmpeg_find_dll: Macro to find DLL for corresponding import library macro(FFmpeg_find_dll) cmake_path(GET FFmpeg_${component}_IMPLIB PARENT_PATH _implib_path) cmake_path(SET _bin_path NORMALIZE "${_implib_path}/../bin") string(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" _dll_version "${FFmpeg_${component}_VERSION}") find_program( FFmpeg_${component}_LIBRARY NAMES ${component_name}-${_dll_version}.dll HINTS ${_implib_path} ${_bin_path} DOC "FFmpeg component ${component_name} DLL location") if(NOT FFmpeg_${component}_LIBRARY) set(FFmpeg_${component}_LIBRARY "${FFmpeg_${component}_IMPLIB}") endif() unset(_implib_path) unset(_bin_path) unset(_dll_version) endmacro() # FFmpeg_check_version: Macro to help extract version number from FFmpeg headers macro(FFmpeg_check_version) if(PC_FFmpeg_${component}_VERSION) set(FFmpeg_${component}_VERSION ${PC_FFmpeg_${component}_VERSION}) elseif(EXISTS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h") if(EXISTS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version_major.h") file(STRINGS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version_major.h" _version_string REGEX "^.*VERSION_MAJOR[ \t]+[0-9]+[ \t]*$") string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}") file(STRINGS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h" _version_string REGEX "^.*VERSION_(MINOR|MICRO)[ \t]+[0-9]+[ \t]*$") string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}") string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" _version_patch "${_version_string}") else() file(STRINGS "${FFmpeg_${component}_INCLUDE_DIR}/${component_libname}/version.h" _version_string REGEX "^.*VERSION_(MAJOR|MINOR|MICRO)[ \t]+[0-9]+[ \t]*$") string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}") string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}") string(REGEX REPLACE ".*VERSION_MICRO[ \t]+([0-9]+).*" "\\1" _version_patch "${_version_string}") endif() set(FFmpeg_${component}_VERSION "${_version_major}.${_version_minor}.${_version_patch}") unset(_version_major) unset(_version_minor) unset(_version_patch) else() if(NOT FFmpeg_FIND_QUIETLY) message(AUTHOR_WARNING "Failed to find ${component_name} version.") endif() set(FFmpeg_${component}_VERSION 0.0.0) endif() endmacro() # FFmpeg_set_soname: Set SONAME property on imported library targets macro(FFmpeg_set_soname) if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") execute_process( COMMAND sh -c "otool -D '${FFmpeg_${component}_LIBRARY}' | grep -v '${FFmpeg_${component}_LIBRARY}'" OUTPUT_VARIABLE _output RESULT_VARIABLE _result) if(_result EQUAL 0 AND _output MATCHES "^@rpath/") set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_SONAME "${_output}") endif() elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") execute_process( COMMAND sh -c "objdump -p '${FFmpeg_${component}_LIBRARY}' | grep SONAME" OUTPUT_VARIABLE _output RESULT_VARIABLE _result) if(_result EQUAL 0) string(REGEX REPLACE "[ \t]+SONAME[ \t]+([^ \t]+)" "\\1" _soname "${_output}") set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_SONAME "${_soname}") unset(_soname) endif() endif() unset(_output) unset(_result) endmacro() foreach(component IN LISTS FFmpeg_FIND_COMPONENTS) if(NOT component IN_LIST _DEFAULT_COMPONENTS) message(FATAL_ERROR "Unknown FFmpeg component specified: ${component}.") endif() if(NOT FFmpeg_${component}_FOUND) ffmpeg_find_component(${component}) endif() if(FFmpeg_${component}_FOUND) list(APPEND FFmpeg_LIBRARIES ${FFmpeg_${component}_LIBRARY}) list(APPEND FFmpeg_DEFINITIONS ${FFmpeg_${component}_DEFINITIONS}) list(APPEND FFmpeg_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIR}) endif() endforeach() if(NOT FFmpeg_avutil_FOUND) ffmpeg_find_component(avutil) endif() if(EXISTS "${FFmpeg_avutil_INCLUDE_DIR}/libavutil/ffversion.h") file(STRINGS "${FFmpeg_avutil_INCLUDE_DIR}/libavutil/ffversion.h" _version_string REGEX "^.*FFMPEG_VERSION[ \t]+\"n[0-9a-z\\.-]+\"[ \t]*$") string(REGEX REPLACE ".*FFMPEG_VERSION[ \t]+\"n([0-9]+\\.[0-9]).+\".*" "\\1" FFmpeg_VERSION "${_version_string}") endif() list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS) list(REMOVE_DUPLICATES FFmpeg_LIBRARIES) list(REMOVE_DUPLICATES FFmpeg_DEFINITIONS) if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows") set(FFmpeg_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.") elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") set(FFmpeg_ERROR_REASON "Ensure that required FFmpeg libraries are installed on the system.") endif() find_package_handle_standard_args( FFmpeg REQUIRED_VARS FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS VERSION_VAR FFmpeg_VERSION HANDLE_COMPONENTS REASON_FAILURE_MESSAGE "${FFmpeg_ERROR_REASON}") if(FFmpeg_FOUND AND NOT TARGET FFmpeg::FFmpeg) add_library(FFmpeg::FFmpeg INTERFACE IMPORTED) endif() foreach(component IN LISTS FFmpeg_FIND_COMPONENTS) if(FFmpeg_${component}_FOUND AND NOT TARGET FFmpeg::${component}) if(IS_ABSOLUTE "${FFmpeg_${component}_LIBRARY}") if(DEFINED FFmpeg_${component}_IMPLIB) if(FFmpeg_${component}_IMPLIB STREQUAL FFmpeg_${component}_LIBRARY) add_library(FFmpeg::${component} STATIC IMPORTED) else() add_library(FFmpeg::${component} SHARED IMPORTED) set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_IMPLIB "${FFmpeg_${component}_IMPLIB}") endif() else() add_library(FFmpeg::${component} UNKNOWN IMPORTED) ffmpeg_set_soname() endif() set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_LOCATION "${FFmpeg_${component}_LIBRARY}") else() add_library(FFmpeg::${component} INTERFACE IMPORTED) set_property(TARGET FFmpeg::${component} PROPERTY IMPORTED_LIBNAME "${FFmpeg_${component}_LIBRARY}") endif() set_target_properties( FFmpeg::${component} PROPERTIES INTERFACE_COMPILE_OPTIONS "${PC_FFmpeg_${component}_CFLAGS_OTHER}" INTERFACE_INCLUDE_DIRECTORIES "${FFmpeg_${component}_INCLUDE_DIR}" VERSION ${FFmpeg_${component}_VERSION}) get_target_property(_ffmpeg_interface_libraries FFmpeg::FFmpeg INTERFACE_LINK_LIBRARIES) if(NOT FFmpeg::${component} IN_LIST _ffmpeg_interface_libraries) set_property( TARGET FFmpeg::FFmpeg APPEND PROPERTY INTERFACE_LINK_LIBRARIES FFmpeg::${component}) endif() endif() endforeach() include(FeatureSummary) set_package_properties( FFmpeg PROPERTIES URL "https://www.ffmpeg.org" DESCRIPTION "A complete, cross-platform solution to record, convert and stream audio and video.")