SDL_mixer: cmake: add SDL3MIXER_STRICT option

From fbb0fc0fbb915f9a4f3ec0bfe96c39eb71a326cc Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Tue, 5 Sep 2023 01:48:28 +0200
Subject: [PATCH] cmake: add SDL3MIXER_STRICT option

This allows to allow building SDL_mixer without all dependencies
present.
---
 .github/workflows/main.yml      |   1 +
 CMakeLists.txt                  | 650 +++++++++++++++++++++-----------
 cmake/SDL3_mixerConfig.cmake.in |  47 +--
 3 files changed, 453 insertions(+), 245 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 3e4bb791..cd6d8c59 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -125,6 +125,7 @@ jobs:
           -DSDL3MIXER_MP3_MPG123=ON \
           -DSDL3MIXER_OPUS=ON \
           -DSDL3MIXER_VORBIS=VORBISFILE \
+          -DSDL3MIXER_STRICT=ON \
           -DSDL3MIXER_WERROR=ON \
           -DCMAKE_INSTALL_PREFIX=prefix_cmake \
           ${NULL+}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d344b770..f6665ec8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -86,6 +86,16 @@ option(SDL3MIXER_DEPS_SHARED "Default value for loading dependencies dynamically
 option(SDL3MIXER_VENDORED "Use vendored third-party libraries" ${vendored_default})
 option(SDL3MIXER_WERROR "Treat warnings as errors" OFF)
 
+cmake_dependent_option(SDL3MIXER_STRICT "Fail when a dependency could not be found" OFF "NOT SDL3MIXER_VENDORED" OFF)
+set(required "")
+set(fatal_error "")
+if(SDL3MIXER_STRICT)
+  set(required "REQUIRED")
+  set(fatal_error "FATAL_ERROR")
+endif()
+set(SDL3MIXER_DEPS_FOUND )
+set(SDL3MIXER_DEPS_NOT_FOUND )
+
 option(SDL3MIXER_SAMPLES "Build the SDL3_mixer sample program(s)" ${SDL3MIXER_SAMPLES_DEFAULT})
 cmake_dependent_option(SDL3MIXER_SAMPLES_INSTALL "Install the SDL3_mixer sample program(s)" OFF "SDL3MIXER_SAMPLES;SDL3MIXER_INSTALL" OFF)
 
@@ -330,55 +340,68 @@ endif()
 set(INSTALL_EXTRA_TARGETS)
 set(PC_LIBS)
 set(PC_REQUIRES)
+set(SDL3MIXER_BACKENDS)
 
+list(APPEND SDL3MIXER_BACKENDS CMD)
+set(SDL3MIXER_CMD_ENABLED FALSE)
 if(SDL3MIXER_CMD)
     target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_CMD)
     set(fork_found OFF)
     if(NOT fork_found)
         check_symbol_exists(fork unistd.h HAVE_FORK)
         if(HAVE_FORK)
-            set(fork_found ON)
+            set(SDL3MIXER_CMD_ENABLED TRUE)
             target_compile_definitions(${sdl3_mixer_target_name} PRIVATE HAVE_FORK)
         endif()
     endif()
     if(NOT fork_found)
         check_symbol_exists(vfork unistd.h HAVE_VFORK)
         if(HAVE_VFORK)
-            set(fork_found ON)
+            set(SDL3MIXER_CMD_ENABLED TRUE)
             target_compile_definitions(${sdl3_mixer_target_name} PRIVATE HAVE_VFORK)
         endif()
     endif()
-    if(NOT fork_found)
-        message(FATAL_ERROR "Neither fork() nor vfork() or available on this platform. Reconfigure with -DSDL3MIXER_CMD=OFF.")
+    if(NOT SDL3MIXER_CMD_ENABLED)
+        message(${fatal_error} "Neither fork() nor vfork() or available on this platform. Reconfigure with -DSDL3MIXER_CMD=OFF.")
     endif()
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS SNDFILE)
+set(SDL3MIXER_SNDFILE_ENABLED FALSE)
 if(SDL3MIXER_SNDFILE)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE LOAD_SNDFILE)
     if(SDL3MIXER_VENDORED)
         message(STATUS "Using vendored libsndfile")
-        message(FATAL_ERROR "libsndfile is not vendored.")
+        message(${fatal_error} "libsndfile is not vendored.")
     else()
