game-music-emu: use a version script to export symbols.

From 9bebd95995f71fa76af131145531f8227784e292 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Tue, 24 Oct 2023 19:30:02 +0300
Subject: [PATCH] use a version script to export symbols.

helps with hiding C++ STL e.g. for Android: https://developer.android.com/ndk/guides/middleware-vendors

Closes: https://github.com/libgme/game-music-emu/issues/62

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
---
 gme/CMakeLists.txt | 50 ++++++++++++++++++++++++++++++++++++
 gme/gme.exports    | 63 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 gme/gme.exports

diff --git a/gme/CMakeLists.txt b/gme/CMakeLists.txt
index f787d80..22e4d84 100644
--- a/gme/CMakeLists.txt
+++ b/gme/CMakeLists.txt
@@ -285,6 +285,56 @@ else()
   message(STATUS "Zlib-Compressed formats excluded")
 endif()
 
+# Extract symbols from gme.exports
+file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/gme.exports" gme_exports_strings)
+set(gme_exports)
+foreach(gme_export_string ${gme_exports_strings})
+    string(STRIP "${gme_export_string}" gme_export_string)
+    string(SUBSTRING "${gme_export_string}" 0 1 gme_export_first_char)
+    if(gme_export_string AND NOT gme_export_first_char STREQUAL "#")
+        list(APPEND gme_exports ${gme_export_string})
+    endif()
+endforeach()
+
+# Add a version script to hide the c++ STL
+if(APPLE)
+    set(gme_syms "")
+    foreach(gme_export ${gme_exports})
+        set(gme_syms "${gme_syms}_${gme_export}\n")
+    endforeach()
+
+    # Use an intermediate 'gme_generated.sym' file to avoid a relink every time CMake runs
+    set(temporary_sym_file "${CMAKE_CURRENT_BINARY_DIR}/gme_generated.sym")
+    set(generated_sym_file "${CMAKE_CURRENT_BINARY_DIR}/gme.sym")
+    file(WRITE "${temporary_sym_file}" "${gme_syms}")
+    execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${temporary_sym_file}" "${generated_sym_file}")
+
+    set_property(TARGET gme APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-exported_symbols_list,'${generated_sym_file}'")
+    set_property(TARGET gme APPEND PROPERTY LINK_DEPENDS "${generated_sym_file}")
+elseif(UNIX)
+    set(gme_syms "{\n  global:\n")
+    foreach(gme_export ${gme_exports})
+        set(gme_syms "${gme_syms}    ${gme_export};\n")
+    endforeach()
+    set(gme_syms "${gme_syms}  local: *;\n};\n")
+
+    # Use an intermediate 'gme_generated.sym' file to avoid a relink every time CMake runs
+    set(temporary_sym_file "${CMAKE_CURRENT_BINARY_DIR}/gme_generated.sym")
+    set(generated_sym_file "${CMAKE_CURRENT_BINARY_DIR}/gme.sym")
+    file(WRITE "${temporary_sym_file}" "${gme_syms}")
+    execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${temporary_sym_file}" "${generated_sym_file}")
+
+    cmake_push_check_state()
+    set(CMAKE_REQUIRED_FLAGS "-Wl,-version-script='${generated_sym_file}'")
+    check_cxx_source_compiles("int main() { return 0;}" LINKER_SUPPORTS_VERSION_SCRIPT)
+    cmake_pop_check_state()
+
+    if(LINKER_SUPPORTS_VERSION_SCRIPT)
+        set_property(TARGET gme APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-version-script='${generated_sym_file}'")
+        set_property(TARGET gme APPEND PROPERTY LINK_DEPENDS "${generated_sym_file}")
+    endif()
+endif()
+
 # The version is the release.  The "soversion" is the API version.  As long
 # as only build fixes are performed (i.e. no backwards-incompatible changes
 # to the API), the SOVERSION should be the same even when bumping up VERSION.
diff --git a/gme/gme.exports b/gme/gme.exports
new file mode 100644
index 0000000..57636f4
--- /dev/null
+++ b/gme/gme.exports
@@ -0,0 +1,63 @@
+# List of all exported symbols
+gme_autoload_playback_limit
+gme_clear_playlist
+gme_delete
+gme_enable_accuracy
+gme_equalizer
+gme_free_info
+gme_identify_extension
+gme_identify_file
+gme_identify_header
+gme_ignore_silence
+gme_load_custom
+gme_load_data
+gme_load_file
+gme_load_m3u
+gme_load_m3u_data
+gme_multi_channel
+gme_mute_voice
+gme_mute_voices
+gme_new_emu
+gme_new_emu_multi_channel
+gme_open_data
+gme_open_file
+gme_play
+gme_seek
+gme_seek_samples
+gme_set_autoload_playback_limit
+gme_set_equalizer
+gme_set_fade
+gme_set_stereo_depth
+gme_set_tempo
+gme_set_user_cleanup
+gme_set_user_data
+gme_start_track
+gme_tell
+gme_tell_samples
+gme_track_count
+gme_track_ended
+gme_track_info
+gme_type
+gme_type_extension
+gme_type_list
+gme_type_multitrack
+gme_type_system
+gme_user_data
+gme_voice_count
+gme_voice_name
+gme_warning
+gme_wrong_file_type
+gme_ay_type
+gme_gbs_type
+gme_gym_type
+gme_hes_type
+gme_kss_type
+gme_nsf_type
+gme_nsfe_type
+gme_sap_type
+gme_spc_type
+gme_vgm_type
+gme_vgz_type
+gme_disable_echo
+gme_set_fade_msecs
+gme_rsn_type