SDL_mixer: cmake: add gme support

From 9afe1971f9fd1207beb244b698032be267e79bd8 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Fri, 6 Jan 2023 16:36:52 +0100
Subject: [PATCH] cmake: add gme support

---
 .github/workflows/main.yml |  4 +++
 .gitmodules                |  3 +++
 CMakeLists.txt             | 52 +++++++++++++++++++++++++++++++++++---
 SDL2_mixerConfig.cmake.in  |  6 +++++
 cmake/Findgme.cmake        | 36 ++++++++++++++++++++++++++
 configure                  |  1 +
 configure.ac               |  1 +
 external/libgme            |  1 +
 sdl2_mixer-config.cmake.in |  2 ++
 9 files changed, 103 insertions(+), 3 deletions(-)
 create mode 100644 cmake/Findgme.cmake
 create mode 160000 external/libgme

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d794d3e8..114d02ba 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -39,6 +39,7 @@ jobs:
           ${{ matrix.platform.msys-env }}-gcc
           ${{ matrix.platform.msys-env }}-flac
           ${{ matrix.platform.msys-env }}-fluidsynth
+          ${{ matrix.platform.msys-env }}-libgme
           ${{ matrix.platform.msys-env }}-libvorbis
           ${{ matrix.platform.msys-env }}-libxmp
           ${{ matrix.platform.msys-env }}-mpg123
@@ -58,6 +59,7 @@ jobs:
           pkg-config \
           flac \
           fluidsynth \
+          game-music-emu \
           libvorbis \
           libxmp \
           mpg123 \
@@ -75,6 +77,7 @@ jobs:
           libsdl2-dev \
           libflac-dev \
           libfluidsynth-dev \
+          libgme-dev \
           libmpg123-dev \
           libopusfile-dev \
           libvorbis-dev \
@@ -127,6 +130,7 @@ jobs:
           -DCMAKE_BUILD_TYPE=Release \
           -DSDL2MIXER_FLAC=ON \
           -DSDL2MIXER_FLAC_LIBFLAC=ON \
+          -DSDL2MIXER_GME=ON \
           -DSDL2MIXER_MOD_XMP=ON \
           -DSDL2MIXER_MP3_MPG123=ON \
           -DSDL2MIXER_OPUS=ON \
diff --git a/.gitmodules b/.gitmodules
index 78669f4b..695951e7 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -34,3 +34,6 @@
 	path = external/wavpack
 	url = https://github.com/libsdl-org/wavpack.git
 	branch = 5.6.0-sdl
+[submodule "external/libgme"]
+	path = external/libgme
+	url = https://github.com/libsdl-org/game-music-emu.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f90fdf80..ec3d9dbf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -84,6 +84,9 @@ cmake_dependent_option(SDL2MIXER_FLAC_LIBFLAC_SHARED "Dynamically load LIBFLAC"
 
 cmake_dependent_option(SDL2MIXER_FLAC_DRFLAC "Enable FLAC music using drflac" ON SDL2MIXER_FLAC OFF)
 
+option(SDL2MIXER_GME "Support loading GME music via game-music-emu" OFF)
+option(SDL2MIXER_GME_SHARED "Dynamically load libgme" "${SDL2MIXER_DEPS_SHARED}")
+
 option(SDL2MIXER_MOD "Support loading MOD music" ON)
 
 cmake_dependent_option(SDL2MIXER_MOD_MODPLUG "Support loading MOD music via modplug" OFF SDL2MIXER_MOD OFF)