-        message(STATUS "Using system libsndfile")
-        find_package(SndFile REQUIRED)
-        if(NOT SDL3MIXER_SNDFILE_SHARED)
-            list(APPEND PC_REQUIRES sndfile)
+        find_package(SndFile ${required})
+        if(SndFile_FOUND)
+            set(SDL3MIXER_SNDFILE_ENABLED TRUE)
+            message(STATUS "Using system libsndfile")
+            if(NOT SDL3MIXER_SNDFILE_SHARED)
+                list(APPEND PC_REQUIRES sndfile)
+            endif()
+        else()
+            set(SDL3MIXER_SNDFILE_ENABLED FALSE)
+            message(STATUS "libsndfile NOT found")
         endif()
     endif()
-    if(SDL3MIXER_SNDFILE_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:SndFile::sndfile,INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:SndFile::sndfile,INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:SndFile::sndfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_sndfile SndFile::sndfile)
-        message(STATUS "Dynamic libsndfile: ${dynamic_sndfile}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "SNDFILE_DYNAMIC=\"${dynamic_sndfile}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} SndFile::sndfile)
+    if(SDL3MIXER_SNDFILE_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE LOAD_SNDFILE)
+        if(SDL3MIXER_SNDFILE_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:SndFile::sndfile,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:SndFile::sndfile,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:SndFile::sndfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+            target_get_dynamic_library(dynamic_sndfile SndFile::sndfile)
+            message(STATUS "Dynamic libsndfile: ${dynamic_sndfile}")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "SNDFILE_DYNAMIC=\"${dynamic_sndfile}\"")
+            if(SDL3MIXER_VENDORED)
+                add_dependencies(${sdl3_mixer_target_name} SndFile::sndfile)
+            endif()
+        else()
+            target_link_libraries(${sdl3_mixer_target_name} PRIVATE SndFile::sndfile)
         endif()
-    else()
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE SndFile::sndfile)
     endif()
 endif()
 
@@ -397,9 +420,11 @@ if(SDL3MIXER_OGG)
     endif()
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS OPUS)
+set(SDL3MIXER_OPUS_ENABLED FALSE)
 if(SDL3MIXER_OPUS)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OPUS)
     if(SDL3MIXER_VENDORED)
+        set(SDL3MIXER_OPUS_ENABLED TRUE)
         # vendored libogg already handled
         if(NOT TARGET ogg)
             message(FATAL_ERROR "ogg target not present")
@@ -438,38 +463,51 @@ if(SDL3MIXER_OPUS)
             list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:opusfile> -l$<TARGET_FILE_BASE_NAME:opus> -l$<TARGET_FILE_BASE_NAME:ogg>)
         endif()
     else()
-        message(STATUS "Using system opusfile")
-        find_package(OpusFile REQUIRED)
-        if(NOT SDL3MIXER_OPUS_SHARED)
-            list(APPEND PC_REQUIRES opusfile)
+        find_package(OpusFile ${required})
+        if(OpusFile_FOUND)
+            set(SDL3MIXER_OPUS_ENABLED TRUE)
+            message(STATUS "Using system opusfile")
+            if(NOT SDL3MIXER_OPUS_SHARED)
+                list(APPEND PC_REQUIRES opusfile)
+            endif()
+        else()
+            message(STATUS "opusfile NOT found")
         endif()
     endif()
-    if(SDL3MIXER_OPUS_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:OpusFile::opusfile,INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:OpusFile::opusfile,INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:OpusFile::opusfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_opusfile OpusFile::opusfile)
-        message(STATUS "Dynamic opus (opusfile): ${dynamic_opusfile}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OPUS_DYNAMIC=\"${dynamic_opusfile}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} OpusFile::opusfile)
+    if(SDL3MIXER_OPUS_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OPUS)
+        if(SDL3MIXER_OPUS_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:OpusFile::opusfile,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:OpusFile::opusfile,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:OpusFile::opusfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+            target_get_dynamic_library(dynamic_opusfile OpusFile::opusfile)
+            message(STATUS "Dynamic opus (opusfile): ${dynamic_opusfile}")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OPUS_DYNAMIC=\"${dynamic_opusfile}\"")
+            if(SDL3MIXER_VENDORED)
+                add_dependencies(${sdl3_mixer_target_name} OpusFile::opusfile)
+            endif()
+        else()
+            target_link_libraries(${sdl3_mixer_target_name} PRIVATE OpusFile::opusfile)
         endif()
-    else()
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE OpusFile::opusfile)
     endif()
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS VORBIS_STB)
+set(SDL3MIXER_VORBIS_STB_ENABLED FALSE)
 if(SDL3MIXER_VORBIS_STB)
