From 61759c00a383e7c414681992d2658188a8b59d57 Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 10:58:24 +0200 Subject: [PATCH 01/13] Use 2.7 version of the VCPKG buildenvs --- tools/android_buildenv.sh | 10 ++++++---- tools/macos_buildenv.sh | 36 ++++++++++++++++++------------------ tools/update_vcpkg.py | 12 ++++++------ tools/windows_buildenv.bat | 24 ++++++++++++------------ 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/tools/android_buildenv.sh b/tools/android_buildenv.sh index 98e56bf05db..9eff21db9d7 100755 --- a/tools/android_buildenv.sh +++ b/tools/android_buildenv.sh @@ -31,13 +31,15 @@ HOST_ARCH=$(uname -m) # One of x86_64, arm64, i386, ppc or ppc64 if [ "$HOST_ARCH" == "x86_64" ]; then if [ -n "${BUILDENV_RELEASE}" ]; then - echo "ERROR: No release VCPKG for Android yet!" - exit 1 + VCPKG_TARGET_TRIPLET="arm64-android-rel" + BUILDENV_BRANCH="2.7-rel" + BUILDENV_NAME="mixxx-deps-2.7-arm64-android-rel-6d5a0074" + BUILDENV_SHA256="88eb436f26ab8879a48d509470b63fde679a142ada1748a051980f120d211035" else VCPKG_TARGET_TRIPLET="arm64-android" BUILDENV_BRANCH="2.7" - BUILDENV_NAME="mixxx-deps-2.7-arm64-android-458eeaf4" - BUILDENV_SHA256="77ad7e5e0178bc62f22c458c8d6e0ee5e7482305f18f8099775aa794ac2745b4" + BUILDENV_NAME="mixxx-deps-2.7-arm64-android-5777af9b" + BUILDENV_SHA256="5f12ffc5356a7821f8aa78b976653debf29961ae1e75774eb4ea79e2a0afb356" fi else echo "ERROR: Unsupported architecture detected: $HOST_ARCH" diff --git a/tools/macos_buildenv.sh b/tools/macos_buildenv.sh index 007c1014a58..70c64e55bf7 100755 --- a/tools/macos_buildenv.sh +++ b/tools/macos_buildenv.sh @@ -33,39 +33,39 @@ if [ "$HOST_ARCH" = "x86_64" ]; then if [ -n "${BUILDENV_ARM64_CROSS}" ]; then if [ -n "${BUILDENV_RELEASE}" ]; then VCPKG_TARGET_TRIPLET="arm64-osx-min1100-release" - BUILDENV_BRANCH="2.6-rel" - BUILDENV_NAME="mixxx-deps-2.6-arm64-osx-cross-rel-f46c645" - BUILDENV_SHA256="191fc876dfaaa49854d5a113b4bfe8e35bfa7d7b58118b645f0d2f2830839e51" + BUILDENV_BRANCH="2.7-rel" + BUILDENV_NAME="mixxx-deps-2.7-arm64-osx-cross-rel-6d5a0074" + BUILDENV_SHA256="a9a1c81198b1c2df808550c9304793cb0f71a251e6e50ecc309c643b432cf1f0" else VCPKG_TARGET_TRIPLET="arm64-osx-min1100" - BUILDENV_BRANCH="2.6" - BUILDENV_NAME="mixxx-deps-2.6-arm64-osx-cross-aa78b5a" - BUILDENV_SHA256="75187939a0847c98dd9c0c64a0bb35f7e8878f2288ac2e22ab99635f598bdd9a" + BUILDENV_BRANCH="2.7" + BUILDENV_NAME="mixxx-deps-2.7-arm64-osx-cross-5777af9b" + BUILDENV_SHA256="92cb1fc581d9b9e1cff5810a2c55bbc7e19bc1b5127cc4b542e62d886cdfcbe4" fi else if [ -n "${BUILDENV_RELEASE}" ]; then VCPKG_TARGET_TRIPLET="x64-osx-min1100-release" - BUILDENV_BRANCH="2.6-rel" - BUILDENV_NAME="mixxx-deps-2.6-x64-osx-rel-f46c645" - BUILDENV_SHA256="c28e64727743c126ea56c152a328a442e5bf8bb20705a2b232c1677ed290e0bb" + BUILDENV_BRANCH="2.7-rel" + BUILDENV_NAME="mixxx-deps-2.7-x64-osx-rel-6d5a0074" + BUILDENV_SHA256="d8033a4883f2d9dddea4ffb1a76984c1ecc82439d0aaa7ecac4550d52541b411" else VCPKG_TARGET_TRIPLET="x64-osx-min1100" - BUILDENV_BRANCH="2.6" - BUILDENV_NAME="mixxx-deps-2.6-x64-osx-aa78b5a" - BUILDENV_SHA256="ccb81981c4a45a65453531ac6a5d0d0ea18e0e1383b9c4fd09077125efce8391" + BUILDENV_BRANCH="2.7" + BUILDENV_NAME="mixxx-deps-2.7-x64-osx-5777af9b" + BUILDENV_SHA256="6f16c318c35ea43f2d6e5f18509f21ca0e9173f7a561b6467b3def600494c0d8" fi fi elif [ "$HOST_ARCH" = "arm64" ]; then if [ -n "${BUILDENV_RELEASE}" ]; then VCPKG_TARGET_TRIPLET="arm64-osx-min1100-release" - BUILDENV_BRANCH="2.6-rel" - BUILDENV_NAME="mixxx-deps-2.6-arm64-osx-rel-f46c645" - BUILDENV_SHA256="fd7873545ef564397f505c7f2611a0ab59091636cece7438cd10bf054fb7c950" + BUILDENV_BRANCH="2.7-rel" + BUILDENV_NAME="mixxx-deps-2.7-arm64-osx-rel-6d5a0074" + BUILDENV_SHA256="d5ad04e9273bf0437334b536bdaa81dde637e93feb1b0c18cd2f467d38ce8f33" else VCPKG_TARGET_TRIPLET="arm64-osx-min1100" - BUILDENV_BRANCH="2.6" - BUILDENV_NAME="mixxx-deps-2.6-arm64-osx-aa78b5a" - BUILDENV_SHA256="560b1572d65480a1773f70c320745f3fab8bb4a12380764d31d9547b38069401" + BUILDENV_BRANCH="2.7" + BUILDENV_NAME="mixxx-deps-2.7-arm64-osx-5777af9b" + BUILDENV_SHA256="a575e8d86a14d1e2888f5fd8b3a24c134b7bc6cbcd6805a3567a8ba492241db3" fi else echo "ERROR: Unsupported architecture detected: $HOST_ARCH" diff --git a/tools/update_vcpkg.py b/tools/update_vcpkg.py index 07d1c00c725..02325e11ade 100755 --- a/tools/update_vcpkg.py +++ b/tools/update_vcpkg.py @@ -73,12 +73,12 @@ "release_triplet": "arm64-osx-rel", "file": "tools/macos_buildenv.sh", }, - # { - # "host_os": "Linux", - # "triplet": "arm64-android", - # "release_triplet": "arm64-android-release", - # "file": "tools/android_buildenv.sh", - # }, + { + "host_os": "Linux", + "triplet": "arm64-android", + "release_triplet": "arm64-android-rel", + "file": "tools/android_buildenv.sh", + }, # { # "host_os": "Linux", # "triplet": "x64-linux", diff --git a/tools/windows_buildenv.bat b/tools/windows_buildenv.bat index 4580118dc39..a42c727b64e 100644 --- a/tools/windows_buildenv.bat +++ b/tools/windows_buildenv.bat @@ -34,27 +34,27 @@ IF NOT DEFINED INSTALL_ROOT ( IF /I "%PLATFORM%"=="arm64" ( IF DEFINED BUILDENV_RELEASE ( - SET BUILDENV_BRANCH=2.6-rel + SET BUILDENV_BRANCH=2.7-rel SET VCPKG_TARGET_TRIPLET=arm64-windows-release - SET BUILDENV_NAME=mixxx-deps-2.6-arm64-windows-rel-f46c645 - SET BUILDENV_SHA256=9492dac4bab0f14a48aa00ee1fdbc3c668893eb6b5f13c7442f7fc6ca5ee3145 + SET BUILDENV_NAME=mixxx-deps-2.7-arm64-windows-rel-6d5a0074 + SET BUILDENV_SHA256=43354581fc4d28529f8341dcf22b8191b8bc79368e5a977bc0f6dca7a1dcab16 ) ELSE ( - SET BUILDENV_BRANCH=2.6 + SET BUILDENV_BRANCH=2.7 SET VCPKG_TARGET_TRIPLET=arm64-windows - SET BUILDENV_NAME=mixxx-deps-2.6-arm64-windows-aa78b5a - SET BUILDENV_SHA256=50fd23c4e64b530bca0389e93c9efcbe3d9695ec1274cbccc876e38b966d0726 + SET BUILDENV_NAME=mixxx-deps-2.7-arm64-windows-5777af9b + SET BUILDENV_SHA256=4804ab1004767e3890781efae7e4438bb0330a3a52764490880ef6eb6fb35cfc ) ) ELSE IF /I "%PLATFORM%"=="x64" ( IF DEFINED BUILDENV_RELEASE ( - SET BUILDENV_BRANCH=2.6-rel + SET BUILDENV_BRANCH=2.7-rel SET VCPKG_TARGET_TRIPLET=x64-windows-release - SET BUILDENV_NAME=mixxx-deps-2.6-x64-windows-rel-f46c645 - SET BUILDENV_SHA256=bab7e63f463168df88f6bc0677dd0bf0d160b138696ec5d56b387083033fe2e5 + SET BUILDENV_NAME=mixxx-deps-2.7-x64-windows-rel-6d5a0074 + SET BUILDENV_SHA256=f57f37130e2fb206382cc89973ed62907e773b99de94af658bbef13379e1cc0f ) ELSE ( - SET BUILDENV_BRANCH=2.6 + SET BUILDENV_BRANCH=2.7 SET VCPKG_TARGET_TRIPLET=x64-windows - SET BUILDENV_NAME=mixxx-deps-2.6-x64-windows-aa78b5a - SET BUILDENV_SHA256=2628755773bed4e25233f9b9951c363ccebac23ca917ea91e9a93c70428b6648 + SET BUILDENV_NAME=mixxx-deps-2.7-x64-windows-5777af9b + SET BUILDENV_SHA256=43ae7072a341417da0abb5fc5d893d1ccf38db0f73dd9e1fbd3d402f2d9deecc ) ) ELSE ( ECHO ^ERROR: Unsupported PLATFORM: %PLATFORM% From c1929304f39154e1163101169af618de40a4f51b Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 11:16:14 +0200 Subject: [PATCH 02/13] Increase minimum required CMake version according Qt requirements --- .github/workflows/benchmark.yml | 9 ++++----- .github/workflows/build.yml | 2 +- CMakeLists.txt | 3 ++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 8645e83f3c2..2a94328ca06 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -126,7 +126,7 @@ jobs: with: # This should always match the minimum required version in # our CMakeLists.txt - cmake-version: "3.21.x" + cmake-version: "3.22.x" - name: "[Windows] Set up cmake" uses: jwlawson/actions-setup-cmake@v2.2 @@ -134,10 +134,9 @@ jobs: # On windows-11-arm this action installs the x64 version which has unwanted side effects if: matrix.os == 'windows-2022' with: - # This is a workaround for a SSL false positive in cmake 3.26.4 - # When downloading the manual. 3.21 is required for installing the - # ANGLE Dlls via IMPORTED_RUNTIME_ARTIFACTS - cmake-version: "3.21.x" + # This is a workaround for a SSL false positive in cmake 3.26.4 when downloading the manual. + # 3.22 is required for Qt 6.10 https://doc.qt.io/qt-6.10/cmake-supported-cmake-versions.html + cmake-version: "3.22.x" - name: "[Windows] Set up MSVC Developer Command Prompt" if: runner.os == 'Windows' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a7e6220b835..e3b6b3af12d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -236,7 +236,7 @@ jobs: with: # This should always match the minimum required version in # our CMakeLists.txt - cmake-version: "3.21.x" + cmake-version: "3.22.x" - name: "[Windows] Set up cmake" uses: jwlawson/actions-setup-cmake@v2.2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 19cc227a9a2..d3b51798873 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_minimum_required(VERSION 3.21) +# Qt 6.10 requires minimum CMake 3.22: https://doc.qt.io/qt-6.10/cmake-supported-cmake-versions.html +cmake_minimum_required(VERSION 3.22) # lint_cmake: -readability/wonkycase message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}") From 64934d1ca69ff8b60527f05d676427ef077a52f5 Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 12:12:29 +0200 Subject: [PATCH 03/13] Rename FFMPEG to FFmpeg to match QtMultimedias requirements Remove lib prefix from FFmpeg CMake component names to match QtMultimedias requirements --- CMakeLists.txt | 49 ++++---- cmake/modules/FindFFMPEG.cmake | 202 -------------------------------- cmake/modules/FindFFmpeg.cmake | 207 +++++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+), 231 deletions(-) delete mode 100644 cmake/modules/FindFFMPEG.cmake create mode 100644 cmake/modules/FindFFmpeg.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d3b51798873..5853fefdb78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2765,51 +2765,42 @@ endif() # FFmpeg support # FFmpeg is multimedia library that can be found http://ffmpeg.org/ -find_package(FFMPEG COMPONENTS libavcodec libavformat libavutil libswresample) -default_option(FFMPEG "FFmpeg support (version 4.1.9 or later)" "FFMPEG_FOUND") -if(FFMPEG) - if(NOT FFMPEG_FOUND) - message(FATAL_ERROR "FFMPEG was not found") +find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE) +default_option(FFmpeg "FFmpeg support (version 4.1.9 or later)" "FFmpeg_FOUND") +if(FFmpeg) + if(NOT FFmpeg_FOUND) + message(FATAL_ERROR "FFmpeg was not found") endif() # Check minimum required versions # Minimum library versions according to # Windows: Version numbers are not available!? # macOS: Untested - if( - FFMPEG_libavcodec_VERSION - AND FFMPEG_libavcodec_VERSION VERSION_LESS 58.35.100 - ) + if(FFmpeg_AVCODEC_VERSION AND FFmpeg_AVCODEC_VERSION VERSION_LESS 58.35.100) message( FATAL_ERROR - "FFmpeg support requires at least version 58.35.100 of libavcodec (found: ${FFMPEG_libavcodec_VERSION})." + "FFmpeg support requires at least version 58.35.100 of libavcodec (found: ${FFmpeg_AVCODEC_VERSION})." ) endif() - if( - FFMPEG_libavformat_VERSION - AND FFMPEG_libavformat_VERSION VERSION_LESS 58.20.100 - ) + if(FFmpeg_AVFORMAT_VERSION AND FFmpeg_AVFORMAT_VERSION VERSION_LESS 58.20.100) message( FATAL_ERROR - "FFmpeg support requires at least version 58.20.100 of libavformat (found: ${FFMPEG_libavformat_VERSION})." + "FFmpeg support requires at least version 58.20.100 of libavformat (found: ${FFmpeg_AVFORMAT_VERSION})." ) endif() - if( - FFMPEG_libavutil_VERSION - AND FFMPEG_libavutil_VERSION VERSION_LESS 56.22.100 - ) + if(FFmpeg_AVUTIL_VERSION AND FFmpeg_AVUTIL_VERSION VERSION_LESS 56.22.100) message( FATAL_ERROR - "FFmpeg support requires at least version 56.22.100 of libavutil (found: ${FFMPEG_libavutil_VERSION})." + "FFmpeg support requires at least version 56.22.100 of libavutil (found: ${FFmpeg_AVUTIL_VERSION})." ) endif() if( - FFMPEG_libswresample_VERSION - AND FFMPEG_libswresample_VERSION VERSION_LESS 3.3.100 + FFmpeg_SWRESAMPLE_VERSION + AND FFmpeg_SWRESAMPLE_VERSION VERSION_LESS 3.3.100 ) message( FATAL_ERROR - "FFmpeg support requires at least version 3.3.100 of libswresample (found: ${FFMPEG_libswresample_VERSION})." + "FFmpeg support requires at least version 3.3.100 of libswresample (found: ${FFmpeg_SWRESAMPLE_VERSION})." ) endif() @@ -2817,21 +2808,21 @@ if(FFMPEG) target_compile_definitions( mixxx-lib PUBLIC - __FFMPEG__ + __FFmpeg__ # Needed to build new FFmpeg __STDC_CONSTANT_MACROS __STDC_LIMIT_MACROS __STDC_FORMAT_MACROS ) - target_link_libraries(mixxx-lib PRIVATE "${FFMPEG_LIBRARIES}") - target_include_directories(mixxx-lib PUBLIC "${FFMPEG_INCLUDE_DIRS}") + target_link_libraries(mixxx-lib PRIVATE "${FFmpeg_LIBRARIES}") + target_include_directories(mixxx-lib PUBLIC "${FFmpeg_INCLUDE_DIRS}") endif() # STEM file support -default_option(STEM "STEM file support" "FFMPEG_FOUND;FFMPEG") +default_option(STEM "STEM file support" "FFmpeg_FOUND;FFmpeg") if(STEM) - if(NOT FFMPEG) - message(FATAL_ERROR "STEM requires that also FFMPEG is enabled") + if(NOT FFmpeg) + message(FATAL_ERROR "STEM requires that also FFmpeg is enabled") endif() target_compile_definitions(mixxx-lib PUBLIC __STEM__) list(APPEND MIXXX_LIB_PRECOMPILED_HEADER src/track/steminfo.h) diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake deleted file mode 100644 index 55255cc30e2..00000000000 --- a/cmake/modules/FindFFMPEG.cmake +++ /dev/null @@ -1,202 +0,0 @@ -#.rst: -# FindFFMPEG -# ---------- -# -# Try to find the required ffmpeg components (default: libavformat, libavutil, libavcodec) -# -# Next variables can be used to hint FFMPEG libs search: -# -# :: -# -# PC__LIBRARY_DIRS -# PC_FFMPEG_LIBRARY_DIRS -# PC__INCLUDE_DIRS -# PC_FFMPEG_INCLUDE_DIRS -# -# Once done this will define -# -# :: -# -# FFMPEG_FOUND - System has the all required components. -# FFMPEG_INCLUDE_DIRS - Include directory necessary for using the required components headers. -# FFMPEG_LIBRARIES - Link these to use the required ffmpeg components. -# FFMPEG_DEFINITIONS - Compiler switches required for using the required ffmpeg components. -# -# For each of the components it will additionally set. -# -# :: -# -# libavcodec -# libavdevice -# libavformat -# libavfilter -# libavutil -# libswscale -# libswresample -# -# the following variables will be defined -# -# :: -# -# _FOUND - System has -# _INCLUDE_DIRS - Include directory necessary for using the headers -# _LIBRARIES - Link these to use -# _DEFINITIONS - Compiler switches required for using -# _VERSION - The components version -# -# the following import targets is created -# -# :: -# -# FFMPEG::FFMPEG - for all components -# FFMPEG:: - where in lower case (FFMPEG::avcodec) for each components -# -# Copyright (c) 2006, Matthias Kretz, -# Copyright (c) 2008, Alexander Neundorf, -# Copyright (c) 2011, Michael Jansen, -# Copyright (c) 2017, Alexander Drozdov, -# Copyright (c) 2019, Jan Holthuis, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -include(FindPackageHandleStandardArgs) - -# The default components were taken from a survey over other FindFFMPEG.cmake files -if(NOT FFMPEG_FIND_COMPONENTS) - set(FFMPEG_FIND_COMPONENTS libavcodec libavformat libavutil) -endif() - -# -### Macro: find_component -# -# Checks for the given component by invoking pkgconfig and then looking up the libraries and -# include directories. -# -macro(find_component component pkgconfig library header) - # use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls - find_package(PkgConfig QUIET) - if(PkgConfig_FOUND) - pkg_check_modules(PC_FFMPEG_${component} QUIET ${pkgconfig}) - endif() - - find_path( - FFMPEG_${component}_INCLUDE_DIRS - ${header} - HINTS - ${PC_FFMPEG_${component}_INCLUDEDIR} - ${PC_FFMPEG_${component}_INCLUDE_DIRS} - ${PC_FFMPEG_INCLUDE_DIRS} - PATH_SUFFIXES ffmpeg - ) - - find_library( - FFMPEG_${component}_LIBRARIES - NAMES ${PC_FFMPEG_${component}_LIBRARIES} ${library} - HINTS - ${PC_FFMPEG_${component}_LIBDIR} - ${PC_FFMPEG_${component}_LIBRARY_DIRS} - ${PC_FFMPEG_LIBRARY_DIRS} - ) - - #message(STATUS ${FFMPEG_${component}_LIBRARIES}) - #message(STATUS ${PC_FFMPEG_${component}_LIBRARIES}) - - set( - FFMPEG_${component}_DEFINITIONS - ${PC_FFMPEG_${component}_CFLAGS_OTHER} - CACHE STRING - "The ${component} CFLAGS." - ) - set( - FFMPEG_${component}_VERSION - ${PC_FFMPEG_${component}_VERSION} - CACHE STRING - "The ${component} version number." - ) - - if(FFMPEG_${component}_LIBRARIES AND FFMPEG_${component}_INCLUDE_DIRS) - message(STATUS " - ${component} ${FFMPEG_${component}_VERSION} found.") - set(FFMPEG_${component}_FOUND TRUE) - else() - message(STATUS " - ${component} not found.") - endif() - - mark_as_advanced( - FFMPEG_${component}_INCLUDE_DIRS - FFMPEG_${component}_LIBRARIES - FFMPEG_${component}_DEFINITIONS - FFMPEG_${component}_VERSION - ) -endmacro() - -message(STATUS "Searching for FFMPEG components") -# Check for all possible component. -find_component(libavcodec libavcodec avcodec libavcodec/avcodec.h) -find_component(libavformat libavformat avformat libavformat/avformat.h) -find_component(libavdevice libavdevice avdevice libavdevice/avdevice.h) -find_component(libavutil libavutil avutil libavutil/avutil.h) -find_component(libavfilter libavfilter avfilter libavfilter/avfilter.h) -find_component(libswscale libswscale swscale libswscale/swscale.h) -find_component(libswresample libswresample swresample libswresample/swresample.h) - -set(FFMPEG_LIBRARIES "") -set(FFMPEG_DEFINITIONS "") -# Check if the required components were found and add their stuff to the FFMPEG_* vars. -foreach(component ${FFMPEG_FIND_COMPONENTS}) - if(FFMPEG_${component}_FOUND) - #message(STATUS "Required component ${component} present.") - set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${FFMPEG_${component}_LIBRARIES}) - set( - FFMPEG_DEFINITIONS - ${FFMPEG_DEFINITIONS} - ${FFMPEG_${component}_DEFINITIONS} - ) - list(APPEND FFMPEG_INCLUDE_DIRS ${FFMPEG_${component}_INCLUDE_DIRS}) - endif() -endforeach() - -# Build the include path with duplicates removed. -if(FFMPEG_INCLUDE_DIRS) - list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS) -endif() - -# 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 -) - -mark_as_advanced(FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARIES FFMPEG_DEFINITIONS) - -# 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 - FFMPEG_${component}_LIBRARIES - FFMPEG_${component}_INCLUDE_DIRS - ) -endforeach() - -# Give a nice error message if some of the required vars are missing. -find_package_handle_standard_args(FFMPEG DEFAULT_MSG ${FFMPEG_REQUIRED_VARS}) diff --git a/cmake/modules/FindFFmpeg.cmake b/cmake/modules/FindFFmpeg.cmake new file mode 100644 index 00000000000..e8581b6a72c --- /dev/null +++ b/cmake/modules/FindFFmpeg.cmake @@ -0,0 +1,207 @@ +#.rst: +# FindFFmpeg +# ---------- +# +# Try to find the required ffmpeg components (default: libavformat, libavutil, libavcodec) +# +# Next variables can be used to hint FFmpeg libs search: +# +# :: +# +# PC__LIBRARY_DIRS +# PC_FFmpeg_LIBRARY_DIRS +# PC__INCLUDE_DIRS +# PC_FFmpeg_INCLUDE_DIRS +# +# Once done this will define +# +# :: +# +# FFmpeg_FOUND - System has the all required components. +# FFmpeg_INCLUDE_DIRS - Include directory necessary for using the required components headers. +# FFmpeg_LIBRARIES - Link these to use the required ffmpeg components. +# FFmpeg_DEFINITIONS - Compiler switches required for using the required ffmpeg components. +# +# For each of the components it will additionally set. +# +# :: +# +# libavcodec +# libavdevice +# libavformat +# libavfilter +# libavutil +# libswscale +# libswresample +# +# the following variables will be defined +# +# :: +# +# _FOUND - System has +# _INCLUDE_DIRS - Include directory necessary for using the headers +# _LIBRARIES - Link these to use +# _DEFINITIONS - Compiler switches required for using +# _VERSION - The components version +# +# the following import targets is created +# +# :: +# +# FFmpeg::FFmpeg - for all components +# FFmpeg:: - where in lower case (FFmpeg::avcodec) for each components +# +# Copyright (c) 2006, Matthias Kretz, +# Copyright (c) 2008, Alexander Neundorf, +# Copyright (c) 2011, Michael Jansen, +# Copyright (c) 2017, Alexander Drozdov, +# Copyright (c) 2019, Jan Holthuis, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +include(FindPackageHandleStandardArgs) + +# Qt-compliant component names (uppercase, no lib prefix): +# AVCODEC, AVFORMAT, AVDEVICE, AVUTIL, AVFILTER, SWSCALE, SWRESAMPLE +if(NOT FFmpeg_FIND_COMPONENTS) + set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL) +endif() + +# +### Macro: find_component +# +# Checks for the given component by invoking pkgconfig and then looking up +# the libraries and include directories. +# component - Qt-compliant uppercase name, e.g. AVCODEC +# pkgconfig - pkg-config module name, e.g. libavcodec +# library - library, e.g. avcodec +# header - header path, e.g. libavcodec/avcodec.h +# +macro(find_component component pkgconfig library header) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + find_package(PkgConfig QUIET) + if(PkgConfig_FOUND) + pkg_check_modules(PC_FFmpeg_${component} QUIET ${pkgconfig}) + endif() + + find_path( + FFmpeg_${component}_INCLUDE_DIRS + ${header} + HINTS + ${PC_FFmpeg_${component}_INCLUDEDIR} + ${PC_FFmpeg_${component}_INCLUDE_DIRS} + ${PC_FFmpeg_INCLUDE_DIRS} + PATH_SUFFIXES ffmpeg + ) + + find_library( + FFmpeg_${component}_LIBRARIES + NAMES ${PC_FFmpeg_${component}_LIBRARIES} ${library} + HINTS + ${PC_FFmpeg_${component}_LIBDIR} + ${PC_FFmpeg_${component}_LIBRARY_DIRS} + ${PC_FFmpeg_LIBRARY_DIRS} + ) + + #message(STATUS ${FFmpeg_${component}_LIBRARIES}) + #message(STATUS ${PC_FFmpeg_${component}_LIBRARIES}) + + set( + FFmpeg_${component}_DEFINITIONS + ${PC_FFmpeg_${component}_CFLAGS_OTHER} + CACHE STRING + "The ${component} CFLAGS." + ) + set( + FFmpeg_${component}_VERSION + ${PC_FFmpeg_${component}_VERSION} + CACHE STRING + "The ${component} version number." + ) + + if(FFmpeg_${component}_LIBRARIES AND FFmpeg_${component}_INCLUDE_DIRS) + message(STATUS " - ${component} ${FFmpeg_${component}_VERSION} found.") + set(FFmpeg_${component}_FOUND TRUE) + else() + message(STATUS " - ${component} not found.") + endif() + + mark_as_advanced( + FFmpeg_${component}_INCLUDE_DIRS + FFmpeg_${component}_LIBRARIES + FFmpeg_${component}_DEFINITIONS + FFmpeg_${component}_VERSION + ) +endmacro() + +message(STATUS "Searching for FFmpeg components") +# 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(SWRESAMPLE libswresample swresample libswresample/swresample.h) + +set(FFmpeg_LIBRARIES "") +set(FFmpeg_DEFINITIONS "") +# Check if the required components were found and add their stuff to the FFmpeg_* vars. +foreach(component ${FFmpeg_FIND_COMPONENTS}) + if(FFmpeg_${component}_FOUND) + #message(STATUS "Required component ${component} present.") + set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} ${FFmpeg_${component}_LIBRARIES}) + set( + FFmpeg_DEFINITIONS + ${FFmpeg_DEFINITIONS} + ${FFmpeg_${component}_DEFINITIONS} + ) + list(APPEND FFmpeg_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIRS}) + endif() +endforeach() + +# Build the include path with duplicates removed. +if(FFmpeg_INCLUDE_DIRS) + list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS) +endif() + +# 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 +) + +mark_as_advanced(FFmpeg_INCLUDE_DIRS FFmpeg_LIBRARIES FFmpeg_DEFINITIONS) + +# 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 + FFmpeg_${component}_LIBRARIES + FFmpeg_${component}_INCLUDE_DIRS + ) +endforeach() + +# Give a nice error message if some of the required vars are missing. +find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${FFmpeg_REQUIRED_VARS}) From 86ddd109a1c5f340cbae9e4f7afac69e3af0e40c Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 15:22:32 +0200 Subject: [PATCH 04/13] Create FFmpeg imported targets FFmpeg::avcodec, FFmpeg::avformat, FFmpeg::avutil, FFmpeg::swresample, FFmpeg::swscale --- cmake/modules/FindFFmpeg.cmake | 194 +++++++++++++++++++++++---------- 1 file changed, 138 insertions(+), 56 deletions(-) diff --git a/cmake/modules/FindFFmpeg.cmake b/cmake/modules/FindFFmpeg.cmake index e8581b6a72c..460f3493ea5 100644 --- a/cmake/modules/FindFFmpeg.cmake +++ b/cmake/modules/FindFFmpeg.cmake @@ -2,54 +2,58 @@ # FindFFmpeg # ---------- # -# Try to find the required ffmpeg components (default: libavformat, libavutil, libavcodec) +# Try to find the required FFmpeg components (default: AVCODEC, AVFORMAT, AVUTIL) # # Next variables can be used to hint FFmpeg libs search: # # :: # -# PC__LIBRARY_DIRS # PC_FFmpeg_LIBRARY_DIRS -# PC__INCLUDE_DIRS # PC_FFmpeg_INCLUDE_DIRS # # Once done this will define # # :: # -# FFmpeg_FOUND - System has the all required components. -# FFmpeg_INCLUDE_DIRS - Include directory necessary for using the required components headers. -# FFmpeg_LIBRARIES - Link these to use the required ffmpeg components. -# FFmpeg_DEFINITIONS - Compiler switches required for using the required ffmpeg components. +# FFmpeg_FOUND - System has all required components. +# FFmpeg_INCLUDE_DIRS - Include directories for all required components. +# FFmpeg_LIBRARIES - Libraries to link for all required components. +# FFmpeg_DEFINITIONS - Compiler switches required for using FFmpeg. # # For each of the components it will additionally set. # # :: # -# libavcodec -# libavdevice -# libavformat -# libavfilter -# libavutil -# libswscale -# libswresample +# FFmpeg__FOUND - System has +# FFmpeg__INCLUDE_DIRS - Include directories for +# FFmpeg__LIBRARIES - Libraries to link for +# FFmpeg__DEFINITIONS - Compiler switches for +# FFmpeg__VERSION - Version of # -# the following variables will be defined +# The following imported targets are created: # # :: # -# _FOUND - System has -# _INCLUDE_DIRS - Include directory necessary for using the headers -# _LIBRARIES - Link these to use -# _DEFINITIONS - Compiler switches required for using -# _VERSION - The components version +# FFmpeg::FFmpeg - interface target aggregating all found components +# FFmpeg::avcodec - libavcodec +# FFmpeg::avformat - libavformat +# FFmpeg::avdevice - libavdevice +# FFmpeg::avutil - libavutil +# FFmpeg::avfilter - libavfilter +# FFmpeg::swscale - libswscale +# FFmpeg::swresample - libswresample # -# the following import targets is created +# Component names are Qt-compliant uppercase (AVCODEC, AVFORMAT, …) as +# required by Qt6's internal find_dependency() calls in +# Qt6FFmpegMediaPluginImplPrivateDependencies.cmake: # -# :: +# find_dependency(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE SWSCALE) +# +# Imported target names are lowercase (FFmpeg::avcodec, …) as listed in +# Qt6FFmpegMediaPluginImplPrivateDependencies.cmake: # -# FFmpeg::FFmpeg - for all components -# FFmpeg:: - where in lower case (FFmpeg::avcodec) for each components +# provided_targets "FFmpeg::avcodec;FFmpeg::avformat;FFmpeg::avutil; +# FFmpeg::swresample;FFmpeg::swscale" # # Copyright (c) 2006, Matthias Kretz, # Copyright (c) 2008, Alexander Neundorf, @@ -62,33 +66,60 @@ include(FindPackageHandleStandardArgs) -# Qt-compliant component names (uppercase, no lib prefix): -# AVCODEC, AVFORMAT, AVDEVICE, AVUTIL, AVFILTER, SWSCALE, SWRESAMPLE +# Default components when none are requested if(NOT FFmpeg_FIND_COMPONENTS) set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL) endif() +# Maps uppercase component name → lowercase library stem (used for both the +# imported target suffix and the pkg-config / find_library name) +set(_FFmpeg_AVCODEC_lower avcodec) +set(_FFmpeg_AVFORMAT_lower avformat) +set(_FFmpeg_AVDEVICE_lower avdevice) +set(_FFmpeg_AVUTIL_lower avutil) +set(_FFmpeg_AVFILTER_lower avfilter) +set(_FFmpeg_SWSCALE_lower swscale) +set(_FFmpeg_SWRESAMPLE_lower swresample) + +# Maps uppercase component name → pkg-config module name +set(_FFmpeg_AVCODEC_pkgconfig libavcodec) +set(_FFmpeg_AVFORMAT_pkgconfig libavformat) +set(_FFmpeg_AVDEVICE_pkgconfig libavdevice) +set(_FFmpeg_AVUTIL_pkgconfig libavutil) +set(_FFmpeg_AVFILTER_pkgconfig libavfilter) +set(_FFmpeg_SWSCALE_pkgconfig libswscale) +set(_FFmpeg_SWRESAMPLE_pkgconfig libswresample) + +# Maps uppercase component name → primary header +set(_FFmpeg_AVCODEC_header libavcodec/avcodec.h) +set(_FFmpeg_AVFORMAT_header libavformat/avformat.h) +set(_FFmpeg_AVDEVICE_header libavdevice/avdevice.h) +set(_FFmpeg_AVUTIL_header libavutil/avutil.h) +set(_FFmpeg_AVFILTER_header libavfilter/avfilter.h) +set(_FFmpeg_SWSCALE_header libswscale/swscale.h) +set(_FFmpeg_SWRESAMPLE_header libswresample/swresample.h) + # ### Macro: find_component # # Checks for the given component by invoking pkgconfig and then looking up # the libraries and include directories. -# component - Qt-compliant uppercase name, e.g. AVCODEC -# pkgconfig - pkg-config module name, e.g. libavcodec -# library - library, e.g. avcodec -# header - header path, e.g. libavcodec/avcodec.h -# -macro(find_component component pkgconfig library header) - # use pkg-config to get the directories and then use these values - # in the FIND_PATH() and FIND_LIBRARY() calls +# +# component - uppercase Qt-compliant name, e.g. AVCODEC +# +macro(find_component component) + set(_lower "${_FFmpeg_${component}_lower}") + set(_pkgcfg "${_FFmpeg_${component}_pkgconfig}") + set(_header "${_FFmpeg_${component}_header}") + find_package(PkgConfig QUIET) if(PkgConfig_FOUND) - pkg_check_modules(PC_FFmpeg_${component} QUIET ${pkgconfig}) + pkg_check_modules(PC_FFmpeg_${component} QUIET ${_pkgcfg}) endif() find_path( FFmpeg_${component}_INCLUDE_DIRS - ${header} + ${_header} HINTS ${PC_FFmpeg_${component}_INCLUDEDIR} ${PC_FFmpeg_${component}_INCLUDE_DIRS} @@ -98,16 +129,13 @@ macro(find_component component pkgconfig library header) find_library( FFmpeg_${component}_LIBRARIES - NAMES ${PC_FFmpeg_${component}_LIBRARIES} ${library} + NAMES ${PC_FFmpeg_${component}_LIBRARIES} ${_lower} HINTS ${PC_FFmpeg_${component}_LIBDIR} ${PC_FFmpeg_${component}_LIBRARY_DIRS} ${PC_FFmpeg_LIBRARY_DIRS} ) - #message(STATUS ${FFmpeg_${component}_LIBRARIES}) - #message(STATUS ${PC_FFmpeg_${component}_LIBRARIES}) - set( FFmpeg_${component}_DEFINITIONS ${PC_FFmpeg_${component}_CFLAGS_OTHER} @@ -134,30 +162,29 @@ macro(find_component component pkgconfig library header) FFmpeg_${component}_DEFINITIONS FFmpeg_${component}_VERSION ) + + unset(_lower) + unset(_pkgcfg) + unset(_header) endmacro() message(STATUS "Searching for FFmpeg components") -# 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(SWRESAMPLE libswresample swresample libswresample/swresample.h) +find_component(AVCODEC) +find_component(AVFORMAT) +find_component(AVDEVICE) +find_component(AVUTIL) +find_component(AVFILTER) +find_component(SWSCALE) +find_component(SWRESAMPLE) +# Aggregate libraries, definitions and include dirs from requested components set(FFmpeg_LIBRARIES "") set(FFmpeg_DEFINITIONS "") -# Check if the required components were found and add their stuff to the FFmpeg_* vars. +set(FFmpeg_INCLUDE_DIRS "") foreach(component ${FFmpeg_FIND_COMPONENTS}) if(FFmpeg_${component}_FOUND) - #message(STATUS "Required component ${component} present.") - set(FFmpeg_LIBRARIES ${FFmpeg_LIBRARIES} ${FFmpeg_${component}_LIBRARIES}) - set( - FFmpeg_DEFINITIONS - ${FFmpeg_DEFINITIONS} - ${FFmpeg_${component}_DEFINITIONS} - ) + list(APPEND FFmpeg_LIBRARIES ${FFmpeg_${component}_LIBRARIES}) + list(APPEND FFmpeg_DEFINITIONS ${FFmpeg_${component}_DEFINITIONS}) list(APPEND FFmpeg_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIRS}) endif() endforeach() @@ -205,3 +232,58 @@ endforeach() # Give a nice error message if some of the required vars are missing. find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${FFmpeg_REQUIRED_VARS}) + +# --------------------------------------------------------------------------- +# Create IMPORTED targets +# +# Qt6FFmpegMediaPluginImplPrivateDependencies.cmake (same content on both +# macOS and Windows) specifies exactly: +# +# provided_targets: +# "FFmpeg::avcodec;FFmpeg::avformat;FFmpeg::avutil; +# FFmpeg::swresample;FFmpeg::swscale" +# +# These targets MUST exist after find_package(FFmpeg) returns, otherwise +# vcpkg's _add_executable wrapper rejects any target that transitively +# links against them. +# --------------------------------------------------------------------------- +if(FFmpeg_FOUND) + foreach( + component + AVCODEC + AVFORMAT + AVDEVICE + AVUTIL + AVFILTER + SWSCALE + SWRESAMPLE + ) + if(FFmpeg_${component}_FOUND) + set(_target "FFmpeg::${_FFmpeg_${component}_lower}") + if(NOT TARGET ${_target}) + add_library(${_target} UNKNOWN IMPORTED) + set_target_properties( + ${_target} + PROPERTIES + IMPORTED_LOCATION "${FFmpeg_${component}_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${FFmpeg_${component}_INCLUDE_DIRS}" + INTERFACE_COMPILE_OPTIONS "${FFmpeg_${component}_DEFINITIONS}" + ) + endif() + unset(_target) + endif() + endforeach() + + # Aggregate interface target for convenience + if(NOT TARGET FFmpeg::FFmpeg) + add_library(FFmpeg::FFmpeg INTERFACE IMPORTED) + foreach(component ${FFmpeg_FIND_COMPONENTS}) + if(FFmpeg_${component}_FOUND) + target_link_libraries( + FFmpeg::FFmpeg + INTERFACE "FFmpeg::${_FFmpeg_${component}_lower}" + ) + endif() + endforeach() + endif() +endif() From 48b2d10cd241f91adb5fbe2e5ba11fe88de3603b Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 16:12:51 +0200 Subject: [PATCH 05/13] Add FindFdkAac.cmake --- CMakeLists.txt | 33 +++-- cmake/modules/FindFFmpeg.cmake | 236 ++++++++++++++++++++------------- cmake/modules/FindFdkAac.cmake | 118 +++++++++++++++++ 3 files changed, 281 insertions(+), 106 deletions(-) create mode 100644 cmake/modules/FindFdkAac.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5853fefdb78..844de96cb05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2814,7 +2814,8 @@ if(FFmpeg) __STDC_LIMIT_MACROS __STDC_FORMAT_MACROS ) - target_link_libraries(mixxx-lib PRIVATE "${FFmpeg_LIBRARIES}") + + target_link_libraries(mixxx-lib PRIVATE FFmpeg::FFmpeg) target_include_directories(mixxx-lib PUBLIC "${FFmpeg_INCLUDE_DIRS}") endif() @@ -4845,12 +4846,12 @@ endif() # FDK-AAC is loaded dynamically at runtime by EncoderFdkAac using QLibrary, # so copy it into the Windows and macOS packages, but do not link to it. -if(APPLE AND MACOS_BUNDLE) - find_library(FDK_AAC_LIBRARY fdk-aac) - if(FDK_AAC_LIBRARY) - message(STATUS "Found fdk-aac: ${FDK_AAC_LIBRARY}") +find_package(FdkAac QUIET) +if(FdkAac_FOUND) + if(APPLE AND MACOS_BUNDLE) + message(STATUS "Found fdk-aac: ${FdkAac_LIBRARY}") file( - COPY ${FDK_AAC_LIBRARY} + COPY "${FdkAac_LIBRARY}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/lib/fdk-aac-install" FOLLOW_SYMLINK_CHAIN ) @@ -4858,18 +4859,16 @@ if(APPLE AND MACOS_BUNDLE) DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib/fdk-aac-install/" DESTINATION "${MIXXX_INSTALL_PREFIX}/Contents/Frameworks" ) - else() - message(STATUS "Could NOT find libfdk-aac.dylib") - endif() -elseif(WIN32) - # On Windows find_library finds the .lib file, but the installer needs the .dll file. - find_file(FDK_AAC_DLL fdk-aac.dll PATH_SUFFIXES ${CMAKE_INSTALL_BINDIR}) - if(FDK_AAC_DLL) - message(STATUS "Found fdk-aac DLL: ${FDK_AAC_DLL}") - install(FILES ${FDK_AAC_DLL} DESTINATION ${MIXXX_INSTALL_BINDIR}) - else() - message(STATUS "Could NOT find fdk-aac.dll") + elseif(WIN32) + if(FdkAac_DLL) + message(STATUS "Found fdk-aac DLL: ${FdkAac_DLL}") + install(FILES "${FdkAac_DLL}" DESTINATION "${MIXXX_INSTALL_BINDIR}") + else() + message(STATUS "Could NOT find fdk-aac.dll (FdkAac_DLL not set)") + endif() endif() +else() + message(STATUS "Could NOT find fdk-aac (FdkAac_FOUND is FALSE)") endif() # Google PerfTools diff --git a/cmake/modules/FindFFmpeg.cmake b/cmake/modules/FindFFmpeg.cmake index 460f3493ea5..725d19b8d63 100644 --- a/cmake/modules/FindFFmpeg.cmake +++ b/cmake/modules/FindFFmpeg.cmake @@ -65,54 +65,55 @@ # For details see the accompanying COPYING-CMAKE-SCRIPTS file. include(FindPackageHandleStandardArgs) +include(IsStaticLibrary) + +# Early-return guard: Qt6's find_dependency() chain calls find_package(FFmpeg) +# once per multimedia plugin. Imported targets are global and persistent, so +# if FFmpeg::avcodec already exists the search is done — return silently. +if(TARGET FFmpeg::avcodec) + set(FFmpeg_FOUND TRUE) + return() +endif() -# Default components when none are requested if(NOT FFmpeg_FIND_COMPONENTS) set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL) endif() -# Maps uppercase component name → lowercase library stem (used for both the -# imported target suffix and the pkg-config / find_library name) -set(_FFmpeg_AVCODEC_lower avcodec) -set(_FFmpeg_AVFORMAT_lower avformat) -set(_FFmpeg_AVDEVICE_lower avdevice) -set(_FFmpeg_AVUTIL_lower avutil) -set(_FFmpeg_AVFILTER_lower avfilter) -set(_FFmpeg_SWSCALE_lower swscale) -set(_FFmpeg_SWRESAMPLE_lower swresample) - -# Maps uppercase component name → pkg-config module name -set(_FFmpeg_AVCODEC_pkgconfig libavcodec) -set(_FFmpeg_AVFORMAT_pkgconfig libavformat) -set(_FFmpeg_AVDEVICE_pkgconfig libavdevice) -set(_FFmpeg_AVUTIL_pkgconfig libavutil) -set(_FFmpeg_AVFILTER_pkgconfig libavfilter) -set(_FFmpeg_SWSCALE_pkgconfig libswscale) -set(_FFmpeg_SWRESAMPLE_pkgconfig libswresample) +# Component table: UPPERCASE lowercase-stem pkg-config-name primary-header +set( + _FFmpeg_components + "AVCODEC avcodec libavcodec libavcodec/avcodec.h" + "AVFORMAT avformat libavformat libavformat/avformat.h" + "AVDEVICE avdevice libavdevice libavdevice/avdevice.h" + "AVUTIL avutil libavutil libavutil/avutil.h" + "AVFILTER avfilter libavfilter libavfilter/avfilter.h" + "SWSCALE swscale libswscale libswscale/swscale.h" + "SWRESAMPLE swresample libswresample libswresample/swresample.h" +) +foreach(_entry IN LISTS _FFmpeg_components) + separate_arguments(_fields UNIX_COMMAND "${_entry}") + list(GET _fields 0 _uc) + list(GET _fields 1 _lc) + list(GET _fields 2 _pc) + list(GET _fields 3 _hdr) + set(_FFmpeg_${_uc}_lower "${_lc}") + set(_FFmpeg_${_uc}_pkgconfig "${_pc}") + set(_FFmpeg_${_uc}_header "${_hdr}") +endforeach() +unset(_entry) +unset(_fields) +unset(_uc) +unset(_lc) +unset(_pc) +unset(_hdr) -# Maps uppercase component name → primary header -set(_FFmpeg_AVCODEC_header libavcodec/avcodec.h) -set(_FFmpeg_AVFORMAT_header libavformat/avformat.h) -set(_FFmpeg_AVDEVICE_header libavdevice/avdevice.h) -set(_FFmpeg_AVUTIL_header libavutil/avutil.h) -set(_FFmpeg_AVFILTER_header libavfilter/avfilter.h) -set(_FFmpeg_SWSCALE_header libswscale/swscale.h) -set(_FFmpeg_SWRESAMPLE_header libswresample/swresample.h) +find_package(PkgConfig QUIET) -# -### Macro: find_component -# -# Checks for the given component by invoking pkgconfig and then looking up -# the libraries and include directories. -# -# component - uppercase Qt-compliant name, e.g. AVCODEC -# macro(find_component component) set(_lower "${_FFmpeg_${component}_lower}") set(_pkgcfg "${_FFmpeg_${component}_pkgconfig}") set(_header "${_FFmpeg_${component}_header}") - find_package(PkgConfig QUIET) if(PkgConfig_FOUND) pkg_check_modules(PC_FFmpeg_${component} QUIET ${_pkgcfg}) endif() @@ -126,7 +127,6 @@ macro(find_component component) ${PC_FFmpeg_INCLUDE_DIRS} PATH_SUFFIXES ffmpeg ) - find_library( FFmpeg_${component}_LIBRARIES NAMES ${PC_FFmpeg_${component}_LIBRARIES} ${_lower} @@ -135,7 +135,6 @@ macro(find_component component) ${PC_FFmpeg_${component}_LIBRARY_DIRS} ${PC_FFmpeg_LIBRARY_DIRS} ) - set( FFmpeg_${component}_DEFINITIONS ${PC_FFmpeg_${component}_CFLAGS_OTHER} @@ -148,14 +147,6 @@ macro(find_component component) CACHE STRING "The ${component} version number." ) - - if(FFmpeg_${component}_LIBRARIES AND FFmpeg_${component}_INCLUDE_DIRS) - message(STATUS " - ${component} ${FFmpeg_${component}_VERSION} found.") - set(FFmpeg_${component}_FOUND TRUE) - else() - message(STATUS " - ${component} not found.") - endif() - mark_as_advanced( FFmpeg_${component}_INCLUDE_DIRS FFmpeg_${component}_LIBRARIES @@ -163,21 +154,33 @@ macro(find_component component) FFmpeg_${component}_VERSION ) + if(FFmpeg_${component}_LIBRARIES AND FFmpeg_${component}_INCLUDE_DIRS) + message(STATUS " - ${component} ${FFmpeg_${component}_VERSION} found.") + set(FFmpeg_${component}_FOUND TRUE) + else() + message(STATUS " - ${component} not found.") + endif() unset(_lower) unset(_pkgcfg) unset(_header) endmacro() message(STATUS "Searching for FFmpeg components") -find_component(AVCODEC) -find_component(AVFORMAT) -find_component(AVDEVICE) -find_component(AVUTIL) -find_component(AVFILTER) -find_component(SWSCALE) -find_component(SWRESAMPLE) +foreach( + _comp + AVCODEC + AVFORMAT + AVDEVICE + AVUTIL + AVFILTER + SWSCALE + SWRESAMPLE +) + find_component(${_comp}) +endforeach() +unset(_comp) -# Aggregate libraries, definitions and include dirs from requested components +# Aggregate results for requested components set(FFmpeg_LIBRARIES "") set(FFmpeg_DEFINITIONS "") set(FFmpeg_INCLUDE_DIRS "") @@ -188,25 +191,21 @@ foreach(component ${FFmpeg_FIND_COMPONENTS}) list(APPEND FFmpeg_INCLUDE_DIRS ${FFmpeg_${component}_INCLUDE_DIRS}) endif() endforeach() +list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS) -# Build the include path with duplicates removed. -if(FFmpeg_INCLUDE_DIRS) - list(REMOVE_DUPLICATES FFmpeg_INCLUDE_DIRS) -endif() - -# cache the vars. +# Cache aggregates (consumed by CMakeLists.txt via "${FFmpeg_LIBRARIES}") set( - FFmpeg_INCLUDE_DIRS - ${FFmpeg_INCLUDE_DIRS} + FFmpeg_LIBRARIES + ${FFmpeg_LIBRARIES} CACHE STRING - "The FFmpeg include directories." + "The FFmpeg libraries." FORCE ) set( - FFmpeg_LIBRARIES - ${FFmpeg_LIBRARIES} + FFmpeg_INCLUDE_DIRS + ${FFmpeg_INCLUDE_DIRS} CACHE STRING - "The FFmpeg libraries." + "The FFmpeg include directories." FORCE ) set( @@ -216,38 +215,23 @@ set( "The FFmpeg cflags." FORCE ) +mark_as_advanced(FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS FFmpeg_DEFINITIONS) -mark_as_advanced(FFmpeg_INCLUDE_DIRS FFmpeg_LIBRARIES FFmpeg_DEFINITIONS) - -# Compile the list of required vars -set(FFmpeg_REQUIRED_VARS FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS) +# Build required-vars list from requested components +set(_FFmpeg_required FFmpeg_LIBRARIES FFmpeg_INCLUDE_DIRS) foreach(component ${FFmpeg_FIND_COMPONENTS}) list( APPEND - FFmpeg_REQUIRED_VARS + _FFmpeg_required FFmpeg_${component}_LIBRARIES FFmpeg_${component}_INCLUDE_DIRS ) endforeach() +find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${_FFmpeg_required}) +unset(_FFmpeg_required) -# Give a nice error message if some of the required vars are missing. -find_package_handle_standard_args(FFmpeg DEFAULT_MSG ${FFmpeg_REQUIRED_VARS}) - -# --------------------------------------------------------------------------- -# Create IMPORTED targets -# -# Qt6FFmpegMediaPluginImplPrivateDependencies.cmake (same content on both -# macOS and Windows) specifies exactly: -# -# provided_targets: -# "FFmpeg::avcodec;FFmpeg::avformat;FFmpeg::avutil; -# FFmpeg::swresample;FFmpeg::swscale" -# -# These targets MUST exist after find_package(FFmpeg) returns, otherwise -# vcpkg's _add_executable wrapper rejects any target that transitively -# links against them. -# --------------------------------------------------------------------------- if(FFmpeg_FOUND) + # Create per-component IMPORTED targets foreach( component AVCODEC @@ -274,7 +258,81 @@ if(FFmpeg_FOUND) endif() endforeach() - # Aggregate interface target for convenience + # When libavcodec is static it may have been built with --enable-libfdk-aac. + # Add FdkAac::FdkAac as a transitive dep so the final linker resolves the + # aacEnc*/aacDec* symbols (mirrors FindChromaprint.cmake's FFTW3 pattern). + if(TARGET FFmpeg::avcodec) + is_static_library(_avcodec_static FFmpeg::avcodec) + if(_avcodec_static) + find_package(FdkAac QUIET) + if(FdkAac_FOUND) + set_property( + TARGET FFmpeg::avcodec + APPEND + PROPERTY INTERFACE_LINK_LIBRARIES FdkAac::FdkAac + ) + # Also append to the cached FFmpeg_LIBRARIES variable so any remaining + # consumers that use "${FFmpeg_LIBRARIES}" directly (e.g. legacy call + # sites) also get the dependency resolved. + list(APPEND FFmpeg_LIBRARIES ${FdkAac_LIBRARY}) + set( + FFmpeg_LIBRARIES + ${FFmpeg_LIBRARIES} + CACHE STRING + "The FFmpeg libraries." + FORCE + ) + endif() + endif() + unset(_avcodec_static) + endif() + + # On Apple platforms the static FFmpeg libraries reference VideoToolbox, + # CoreMedia and CoreVideo symbols (e.g. av_map_videotoolbox_format_to_pixfmt + # in libavutil, hardware-accelerated codecs in libavcodec). Add the + # required frameworks as transitive interface deps on the affected targets. + if(APPLE) + foreach(_component_target IN ITEMS FFmpeg::avcodec FFmpeg::avutil) + if(TARGET ${_component_target}) + is_static_library(_is_static ${_component_target}) + if(_is_static) + set_property( + TARGET ${_component_target} + APPEND + PROPERTY + INTERFACE_LINK_LIBRARIES + "-framework VideoToolbox" + "-framework CoreMedia" + "-framework CoreVideo" + ) + endif() + unset(_is_static) + endif() + endforeach() + unset(_component_target) + + # Also append to FFmpeg_LIBRARIES for legacy consumers + is_static_library(_avutil_static FFmpeg::avutil) + if(_avutil_static) + list( + APPEND + FFmpeg_LIBRARIES + "-framework VideoToolbox" + "-framework CoreMedia" + "-framework CoreVideo" + ) + set( + FFmpeg_LIBRARIES + ${FFmpeg_LIBRARIES} + CACHE STRING + "The FFmpeg libraries." + FORCE + ) + endif() + unset(_avutil_static) + endif() + + # Aggregate convenience target if(NOT TARGET FFmpeg::FFmpeg) add_library(FFmpeg::FFmpeg INTERFACE IMPORTED) foreach(component ${FFmpeg_FIND_COMPONENTS}) diff --git a/cmake/modules/FindFdkAac.cmake b/cmake/modules/FindFdkAac.cmake new file mode 100644 index 00000000000..463d6944a08 --- /dev/null +++ b/cmake/modules/FindFdkAac.cmake @@ -0,0 +1,118 @@ +#[=======================================================================[.rst: +FindFdkAac +---------- + +Finds the Fraunhofer FDK AAC library (libfdk-aac). + +FDK-AAC is used in two distinct ways in Mixxx: + +1. **Runtime dynamic loading** (``EncoderFdkAac`` via ``QLibrary``) — the + shared library is bundled into the macOS/Windows packages but never + linked at build time. + +2. **Transitive static dependency of FFmpeg** — when FFmpeg's + ``libavcodec.a`` is built with ``--enable-libfdk-aac`` the FDK-AAC + symbols must be satisfied at final link time. ``FindFFmpeg.cmake`` + calls this module and attaches ``FdkAac::FdkAac`` as a transitive + dependency of the ``FFmpeg::avcodec`` imported target whenever + ``libavcodec`` is a static library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +``FdkAac::FdkAac`` + The FDK-AAC library. + +Result Variables +^^^^^^^^^^^^^^^^ + +``FdkAac_FOUND`` + True if the system has the FDK-AAC library. +``FdkAac_INCLUDE_DIRS`` + Include directories needed to use FDK-AAC (may be empty when headers + are absent — only required when compiling against FDK-AAC directly). +``FdkAac_DLL`` + (Windows only) Full path to ``fdk-aac.dll``, suitable for install(). + +Cache Variables +^^^^^^^^^^^^^^^ + +``FdkAac_INCLUDE_DIR`` + The directory containing ``fdk-aac/aacenc_lib.h`` (optional). +``FdkAac_LIBRARY`` + The FDK-AAC link library (``.dylib`` / ``.so`` / ``.a`` / ``.lib``). +``FdkAac_DLL`` + (Windows only) Path to ``fdk-aac.dll``. + +#]=======================================================================] + +find_package(PkgConfig QUIET) +if(PkgConfig_FOUND) + pkg_check_modules(PC_FdkAac QUIET fdk-aac) +endif() + +find_path( + FdkAac_INCLUDE_DIR + NAMES fdk-aac/aacenc_lib.h + HINTS ${PC_FdkAac_INCLUDE_DIRS} + DOC "FDK-AAC include directory (optional)" +) +mark_as_advanced(FdkAac_INCLUDE_DIR) + +find_library( + FdkAac_LIBRARY + NAMES fdk-aac libfdk-aac + HINTS ${PC_FdkAac_LIBRARY_DIRS} + DOC "FDK-AAC link library" +) +mark_as_advanced(FdkAac_LIBRARY) + +# On Windows find_library() returns the .lib import library. +# Locate the companion .dll separately so callers can install it. +if(WIN32) + find_file( + FdkAac_DLL + NAMES fdk-aac.dll + HINTS ${PC_FdkAac_LIBRARY_DIRS} + PATH_SUFFIXES ${CMAKE_INSTALL_BINDIR} bin + DOC "FDK-AAC DLL (Windows runtime)" + ) + mark_as_advanced(FdkAac_DLL) +endif() + +include(FindPackageHandleStandardArgs) +# Only the library is required. Headers are optional: on Android the library +# is a transitive static dep of libavcodec.a and no Mixxx code includes +# FDK-AAC headers directly, so the include dir may legitimately be absent. +find_package_handle_standard_args( + FdkAac + REQUIRED_VARS FdkAac_LIBRARY + VERSION_VAR PC_FdkAac_VERSION +) + +if(FdkAac_FOUND AND NOT TARGET FdkAac::FdkAac) + # FdkAac_INCLUDE_DIRS: empty string when headers not present — callers must + # not assume non-empty (Android links transitively; no headers needed). + set(FdkAac_INCLUDE_DIRS "${FdkAac_INCLUDE_DIR}") + + add_library(FdkAac::FdkAac UNKNOWN IMPORTED) + set_target_properties( + FdkAac::FdkAac + PROPERTIES IMPORTED_LOCATION "${FdkAac_LIBRARY}" + ) + if(FdkAac_INCLUDE_DIR) + set_target_properties( + FdkAac::FdkAac + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FdkAac_INCLUDE_DIR}" + ) + endif() + if(WIN32 AND FdkAac_DLL) + # Expose the DLL as the runtime artifact; the .lib is the link artifact. + set_target_properties( + FdkAac::FdkAac + PROPERTIES + IMPORTED_LOCATION "${FdkAac_DLL}" + IMPORTED_IMPLIB "${FdkAac_LIBRARY}" + ) + endif() +endif() From 6c234345eeb5d07594c784cceb3f8609c69d8112 Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 18:53:38 +0200 Subject: [PATCH 06/13] Apple videotoolbox --- CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 844de96cb05..168e1d0b0c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2816,7 +2816,19 @@ if(FFmpeg) ) target_link_libraries(mixxx-lib PRIVATE FFmpeg::FFmpeg) + target_include_directories(mixxx-lib PUBLIC "${FFmpeg_INCLUDE_DIRS}") + # Qt6's FFmpeg multimedia plugin (libQt6FFmpegMediaPluginImpl.a) references + # Apple VideoToolbox symbols. + if(APPLE) + target_link_libraries( + mixxx-lib + PRIVATE + "-framework VideoToolbox" + "-framework CoreMedia" + "-framework CoreVideo" + ) + endif() endif() # STEM file support From 830265cc00ca0283f709e7b6af5230fc358348a2 Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 19:25:58 +0200 Subject: [PATCH 07/13] Fix FFmpeg preprocessor flag case --- CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 168e1d0b0c6..2f195163a55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2766,8 +2766,8 @@ endif() # FFmpeg support # FFmpeg is multimedia library that can be found http://ffmpeg.org/ find_package(FFmpeg COMPONENTS AVCODEC AVFORMAT AVUTIL SWRESAMPLE) -default_option(FFmpeg "FFmpeg support (version 4.1.9 or later)" "FFmpeg_FOUND") -if(FFmpeg) +default_option(FFMPEG "FFmpeg support (version 4.1.9 or later)" "FFmpeg_FOUND") +if(FFMPEG) if(NOT FFmpeg_FOUND) message(FATAL_ERROR "FFmpeg was not found") endif() @@ -2808,7 +2808,7 @@ if(FFmpeg) target_compile_definitions( mixxx-lib PUBLIC - __FFmpeg__ + __FFMPEG__ # Needed to build new FFmpeg __STDC_CONSTANT_MACROS __STDC_LIMIT_MACROS @@ -2832,9 +2832,9 @@ if(FFmpeg) endif() # STEM file support -default_option(STEM "STEM file support" "FFmpeg_FOUND;FFmpeg") +default_option(STEM "STEM file support" "FFmpeg_FOUND;FFMPEG") if(STEM) - if(NOT FFmpeg) + if(NOT FFMPEG) message(FATAL_ERROR "STEM requires that also FFmpeg is enabled") endif() target_compile_definitions(mixxx-lib PUBLIC __STEM__) From 5aada58682858c596628055c3993fe12086de797 Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 19:54:20 +0200 Subject: [PATCH 08/13] -force_load ${FFmpeg_AVUTIL_LIBRARIES}" --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f195163a55..5f4a4a0e610 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2820,10 +2820,11 @@ if(FFMPEG) target_include_directories(mixxx-lib PUBLIC "${FFmpeg_INCLUDE_DIRS}") # Qt6's FFmpeg multimedia plugin (libQt6FFmpegMediaPluginImpl.a) references # Apple VideoToolbox symbols. - if(APPLE) + if(APPLE AND FFmpeg_AVUTIL_LIBRARIES) target_link_libraries( - mixxx-lib + mixxx PRIVATE + "-force_load ${FFmpeg_AVUTIL_LIBRARIES}" "-framework VideoToolbox" "-framework CoreMedia" "-framework CoreVideo" From 12838171518ec74734b4f20117614171ee1a808e Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 20:38:55 +0200 Subject: [PATCH 09/13] Adapt Antoines taglibtest fix from 4880a76dbb140b8ab52070f5057fb5170403eb3a --- src/test/taglibtest.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/test/taglibtest.cpp b/src/test/taglibtest.cpp index 5dbe57a7e7c..b32b735e3d8 100644 --- a/src/test/taglibtest.cpp +++ b/src/test/taglibtest.cpp @@ -91,7 +91,9 @@ TEST_F(TagLibTest, WriteID3v2TagViaLink) { auto linkFileInfoBefore = QFileInfo(linkFileName); EXPECT_TRUE(linkFileInfoBefore.exists()); EXPECT_TRUE(linkFileInfoBefore.isSymLink()); - EXPECT_EQ(linkFileInfoBefore.canonicalFilePath().toStdString(), tmpFileName.toStdString()); + auto canonicalTmpFileName = QFileInfo(tmpFileName).canonicalFilePath(); + EXPECT_EQ(linkFileInfoBefore.canonicalFilePath().toStdString(), + canonicalTmpFileName.toStdString()); // Verify that the file has no tags { @@ -127,7 +129,8 @@ TEST_F(TagLibTest, WriteID3v2TagViaLink) { auto linkFileInfoAfter = QFileInfo(linkFileName); EXPECT_TRUE(linkFileInfoAfter.exists()); - EXPECT_EQ(linkFileInfoAfter.canonicalFilePath().toStdString(), tmpFileName.toStdString()); + EXPECT_EQ(linkFileInfoAfter.canonicalFilePath().toStdString(), + canonicalTmpFileName.toStdString()); EXPECT_TRUE(linkFileInfoAfter.isSymLink()); } #endif From 89d9a386e966d06c2ee5aadb1ce980666788d165 Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 21:25:28 +0200 Subject: [PATCH 10/13] CrossCompile macOS fix --- CMakeLists.txt | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f4a4a0e610..10d8599148d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2816,19 +2816,34 @@ if(FFMPEG) ) target_link_libraries(mixxx-lib PRIVATE FFmpeg::FFmpeg) - target_include_directories(mixxx-lib PUBLIC "${FFmpeg_INCLUDE_DIRS}") - # Qt6's FFmpeg multimedia plugin (libQt6FFmpegMediaPluginImpl.a) references - # Apple VideoToolbox symbols. - if(APPLE AND FFmpeg_AVUTIL_LIBRARIES) - target_link_libraries( - mixxx - PRIVATE - "-force_load ${FFmpeg_AVUTIL_LIBRARIES}" - "-framework VideoToolbox" - "-framework CoreMedia" - "-framework CoreVideo" - ) + + # 1. -force_load ensures ALL object files from libavutil.a are pulled in + # unconditionally, regardless of link order. + # 2. $ uses a generator expression so the correct + # ARM64 library path is used on cross-compiled builds (avoids stale cache from + # ${FFmpeg_AVUTIL_LIBRARIES} which may point to the host-arch library). + # 3. LINKER: prefix in target_link_options is the correct CMake-idiomatic form; + # avoids the space-in-string splitting ambiguity of target_link_libraries. + # 4. Explicit FFmpeg::avutil on mixxx re-lists the archive after the Qt plugin + # init objects, giving ld64 a second pass opportunity. + if(APPLE AND TARGET FFmpeg::avutil) + is_static_library(_ffmpeg_avutil_static FFmpeg::avutil) + if(_ffmpeg_avutil_static) + target_link_options( + mixxx + PRIVATE "LINKER:-force_load,$" + ) + target_link_libraries( + mixxx + PRIVATE + FFmpeg::avutil + "-framework VideoToolbox" + "-framework CoreMedia" + "-framework CoreVideo" + ) + endif() + unset(_ffmpeg_avutil_static) endif() endif() From b90375478b83e830158c008a7a824ca11324f050 Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 22:26:47 +0200 Subject: [PATCH 11/13] mixxx-lib --- CMakeLists.txt | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10d8599148d..40aed1a49b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2827,23 +2827,15 @@ if(FFMPEG) # avoids the space-in-string splitting ambiguity of target_link_libraries. # 4. Explicit FFmpeg::avutil on mixxx re-lists the archive after the Qt plugin # init objects, giving ld64 a second pass opportunity. - if(APPLE AND TARGET FFmpeg::avutil) - is_static_library(_ffmpeg_avutil_static FFmpeg::avutil) - if(_ffmpeg_avutil_static) - target_link_options( - mixxx - PRIVATE "LINKER:-force_load,$" - ) - target_link_libraries( - mixxx - PRIVATE - FFmpeg::avutil - "-framework VideoToolbox" - "-framework CoreMedia" - "-framework CoreVideo" - ) - endif() - unset(_ffmpeg_avutil_static) + if(APPLE) + target_link_libraries( + mixxx-lib + PRIVATE + FFmpeg::avutil + "-framework VideoToolbox" + "-framework CoreMedia" + "-framework CoreVideo" + ) endif() endif() From d01e4c1ecd75a41aeec19d97cae9ac714caaf33a Mon Sep 17 00:00:00 2001 From: Joerg Date: Sat, 30 May 2026 23:46:22 +0200 Subject: [PATCH 12/13] -framework --- CMakeLists.txt | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40aed1a49b5..bfb919e2e64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2817,26 +2817,6 @@ if(FFMPEG) target_link_libraries(mixxx-lib PRIVATE FFmpeg::FFmpeg) target_include_directories(mixxx-lib PUBLIC "${FFmpeg_INCLUDE_DIRS}") - - # 1. -force_load ensures ALL object files from libavutil.a are pulled in - # unconditionally, regardless of link order. - # 2. $ uses a generator expression so the correct - # ARM64 library path is used on cross-compiled builds (avoids stale cache from - # ${FFmpeg_AVUTIL_LIBRARIES} which may point to the host-arch library). - # 3. LINKER: prefix in target_link_options is the correct CMake-idiomatic form; - # avoids the space-in-string splitting ambiguity of target_link_libraries. - # 4. Explicit FFmpeg::avutil on mixxx re-lists the archive after the Qt plugin - # init objects, giving ld64 a second pass opportunity. - if(APPLE) - target_link_libraries( - mixxx-lib - PRIVATE - FFmpeg::avutil - "-framework VideoToolbox" - "-framework CoreMedia" - "-framework CoreVideo" - ) - endif() endif() # STEM file support @@ -4428,12 +4408,12 @@ if(APPLE) "-weak_framework CoreAudio" "-weak_framework CoreFoundation" "-weak_framework CoreImage" - "-weak_framework CoreMedia" + "-framework CoreMedia" "-weak_framework CoreMidi" "-weak_framework CoreServices" - "-weak_framework CoreVideo" + "-framework CoreVideo" "-weak_framework IOSurface" - "-weak_framework VideoToolbox" + "-framework VideoToolbox" ) if(IOS) target_link_libraries(mixxx-lib PRIVATE "-weak_framework UIKit") From 3e8d6fc59755fb3da07ccbccb2834f3e35e63f2f Mon Sep 17 00:00:00 2001 From: Joerg Date: Sun, 31 May 2026 20:43:38 +0200 Subject: [PATCH 13/13] Verbose --- CMakeLists.txt | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfb919e2e64..84ca67b5f08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2776,32 +2776,58 @@ if(FFMPEG) # Minimum library versions according to # Windows: Version numbers are not available!? # macOS: Untested - if(FFmpeg_AVCODEC_VERSION AND FFmpeg_AVCODEC_VERSION VERSION_LESS 58.35.100) + if( + NOT FFmpeg_AVCODEC_VERSION + OR FFmpeg_AVCODEC_VERSION VERSION_LESS 58.35.100 + ) message( FATAL_ERROR "FFmpeg support requires at least version 58.35.100 of libavcodec (found: ${FFmpeg_AVCODEC_VERSION})." ) + else() + message( + STATUS + "Found FFmpeg AVCODEC: ${FFmpeg_AVCODEC_LIBRARIES} (found version \"${FFmpeg_AVCODEC_VERSION}\")" + ) endif() - if(FFmpeg_AVFORMAT_VERSION AND FFmpeg_AVFORMAT_VERSION VERSION_LESS 58.20.100) + if( + NOT FFmpeg_AVFORMAT_VERSION + OR FFmpeg_AVFORMAT_VERSION VERSION_LESS 58.20.100 + ) message( FATAL_ERROR "FFmpeg support requires at least version 58.20.100 of libavformat (found: ${FFmpeg_AVFORMAT_VERSION})." ) + else() + message( + STATUS + "Found FFmpeg AVFORMAT: ${FFmpeg_AVFORMAT_LIBRARIES} (found version \"${FFmpeg_AVFORMAT_VERSION}\")" + ) endif() - if(FFmpeg_AVUTIL_VERSION AND FFmpeg_AVUTIL_VERSION VERSION_LESS 56.22.100) + if(NOT FFmpeg_AVUTIL_VERSION OR FFmpeg_AVUTIL_VERSION VERSION_LESS 56.22.100) message( FATAL_ERROR "FFmpeg support requires at least version 56.22.100 of libavutil (found: ${FFmpeg_AVUTIL_VERSION})." ) + else() + message( + STATUS + "Found FFmpeg AVUTIL: ${FFmpeg_AVUTIL_LIBRARIES} (found version \"${FFmpeg_AVUTIL_VERSION}\")" + ) endif() if( - FFmpeg_SWRESAMPLE_VERSION - AND FFmpeg_SWRESAMPLE_VERSION VERSION_LESS 3.3.100 + NOT FFmpeg_SWRESAMPLE_VERSION + OR FFmpeg_SWRESAMPLE_VERSION VERSION_LESS 3.3.100 ) message( FATAL_ERROR "FFmpeg support requires at least version 3.3.100 of libswresample (found: ${FFmpeg_SWRESAMPLE_VERSION})." ) + else() + message( + STATUS + "Found FFmpeg SWRESAMPLE: ${FFmpeg_SWRESAMPLE_LIBRARIES} (found version \"${FFmpeg_SWRESAMPLE_VERSION}\")" + ) endif() target_sources(mixxx-lib PRIVATE src/sources/soundsourceffmpeg.cpp)