@@ -194,6 +197,7 @@ add_library(SDL2_mixer
     src/codecs/music_drmp3.c
     src/codecs/music_flac.c
     src/codecs/music_fluidsynth.c
+    src/codecs/music_gme.c
     src/codecs/music_modplug.c
     src/codecs/music_mpg123.c
     src/codecs/music_nativemidi.c
@@ -506,7 +510,7 @@ endif()
 if(SDL2MIXER_FLAC_LIBFLAC)
     target_compile_definitions(SDL2_mixer PRIVATE MUSIC_FLAC_LIBFLAC)
     if(SDL2MIXER_VENDORED)
-        # vendored libogg alread handled
+        # vendored libogg already handled
         if(NOT TARGET ogg)
             message(FATAL_ERROR "ogg target not present")
         endif()
@@ -555,6 +559,47 @@ if(SDL2MIXER_FLAC_DRFLAC)
     target_compile_definitions(SDL2_mixer PRIVATE MUSIC_FLAC_DRFLAC)
 endif()
 
+if(SDL2MIXER_GME)
+    target_compile_definitions(SDL2_mixer PRIVATE MUSIC_GME)
+    if(SDL2MIXER_VENDORED)
+        set(BUILD_SHARED_LIBS "${SDL2MIXER_GME_SHARED}")
+        set(ENABLE_UBSAN OFF CACHE BOOL "UB sanitizer")
+        set(BUILD_FRAMEWORK OFF CACHE BOOL "macos framework")
+        set(GME_ZLIB OFF CACHE BOOL "GME supports compressed formats")
+        message(STATUS "Using vendored libgme")
+        sdl_check_project_in_subfolder(external/libgme libgme SDL2MIXER_VENDORED)
+        add_subdirectory(external/libgme EXCLUDE_FROM_ALL)
+        add_library(gme::gme ALIAS gme)
+        if(SDL2MIXER_GME_SHARED)
+            list(APPEND INSTALL_EXTRA_TARGETS gme)
+        endif()
+        if(NOT SDL2MIXER_GME_SHARED)
+            list(APPEND PC_LIBS -l$<TARGET_FILE_BASE_NAME:gme>)
+        endif()
+    else()
+        message(STATUS "Using system libgme")
+        find_package(gme REQUIRED)
+        if(NOT SDL2MIXER_GME_SHARED)
+            list(APPEND PC_REQUIRES libgme)
+        endif()
+    endif()
+    if(SDL2MIXER_GME_SHARED)
+        target_include_directories(SDL2_mixer 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(SDL2_mixer PRIVATE "GME_DYNAMIC=\"${dynamic_gme}\"")
+        if(SDL2MIXER_VENDORED)
+            add_dependencies(SDL2_mixer gme::gme)
+        endif()
+    else()
+        target_link_libraries(SDL2_mixer PRIVATE gme::gme)
+    endif()
+endif()
+
 if(SDL2MIXER_MOD_MODPLUG)
     target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MOD_MODPLUG)
     if(SDL2MIXER_VENDORED)
@@ -848,13 +893,14 @@ if(SDL2MIXER_INSTALL)
             FILES
                 cmake/FindFLAC.cmake
                 cmake/FindFluidSynth.cmake
+                cmake/Findgme.cmake
                 cmake/Findlibxmp.cmake
                 cmake/Findlibxmp-lite.cmake
                 cmake/Findmodplug.cmake
-                cmake/FindOpusFile.cmake
                 cmake/FindMPG123.cmake
-                cmake/FindVorbis.cmake
+                cmake/FindOpusFile.cmake
                 cmake/Findtremor.cmake
+                cmake/FindVorbis.cmake
                 cmake/Findwavpack.cmake
             DESTINATION "${SDLMIXER_INSTALL_CMAKEDIR}"
             COMPONENT devel
diff --git a/SDL2_mixerConfig.cmake.in b/SDL2_mixerConfig.cmake.in
index b6c8154d..990d935d 100644
--- a/SDL2_mixerConfig.cmake.in
+++ b/SDL2_mixerConfig.cmake.in
@@ -15,6 +15,8 @@ set(SDL2MIXER_CMD                   @SDL2MIXER_CMD@)
 set(SDL2MIXER_FLAC_LIBFLAC          @SDL2MIXER_FLAC_LIBFLAC@)
 set(SDL2MIXER_FLAC_DRFLAC           @SDL2MIXER_FLAC_DRFLAC@)
 
+set(SDL2MIXER_GME                   @SDL2MIXER_GME@)
+
 set(SDL2MIXER_MOD                   @SDL2MIXER_MOD@)
 set(SDL2MIXER_MOD_MODPLUG           @SDL2MIXER_MOD_MODPLUG@)
 set(SDL2MIXER_MOD_XMP               @SDL2MIXER_MOD_XMP@)
@@ -59,6 +61,10 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2_mixer-static-targets.cmake")
         find_dependency(FLAC)
     endif()
 
+    if(SDL2MIXER_GME AND NOT SDL2MIXER_VENDORED AND NOT TARGET gme::gme)
+        find_dependency(gme)
+    endif()
+
     if(SDL2MIXER_MOD_MODPLUG AND NOT SDL2MIXER_VENDORED AND NOT TARGET modplug::modplug)
         find_dependency(modplug)
     endif()
diff --git a/cmake/Findgme.cmake b/cmake/Findgme.cmake
new file mode 100644
index 00000000..c74e0aab
--- /dev/null
+++ b/cmake/Findgme.cmake
@@ -0,0 +1,36 @@
+include(FindPackageHandleStandardArgs)
+
+find_library(gme_LIBRARY
+    NAMES gme
+)
+
+set(gme_COMPILE_OPTIONS "" CACHE STRING "Extra compile options of gme")
+
+set(gme_LINK_LIBRARIES "" CACHE STRING "Extra link libraries of gme")
+
+set(gme_LINK_FLAGS "" CACHE STRING "Extra link flags of gme")
+
+find_path(gme_INCLUDE_PATH
+    NAMES gme/gme.h
+)
+
+find_package_handle_standard_args(gme
+    REQUIRED_VARS gme_LIBRARY gme_INCLUDE_PATH
+)
+
+if(gme_FOUND)
+    set(gme_dirs ${gme_INCLUDE_PATH})
+    if(EXISTS "${gme_INCLUDE_PATH}/gme")
+        list(APPEND gme_dirs "${gme_INCLUDE_PATH}/gme")
+    endif()
+    if (NOT TARGET gme::gme)
+        add_library(gme::gme UNKNOWN IMPORTED)
+        set_target_properties(gme::gme PROPERTIES
+            IMPORTED_LOCATION "${gme_LIBRARY}"
+            INTERFACE_INCLUDE_DIRECTORIES "${gme_dirs}"
+            INTERFACE_COMPILE_OPTIONS "${gme_COMPILE_OPTIONS}"
+            INTERFACE_LINK_LIBRARIES "${gme_LINK_LIBRARIES}"
+            INTERFACE_LINK_FLAGS "${gme_LINK_FLAGS}"
+        )
+    endif()
+endif()
diff --git a/configure b/configure
index f35e6f02..a5a881a2 100755
--- a/configure
+++ b/configure
@@ -815,6 +815,7 @@ SDL2MIXER_MP3_DRMP3
 SDL2MIXER_MOD_XMP_LITE
 SDL2MIXER_MOD_XMP
 SDL2MIXER_MOD_MODPLUG
+SDL2MIXER_GME
 SDL2MIXER_FLAC_LIBFLAC
 SDL2MIXER_FLAC_DRFLAC
 SDL2MIXER_CMD
diff --git a/configure.ac b/configure.ac
index 70aa1ed1..6ae47854 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1092,6 +1092,7 @@ AC_SUBST(PC_LIBS)
 AC_SUBST(SDL2MIXER_CMD)
 AC_SUBST(SDL2MIXER_FLAC_DRFLAC)
 AC_SUBST(SDL2MIXER_FLAC_LIBFLAC)
+AC_SUBST(SDL2MIXER_GME)
 AC_SUBST(SDL2MIXER_MOD_MODPLUG)
 AC_SUBST(SDL2MIXER_MOD_XMP)
 AC_SUBST(SDL2MIXER_MOD_XMP_LITE)
diff --git a/external/libgme b/external/libgme
new file mode 160000
index 00000000..d5ae8555
--- /dev/null
+++ b/external/libgme
@@ -0,0 +1 @@
+Subproject commit d5ae855592c01ee2e253073c0afc2d89361e50bf
diff --git a/sdl2_mixer-config.cmake.in b/sdl2_mixer-config.cmake.in
index c394a09a..a2eaf7e5 100644
--- a/sdl2_mixer-config.cmake.in
+++ b/sdl2_mixer-config.cmake.in
@@ -20,6 +20,8 @@ else()
     set(SDL2MIXER_FLAC              0)
 endif()
 
+set(SDL2MIXER_GME                   @SDL2MIXER_GME@)
+
 set(SDL2MIXER_MOD_MODPLUG           @SDL2MIXER_MOD_MODPLUG@)
 set(SDL2MIXER_MOD_XMP               @SDL2MIXER_MOD_XMP@)
 set(SDL2MIXER_MOD_XMP_LITE          @SDL2MIXER_MOD_XMP_LITE@)