+    set(SDL3MIXER_VORBIS_STB_ENABLED TRUE)
     message(STATUS "Enabled ogg music: using stb_vorbis")
     target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG)
     target_compile_definitions(${sdl3_mixer_target_name} PRIVATE OGG_USE_STB)
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS VORBIS_TREMOR)
+set(SDL3MIXER_VORBIS_TREMOR_ENABLED FALSE)
 if(SDL3MIXER_VORBIS_TREMOR)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG OGG_USE_TREMOR)
     if(SDL3MIXER_VENDORED)
+        set(SDL3MIXER_VORBIS_TREMOR_ENABLED TRUE)
         # vendored libogg already handled
         if(NOT TARGET ogg)
             message(FATAL_ERROR "ogg target not present")
@@ -496,31 +534,42 @@ if(SDL3MIXER_VORBIS_TREMOR)
         endif()
     else()
         message(STATUS "Using system tremor")
-        find_package(tremor REQUIRED)
-        if(NOT SDL3MIXER_VORBIS_TREMOR_SHARED)
-            list(APPEND PC_REQUIRES tremor)
+        find_package(tremor ${required})
+        if(tremor_FOUND)
+            if(NOT SDL3MIXER_VORBIS_TREMOR_SHARED)
+                list(APPEND PC_REQUIRES tremor)
+            endif()
+            set(SDL3MIXER_VORBIS_TREMOR_ENABLED TRUE)
+        else()
+            set(SDL3MIXER_VORBIS_TREMOR_ENABLED FALSE)
+            message(STATUS "tremor NOT found")
         endif()
     endif()
-    if(SDL3MIXER_VORBIS_TREMOR_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:tremor::tremor,INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:tremor::tremor,INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:tremor::tremor,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_tremor tremor::tremor)
-        message(STATUS "Dynamic vorbis (tremor): ${dynamic_tremor}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OGG_DYNAMIC=\"${dynamic_tremor}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} tremor::tremor)
+    if(SDL3MIXER_VORBIS_TREMOR_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG OGG_USE_TREMOR)
+        if(SDL3MIXER_VORBIS_TREMOR_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:tremor::tremor,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:tremor::tremor,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:tremor::tremor,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+            target_get_dynamic_library(dynamic_tremor tremor::tremor)
+            message(STATUS "Dynamic vorbis (tremor): ${dynamic_tremor}")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OGG_DYNAMIC=\"${dynamic_tremor}\"")
+            if(SDL3MIXER_VENDORED)
+                add_dependencies(${sdl3_mixer_target_name} tremor::tremor)
+            endif()
+        else()
+            target_link_libraries(${sdl3_mixer_target_name} PRIVATE tremor::tremor)
         endif()
-    else()
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE tremor::tremor)
     endif()
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS VORBIS_VORBISFILE)
+set(SDL3MIXER_VORBIS_VORBISFILE_ENABLED FALSE)
 if(SDL3MIXER_VORBIS_VORBISFILE)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG)
     if(SDL3MIXER_VENDORED)
+        set(SDL3MIXER_VORBIS_VORBISFILE_ENABLED TRUE)
         # vendored libogg already handled
         if(NOT TARGET ogg)
             message(FATAL_ERROR "ogg target not present")
@@ -539,32 +588,47 @@ if(SDL3MIXER_VORBIS_VORBISFILE)
             list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:vorbisfile>)
         endif()
     else()
-        message(STATUS "Using system vorbisfile")
-        find_package(Vorbis REQUIRED)
-        if(NOT SDL3MIXER_VORBIS_VORBISFILE_SHARED)
-            list(APPEND PC_REQUIRES vorbisfile)
+        find_package(Vorbis ${required})
+        if(vorbis_FOUND)
+            set(SDL3MIXER_VORBIS_VORBISFILE_ENABLED TRUE)
+            message(STATUS "Using system vorbisfile")
+            if(NOT SDL3MIXER_VORBIS_VORBISFILE_SHARED)
+                list(APPEND PC_REQUIRES vorbisfile)
+            endif()
+        else()
+            message(STATUS "vorbisfile NOT found")
         endif()
     endif()
-    if(SDL3MIXER_VORBIS_VORBISFILE_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:Vorbis::vorbisfile,INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:Vorbis::vorbisfile,INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:Vorbis::vorbisfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_vorbisfile Vorbis::vorbisfile)
-        message(STATUS "Dynamic vorbisfile: ${dynamic_vorbisfile}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OGG_DYNAMIC=\"${dynamic_vorbisfile}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} Vorbis::vorbisfile)
+    if(SDL3MIXER_VORBIS_VORBISFILE_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG)
+        if(SDL3MIXER_VORBIS_VORBISFILE_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:Vorbis::vorbisfile,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:Vorbis::vorbisfile,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:Vorbis::vorbisfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+            target_get_dynamic_library(dynamic_vorbisfile Vorbis::vorbisfile)
+            message(STATUS "Dynamic vorbisfile: ${dynamic_vorbisfile}")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OGG_DYNAMIC=\"${dynamic_vorbisfile}\"")
+            if(SDL3MIXER_VENDORED)
+                add_dependencies(${sdl3_mixer_target_name} Vorbis::vorbisfile)
+            endif()
+        else()
+            target_link_libraries(${sdl3_mixer_target_name} PRIVATE Vorbis::vorbisfile)
         endif()
-    else()
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE Vorbis::vorbisfile)
     endif()
 endif()
 
+set(SDL3MIXER_VORBIS_ENABLED FALSE)
+if(SDL3MIXER_VORBIS_STB_ENABLED OR SDL3MIXER_VORBIS_TREMOR_ENABLED OR SDL3MIXER_VORBIS_VORBISFILE_ENABLED)
+    set(SDL3MIXER_VORBIS_ENABLED TRUE)
+endif()
+
+list(APPEND SDL3MIXER_BACKENDS FLAC_LIBFLAC)
+set(SDL3MIXER_FLAC_LIBFLAC_ENABLED FALSE)
 if(SDL3MIXER_FLAC_LIBFLAC)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_FLAC_LIBFLAC)
     if(SDL3MIXER_VENDORED)
+        set(SDL3MIXER_FLAC_LIBFLAC_ENABLED TRUE)
         # vendored libogg already handled
         if(NOT TARGET ogg)
             message(FATAL_ERROR "ogg target not present")
@@ -587,36 +651,55 @@ if(SDL3MIXER_FLAC_LIBFLAC)
             list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:FLAC::FLAC> -l$<TARGET_FILE_BASE_NAME:ogg>)
         endif()
     else()
-        message(STATUS "Using system libflac")
-        find_package(FLAC REQUIRED)
-        if(NOT SDL3MIXER_FLAC_LIBFLAC_SHARED)
-            list(APPEND PC_REQUIRES flac)
+        find_package(FLAC ${required})
+        if(FLAC_FOUND)
+            set(SDL3MIXER_FLAC_LIBFLAC_ENABLED TRUE)
+            message(STATUS "Using system libflac")
+            if(NOT SDL3MIXER_FLAC_LIBFLAC_SHARED)
+                list(APPEND PC_REQUIRES flac)
+            endif()
+        else()
+            set(SDL3MIXER_FLAC_LIBFLAC_ENABLED FALSE)
+            message(STATUS "libflac NOT found")
         endif()
     endif()
-    if(SDL3MIXER_FLAC_LIBFLAC_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:FLAC::FLAC,INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_flac FLAC::FLAC)
-        message(STATUS "Dynamic libflac: ${dynamic_flac}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "FLAC_DYNAMIC=\"${dynamic_flac}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} FLAC)
+    if(SDL3MIXER_FLAC_LIBFLAC_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_FLAC_LIBFLAC)
+        if(SDL3MIXER_FLAC_LIBFLAC_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:FLAC::FLAC,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:FLAC::FLAC,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+            target_get_dynamic_library(dynamic_flac FLAC::FLAC)
+            message(STATUS "Dynamic libflac: ${dynamic_flac}")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "FLAC_DYNAMIC=\"${dynamic_flac}\"")
+            if(SDL3MIXER_VENDORED)
+                add_dependencies(${sdl3_mixer_target_name} FLAC)
+            endif()
+        else()
+            target_link_libraries(${sdl3_mixer_target_name} PRIVATE FLAC::FLAC)
         endif()
-    else()
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE FLAC::FLAC)
     endif()
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS FLAC_DRFLAC)
+set(SDL3MIXER_FLAC_DRFLAC_ENABLED FALSE)
 if(SDL3MIXER_FLAC_DRFLAC)
+    set(SDL3MIXER_FLAC_DRFLAC_ENABLED TRUE)
     target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_FLAC_DRFLAC)
 endif()
 
+set(SDL3MIXER_FLAC_ENABLED FALSE)
+if(SDL3MIXER_FLAC_DRFLAC_ENABLED OR SDL3MIXER_FLAC_LIBFLAC_ENABLED)
+    set(SDL3MIXER_FLAC_ENABLED TRUE)
+endif()
+
+list(APPEND SDL3MIXER_BACKENDS GME)
+set(SDL3MIXER_GME_ENABLED FALSE)
 if(SDL3MIXER_GME)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_GME)
     if(SDL3MIXER_VENDORED)
+        set(SDL3MIXER_GME_ENABLED TRUE)
         set(BUILD_SHARED_LIBS "${SDL3MIXER_GME_SHARED}")
         set(ENABLE_UBSAN OFF)
         set(BUILD_FRAMEWORK OFF)
@@ -632,61 +715,82 @@ if(SDL3MIXER_GME)
             list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:gme>)
         endif()
     else()
-        message(STATUS "Using system libgme")
-        find_package(gme REQUIRED)
-        if(NOT SDL3MIXER_GME_SHARED)
-            list(APPEND PC_REQUIRES libgme)
+        find_package(gme ${required})
+        if(gme_FOUND)
+            set(SDL3MIXER_GME_ENABLED TRUE)
+            message(STATUS "Using system libgme")
+            if(NOT SDL3MIXER_GME_SHARED)
+                list(APPEND PC_REQUIRES libgme)
+            endif()
+        else()
+            set(SDL3MIXER_GME_ENABLED FALSE)
+            message(STATUS "libgme NOT found")
         endif()
     endif()
-    if(SDL3MIXER_GME_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:gme::gme,INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:gme::gme,INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:gme::gme,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_gme gme::gme)
-        message(STATUS "Dynamic libgme: ${dynamic_gme}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "GME_DYNAMIC=\"${dynamic_gme}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} gme::gme)
+    if(SDL3MIXER_GME_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_GME)
+        if(SDL3MIXER_GME_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:gme::gme,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:gme::gme,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:gme::gme,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+            target_get_dynamic_library(dynamic_gme gme::gme)
+            message(STATUS "Dynamic libgme: ${dynamic_gme}")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "GME_DYNAMIC=\"${dynamic_gme}\"")
+            if(SDL3MIXER_VENDORED)
+                add_dependencies(${sdl3_mixer_target_name} gme::gme)
+            endif()
+        else()
+            target_link_libraries(${sdl3_mixer_target_name} PRIVATE gme::gme)
         endif()
-    else()
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE gme::gme)
     endif()
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS MOD_MODPLUG)
+set(SDL3MIXER_MOD_MODPLUG_ENABLED FALSE)
 if(SDL3MIXER_MOD_MODPLUG)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MOD_MODPLUG)
     if(SDL3MIXER_VENDORED)
         message(STATUS "Using vendored libmodplug")
-        message(FATAL_ERROR "libmodplug is not vendored.")
+        message(${fatal_error} "libmodplug is not vendored.")
     else()
-        message(STATUS "Using system libmodplug")
-        find_package(modplug REQUIRED)
-        if(NOT SDL3MIXER_MOD_MODPLUG_SHARED)
-            list(APPEND PC_REQUIRES libmodplug)
+        find_package(modplug ${required})
+        if(modplug_FOUND)
+            set(SDL3MIXER_MOD_MODPLUG_ENABLED TRUE)
+            message(STATUS "Using system libmodplug")
+            if(NOT SDL3MIXER_MOD_MODPLUG_SHARED)
+                list(APPEND PC_REQUIRES libmodplug)
+            endif()
+        else()
+            set(SDL3MIXER_MOD_MODPLUG_ENABLED FALSE)
+            message(STATUS "libmodplug NOT found")
         endif()
     endif()
-    if(SDL3MIXER_MOD_MODPLUG_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:modplug::modplug,INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:modplug::modplug,INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:modplug::modplug,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_modplug modplug::modplug)
-        message(STATUS "Dynamic modplug: ${dynamic_modplug}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "MODPLUG_DYNAMIC=\"${dynamic_modplug}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} modplug::modplug)
+    if(SDL3MIXER_MOD_MODPLUG_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MOD_MODPLUG)
+        if(SDL3MIXER_MOD_MODPLUG_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:modplug::modplug,INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:modplug::modplug,INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:modplug::modplug,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+            target_get_dynamic_library(dynamic_modplug modplug::modplug)
+            message(STATUS "Dynamic modplug: ${dynamic_modplug}")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "MODPLUG_DYNAMIC=\"${dynamic_modplug}\"")
+            if(SDL3MIXER_VENDORED)
+                add_dependencies(${sdl3_mixer_target_name} modplug::modplug)
+            endif()
+        else()
+            target_link_libraries(${sdl3_mixer_target_name} PRIVATE modplug::modplug)
         endif()
-    else()
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE modplug::modplug)
     endif()
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS MOD_XMP)
+set(SDL3MIXER_MOD_XMP_ENABLED FALSE)
 if(SDL3MIXER_MOD_XMP)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MOD_XMP)
     if(SDL3MIXER_VENDORED)
+        set(SDL3MIXER_MOD_XMP_ENABLED TRUE)
         message(STATUS "Using vendored libxmp")
         sdl_check_project_in_subfolder(external/libxmp libxmp SDL3MIXER_VENDORED)
         set(LIBXMP_DISABLE_DEPACKERS ON CACHE BOOL "Disable archive depackers")
@@ -710,53 +814,78 @@ if(SDL3MIXER_MOD_XMP)
         endif()
     else()
         if(SDL3MIXER_MOD_XMP_LITE)
-            message(STATUS "Using system libxmp-lite")
-            find_package(libxmp-lite REQUIRED)
-            set(tgt_xmp libxmp-lite::libxmp-lite)
-            set(xmp_name libxmp-lite)
-            if(NOT SDL3MIXER_MOD_XMP_SHARED)
-                list(APPEND PC_REQUIRES libxmplite)
+            find_package(libxmp-lite ${required})
+            if(libxmp-lite_FOUND)
+                set(SDL3MIXER_MOD_XMP_ENABLED TRUE)
+                message(STATUS "Using system libxmp-lite")
+                set(tgt_xmp libxmp-lite::libxmp-lite)
+                set(xmp_name libxmp-lite)
+                if(NOT SDL3MIXER_MOD_XMP_SHARED)
+                    list(APPEND PC_REQUIRES libxmplite)
+                endif()
+            else()
+                set(SDL3MIXER_MOD_XMP_ENABLED FALSE)
+                message(STATUS "libxmp-lite NOT found")
             endif()
         else()
-            message(STATUS "Using system libxmp")
-            find_package(libxmp REQUIRED)
-            if(TARGET libxmp::xmp_shared AND SDL3MIXER_MOD_XMP_SHARED)
-              set(tgt_xmp libxmp::xmp_shared)
-            elseif(TARGET libxmp::xmp_static)
-              set(tgt_xmp libxmp::xmp_static)
+            find_package(libxmp ${required})
+            if(libxmp_FOUND)
+                set(SDL3MIXER_MOD_XMP_ENABLED TRUE)
+                message(STATUS "Using system libxmp")
+                if(TARGET libxmp::xmp_shared AND SDL3MIXER_MOD_XMP_SHARED)
+                  set(tgt_xmp libxmp::xmp_shared)
+                elseif(TARGET libxmp::xmp_static)
+                  set(tgt_xmp libxmp::xmp_static)
+                else()
+                  set(tgt_xmp libxmp::libxmp)
+                endif()
+                set(xmp_name libxmp)
+                if(NOT SDL3MIXER_MOD_XMP_SHARED)
+                    list(APPEND PC_REQUIRES libxmp)
+                endif()
             else()
-              set(tgt_xmp libxmp::libxmp)
-            endif()
-            set(xmp_name libxmp)
-            if(NOT SDL3MIXER_MOD_XMP_SHARED)
-                list(APPEND PC_REQUIRES libxmp)
+                set(SDL3MIXER_MOD_XMP_ENABLED FALSE)
+                message(STATUS "libxmp NOT found")
             endif()
         endif()
     endif()
-    if(SDL3MIXER_MOD_XMP_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:${tgt_xmp},INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:${tgt_xmp},INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:${tgt_xmp},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_xmp ${tgt_xmp})
-        message(STATUS "Dynamic ${xmp_name}: ${dynamic_xmp}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "XMP_DYNAMIC=\"${dynamic_xmp}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} ${tgt_xmp})
+    if(SDL3MIXER_MOD_XMP_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MOD_XMP)
+        if(SDL3MIXER_MOD_XMP_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:${tgt_xmp},INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:${tgt_xmp},INTERFACE_INCLUDE_DIRECTORIES>
+                $<TARGET_PROPERTY:${tgt_xmp},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
+            )
+            target_get_dynamic_library(dynamic_xmp ${tgt_xmp})
+            message(STATUS "Dynamic ${xmp_name}: ${dynamic_xmp}")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "XMP_DYNAMIC=\"${dynamic_xmp}\"")
+            if(SDL3MIXER_VENDORED)
+                add_dependencies(${sdl3_mixer_target_name} ${tgt_xmp})
+            endif()
+        else()
+            target_link_libraries(${sdl3_mixer_target_name} PRIVATE ${tgt_xmp})
         endif()
-    else()
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE ${tgt_xmp})
     endif()
 endif()
 
+set(SDL3MIXER_MOD_ENABLED FALSE)
+if(SDL3MIXER_MOD_MODPLUG_ENABLED OR SDL3MIXER_MOD_XMP_ENABLED OR SDL3MIXER_MOD_XMP_ENABLED)
+    set(SDL3MIXER_MOD_ENABLED TRUE)
+endif()
+
+list(APPEND SDL3MIXER_BACKENDS MP3_DRMP3)
+set(SDL3MIXER_MP3_DRMP3_ENABLED FALSE)
 if(SDL3MIXER_MP3_DRMP3)
+    set(SDL3MIXER_MP3_DRMP3_ENABLED TRUE)
     target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MP3_DRMP3)
 endif()
 
+list(APPEND SDL3MIXER_BACKENDS MP3_MPG123)
+set(SDL3MIXER_MP3_MPG123_ENABLED FALSE)
 if(SDL3MIXER_MP3_MPG123)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MP3_MPG123)
     if(SDL3MIXER_VENDORED)
+        set(SDL3MIXER_MP3_MPG123_ENABLED TRUE)
         message(STATUS "Using vendored mpg123")
         sdl_check_project_in_subfolder(external/mpg123/ports/cmake mpg123 SDL3MIXER_VENDORED)
         set(BUILD_LIBOUT123 FALSE)
@@ -773,78 +902,115 @@ if(SDL3MIXER_MP3_MPG123)
             list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:MPG123::mpg123>)
         endif()
     else()
-        message(STATUS "Using system mpg123")
-        find_package(mpg123 REQUIRED)
-        if(NOT SDL3MIXER_MP3_MPG123_SHARED)
-            list(APPEND PC_REQUIRES libmpg123)
+        find_package(mpg123 ${required})
+        if(mpg123_FOUND)
+            set(SDL3MIXER_MP3_MPG123_ENABLED TRUE)
+            message(STATUS "Using system mpg123")
+            if(NOT SDL3MIXER_MP3_MPG123_SHARED)
+                list(APPEND PC_REQUIRES libmpg123)
+            endif()
+        else()
+            set(SDL3MIXER_MP3_MPG123_ENABLED FALSE)
+            message(STATUS "mpg123 NOT found")
         endif()
     endif()
-    if(SDL3MIXER_MP3_MPG123_SHARED)
-        target_include_directories(${sdl3_mixer_target_name} PRIVATE
-            $<TARGET_PROPERTY:MPG123::libmpg123,INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:MPG123::libmpg123,INTERFACE_INCLUDE_DIRECTORIES>
-            $<TARGET_PROPERTY:MPG123::libmpg123,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-        )
-        target_get_dynamic_library(dynamic_mpg123 MPG123::libmpg123)
-        message(STATUS "Dynamic mpg123}: ${dynamic_mpg123}")
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "MPG123_DYNAMIC=\"${dynamic_mpg123}\"")
-        if(SDL3MIXER_VENDORED)
-            add_dependencies(${sdl3_mixer_target_name} MPG123::libmpg123)
+    if(SDL3MIXER_MP3_MPG123_ENABLED)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MP3_MPG123)
+        if(SDL3MIXER_MP3_MPG123_SHARED)
+            target_include_directories(${sdl3_mixer_target_name} PRIVATE
+                $<TARGET_PROPERTY:MPG123::libmpg123,INCLUDE_DIRECT

(Patch may be truncated, please check the link at the top of this post.)