game-music-emu: Merge branch 'master' of git@bitbucket.org:mpyne/game-music-emu.git (c5cc3)

From cdf332f29c719a672920b869680a481a23ade83b Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Fri, 6 Oct 2023 06:03:20 +0300
Subject: [PATCH] cmake clean-ups and updates.

- Extract GME_VERSION from gme.h using cmake regex utils.
- Make as much of define, link library, etc, private to libgme.
- Link with -Wl,-no-undefined if available.
- Link to libm, if necessary.
- Generate 'gen_types.h' instead of 'gme_types.h' and make its
  user gme.cpp aware of it (for out-of-tree builds, bug/38.)
- Require C++11 for whole project using cmake properties.
- Use cmake properties for visibility attributes.
- Change ubsan option to OFF by default.
- General cmake beautification.
- Make ZLIB an option, GME_ZLIB, defaulting to on.
- Renamed GME_UNRAR_RSN to GME_UNRAR.
- Bump minimum required cmake version to 3.3.
- Possibly a few other minor things.

Closes: https://bitbucket.org/mpyne/game-music-emu/pull-requests/37
Fixes: https://bitbucket.org/mpyne/game-music-emu/issues/38

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
Co-authored-by: Johannes Kauffmann <johanneskauffmann@hotmail.com>
---
 CMakeLists.txt        | 162 ++++++++++--------------------
 gme/CMakeLists.txt    | 227 ++++++++++++++++++++++++++++--------------
 gme/gme.cpp           |   4 +
 gme/libgme.pc.in      |   2 +-
 player/CMakeLists.txt |  17 ++--
 readme.txt            |   2 +-
 6 files changed, 222 insertions(+), 192 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 214a832..e60a616 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,131 +1,77 @@
 # CMake project definition file.
-cmake_minimum_required(VERSION 3.0...3.5 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.3...3.5)
 project(libgme)
 
-include (TestBigEndian)
-include (CheckCXXCompilerFlag)
-include (CTest)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
 
-# When version is changed, also change the one in gme/gme.h to match
-set(GME_VERSION 0.6.4 CACHE INTERNAL "libgme Version")
+include(CMakePushCheckState)
+include(CheckCXXSourceCompiles)
+include(TestBigEndian)
+include(GNUInstallDirs)
+include(CTest)
 
-# Default emulators to build (all of them! ;)
-if (NOT DEFINED USE_GME_AY)
-    SET(USE_GME_AY 1 CACHE BOOL "Enable support for Spectrum ZX music emulation")
-endif()
-
-if (NOT DEFINED USE_GME_GBS)
-    SET(USE_GME_GBS 1 CACHE BOOL "Enable support for Game Boy music emulation")
-endif()
-
-if (NOT DEFINED USE_GME_GYM)
-    SET(USE_GME_GYM 1 CACHE BOOL "Enable Sega MegaDrive/Genesis music emulation")
-endif()
-
-if (NOT DEFINED USE_GME_HES)
-    SET(USE_GME_HES 1 CACHE BOOL "Enable PC Engine/TurboGrafx-16 music emulation")
-endif()
-
-if (NOT DEFINED USE_GME_KSS)
-    SET(USE_GME_KSS 1 CACHE BOOL "Enable MSX or other Z80 systems music emulation")
-endif()
-
-if (NOT DEFINED USE_GME_NSF)
-    SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation")
-endif()
-
-if (NOT DEFINED USE_GME_NSFE)
-    SET(USE_GME_NSFE 1 CACHE BOOL "Enable NES NSFE and NSF music emulation")
-endif()
-
-if (NOT DEFINED USE_GME_SAP)
-    SET(USE_GME_SAP 1 CACHE BOOL "Enable Atari SAP music emulation")
+file(READ "gme/gme.h" GME_GME_H)
+string(REGEX MATCH "/\\* Game_Music_Emu ([0-9]+)\\.([0-9]+).([0-9]+) \\*/" RE_GME_VERSION "${GME_GME_H}")
+if(NOT RE_GME_VERSION)
+    message(FATAL_ERROR "Unable to extract gme version from gme/gme.h")
 endif()
+set(GME_VERSION_MAJOR "${CMAKE_MATCH_1}")
+set(GME_VERSION_MINOR "${CMAKE_MATCH_2}")
+set(GME_VERSION_PATCH "${CMAKE_MATCH_3}")
+set(GME_VERSION "${GME_VERSION_MAJOR}.${GME_VERSION_MINOR}.${GME_VERSION_PATCH}")
 
-if (NOT DEFINED USE_GME_SPC)
-    SET(USE_GME_SPC 1 CACHE BOOL "Enable SNES SPC music emulation")
-endif()
-
-if (NOT DEFINED GME_UNRAR_RSN)
-    option(GME_UNRAR_RSN "Enable SPC RSN format (optional, requires UnRAR library)" ON)
-endif()
-
-if (NOT DEFINED GME_SPC_ISOLATED_ECHO_BUFFER)
-    option(GME_SPC_ISOLATED_ECHO_BUFFER "Enable isolated echo buffer on SPC emulator to allow correct playing of \"dodgy\" SPC files made for various ROM hacks ran on ZSNES" OFF)
-endif()
-
-if (NOT DEFINED USE_GME_VGM)
-    SET(USE_GME_VGM 1 CACHE BOOL "Enable Sega VGM/VGZ music emulation")
-endif()
-
-if (NOT DEFINED GME_YM2612_EMU)
-    SET(GME_YM2612_EMU "Nuked" CACHE STRING "Which YM2612 emulator to use: \"Nuked\" (LGPLv2.1+), \"MAME\" (GPLv2+), or \"GENS\" (LGPLv2.1+)")
-endif()
-
-if (USE_GME_NSFE AND NOT USE_GME_NSF)
-    MESSAGE(" -- NSFE support requires NSF, enabling NSF support. --")
-    SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
+# Default emulators to build (all of them! ;)
+option(USE_GME_AY "Enable support for Spectrum ZX music emulation" ON)
+option(USE_GME_GBS "Enable support for Game Boy music emulation" ON)
+option(USE_GME_GYM "Enable Sega MegaDrive/Genesis music emulation" ON)
+option(USE_GME_HES "Enable PC Engine/TurboGrafx-16 music emulation" ON)
+option(USE_GME_KSS "Enable MSX or other Z80 systems music emulation" ON)
+option(USE_GME_NSF "Enable NES NSF music emulation" ON)
+option(USE_GME_NSFE "Enable NES NSFE and NSF music emulation" ON)
+option(USE_GME_SAP "Enable Atari SAP music emulation" ON)
+option(USE_GME_SPC "Enable SNES SPC music emulation" ON)
+option(USE_GME_VGM "Enable Sega VGM/VGZ music emulation" ON)
+
+option(GME_SPC_ISOLATED_ECHO_BUFFER "Enable isolated echo buffer on SPC emulator to allow correct playing of \"dodgy\" SPC files made for various ROM hacks ran on ZSNES" OFF)
+option(GME_ZLIB "Enable GME to support compressed sound formats" ON)
+option(GME_UNRAR "Enable SPC RSN format (optional, requires UnRAR library)" ON)
+
+set(GME_YM2612_EMU "Nuked" CACHE STRING "Which YM2612 emulator to use: \"Nuked\" (LGPLv2.1+), \"MAME\" (GPLv2+), or \"GENS\" (LGPLv2.1+)")
+set(GME_YM2612_EMU_CHOICES "Nuked;MAME;GENS")
+set_property(CACHE GME_YM2612_EMU PROPERTY STRINGS "${GME_YM2612_EMU_CHOICES}")
+
+if(USE_GME_NSFE AND NOT USE_GME_NSF)
+    message(STATUS "NSFE support requires NSF, enabling NSF support.")
+    set(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
 endif()
 
 option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
+option(BUILD_FRAMEWORK "Build framework instead of dylib on macOS" OFF)
 
-option(ENABLE_UBSAN "Enable Undefined Behavior Sanitizer error-checking" ON)
+option(ENABLE_UBSAN "Enable Undefined Behavior Sanitizer error-checking" OFF)
 
-option(BUILD_FRAMEWORK "Build framework instead of dylib (on macOS)" OFF)
 
+set (CMAKE_CXX_STANDARD  11)
+set (CMAKE_CXX_STANDARD_REQUIRED ON)
+set (CMAKE_CXX_EXTENSIONS OFF)
 
 test_big_endian(WORDS_BIGENDIAN)
-if(WORDS_BIGENDIAN)
-    add_definitions(-DBLARGG_BIG_ENDIAN=1)
-else()
-    add_definitions(-DBLARGG_LITTLE_ENDIAN=1)
-endif()
 
-# static builds need to find static zlib (and static forms of other needed
-# libraries.  Ensure CMake looks only for static libs if we're doing a static
-# build.  See https://stackoverflow.com/a/44738756
-if(NOT BUILD_SHARED_LIBS)
-  if(MSVC)
-    set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
-  else()
-    set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
-  endif()
+if(MSVC)
+    add_compile_options(/W2)
+elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+    add_compile_options(-Wall -W -Wextra)
 endif()
 
 # Check for GCC/Clang "visibility" support.
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
-
-    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -W -Wextra")
-    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
-
-    # Assume we have visibility support on any compiler that supports C++11
-    add_definitions (-DLIBGME_VISIBILITY)
-    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
-    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden")
-
-    # Try to protect against undefined behavior from signed integer overflow
-    # This has caused miscompilation of code already and there are other
-    # potential uses; see https://bitbucket.org/mpyne/game-music-emu/issues/18/
-    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwrapv")
-
-    if (USE_GME_SPC)
-        list(APPEND CMAKE_MODULE_PATH "${CMAKE_HOME_DIRECTORY}/cmake")
-        find_package(UNRAR QUIET)
-        if (UNRAR_FOUND AND NOT WIN32)
-            # POSIX Threading for unRAR
-            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
-        endif()
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" AND ENABLE_UBSAN)
+    # GCC needs -static-libubsan
+    if(NOT BUILD_SHARED_LIBS AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -static-libubsan")
+    else()
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
     endif()
-
-    if (ENABLE_UBSAN)
-        # GCC needs -static-libubsan
-        if (NOT BUILD_SHARED_LIBS AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -static-libubsan")
-        else()
-            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
-        endif()
-    endif()
-endif ()
+endif()
 
 # Shared library defined here
 add_subdirectory(gme)
diff --git a/gme/CMakeLists.txt b/gme/CMakeLists.txt
index eb0bc97..a2f413d 100644
--- a/gme/CMakeLists.txt
+++ b/gme/CMakeLists.txt
@@ -14,55 +14,71 @@ set(libgme_SRCS Blip_Buffer.cpp
                 Music_Emu.cpp
                 )
 
-find_package(ZLIB QUIET)
+# static builds need to find static zlib (and static forms of other needed
+# libraries.  Ensure CMake looks only for static libs if we're doing a static
+# build.  See https://stackoverflow.com/a/44738756
+if(NOT BUILD_SHARED_LIBS)
+  if(MSVC)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
+  else()
+    set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+  endif()
+endif()
+
+if(GME_ZLIB)
+    find_package(ZLIB QUIET)
+endif()
+if (USE_GME_SPC AND GME_UNRAR)
+    find_package(UNRAR QUIET)
+endif()
 
 # Ay_Apu is very popular around here
-if (USE_GME_AY OR USE_GME_KSS)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_AY OR USE_GME_KSS)
+    list(APPEND libgme_SRCS
                 Ay_Apu.cpp
         )
 endif()
 
 # so is Ym2612_Emu
-if (USE_GME_VGM OR USE_GME_GYM)
+if(USE_GME_VGM OR USE_GME_GYM)
     if(GME_YM2612_EMU STREQUAL "Nuked")
         add_definitions(-DVGM_YM2612_NUKED)
-        set(libgme_SRCS ${libgme_SRCS}
+        list(APPEND libgme_SRCS
                     Ym2612_Nuked.cpp
             )
-        message("VGM/GYM: Nuked OPN2 emulator will be used")
+        message(STATUS "VGM/GYM: Nuked OPN2 emulator will be used")
     elseif(GME_YM2612_EMU STREQUAL "MAME")
         add_definitions(-DVGM_YM2612_MAME)
-        set(libgme_SRCS ${libgme_SRCS}
+        list(APPEND libgme_SRCS
                     Ym2612_MAME.cpp
             )
-        message("VGM/GYM: MAME YM2612 emulator will be used")
+        message(STATUS "VGM/GYM: MAME YM2612 emulator will be used")
     else()
         add_definitions(-DVGM_YM2612_GENS)
-        set(libgme_SRCS ${libgme_SRCS}
+        list(APPEND libgme_SRCS
                     Ym2612_GENS.cpp
             )
-        message("VGM/GYM: GENS 2.10 emulator will be used")
+        message(STATUS "VGM/GYM: GENS 2.10 emulator will be used")
     endif()
 endif()
 
 # But none are as popular as Sms_Apu
-if (USE_GME_VGM OR USE_GME_GYM OR USE_GME_KSS)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_VGM OR USE_GME_GYM OR USE_GME_KSS)
+    list(APPEND libgme_SRCS
                 Sms_Apu.cpp
         )
 endif()
 
-if (USE_GME_AY)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_AY)
+    list(APPEND libgme_SRCS
               # Ay_Apu.cpp included earlier
                 Ay_Cpu.cpp
                 Ay_Emu.cpp
         )
 endif()
 
-if (USE_GME_GBS)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_GBS)
+    list(APPEND libgme_SRCS
                 Gb_Apu.cpp
                 Gb_Cpu.cpp
                 Gb_Oscs.cpp
@@ -70,24 +86,24 @@ if (USE_GME_GBS)
         )
 endif()
 
-if (USE_GME_GYM)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_GYM)
+    list(APPEND libgme_SRCS
               # Sms_Apu.cpp included earlier
               # Ym2612_Emu.cpp included earlier
                 Gym_Emu.cpp
         )
 endif()
 
-if (USE_GME_HES)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_HES)
+    list(APPEND libgme_SRCS
                 Hes_Apu.cpp
                 Hes_Cpu.cpp
                 Hes_Emu.cpp
         )
 endif()
 
-if (USE_GME_KSS)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_KSS)
+    list(APPEND libgme_SRCS
               # Ay_Apu.cpp included earlier
               # Sms_Apu.cpp included earlier
                 Kss_Cpu.cpp
@@ -96,8 +112,8 @@ if (USE_GME_KSS)
         )
 endif()
 
-if (USE_GME_NSF OR USE_GME_NSFE)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_NSF OR USE_GME_NSFE)
+    list(APPEND libgme_SRCS
                 Nes_Apu.cpp
                 Nes_Cpu.cpp
                 Nes_Fme7_Apu.cpp
@@ -112,35 +128,35 @@ if (USE_GME_NSF OR USE_GME_NSFE)
         )
 endif()
 
-if (USE_GME_NSFE)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_NSFE)
+    list(APPEND libgme_SRCS
                 Nsfe_Emu.cpp
         )
 endif()
 
-if (USE_GME_SAP)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_SAP)
+    list(APPEND libgme_SRCS
                 Sap_Apu.cpp
                 Sap_Cpu.cpp
                 Sap_Emu.cpp
         )
 endif()
 
-if (USE_GME_SPC)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_SPC)
+    list(APPEND libgme_SRCS
                 Snes_Spc.cpp
                 Spc_Cpu.cpp
                 Spc_Dsp.cpp
                 Spc_Emu.cpp
                 Spc_Filter.cpp
         )
-    if (GME_SPC_ISOLATED_ECHO_BUFFER)
+    if(GME_SPC_ISOLATED_ECHO_BUFFER)
         add_definitions(-DSPC_ISOLATED_ECHO_BUFFER)
     endif()
 endif()
 
-if (USE_GME_VGM)
-    set(libgme_SRCS ${libgme_SRCS}
+if(USE_GME_VGM)
+    list(APPEND libgme_SRCS
               # Sms_Apu.cpp included earlier
               # Ym2612_Emu.cpp included earlier
                 Vgm_Emu.cpp
@@ -154,51 +170,116 @@ set (EXPORTED_HEADERS gme.h)
 
 # while building a macOS framework, exported headers must be in the source
 # list, or the header files aren't copied to the bundle.
-if (BUILD_FRAMEWORK)
+if(BUILD_FRAMEWORK)
     set(libgme_SRCS ${libgme_SRCS} ${EXPORTED_HEADERS})
 endif()
 
+# Add library to be compiled.
+add_library(gme ${libgme_SRCS})
+add_library(gme::gme ALIAS gme)
+
+set_property(TARGET gme PROPERTY C_VISIBILITY_PRESET "hidden")
+set_property(TARGET gme PROPERTY VISIBILITY_INLINES_HIDDEN TRUE)
+set_property(TARGET gme PROPERTY CXX_VISIBILITY_PRESET "hidden")
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+    target_compile_definitions(gme PRIVATE LIBGME_VISIBILITY)
+endif()
+
 # On some platforms we may need to change headers or whatnot based on whether
 # we're building the library or merely using the library. The following is
 # only defined when building the library to allow us to tell which is which.
-add_definitions(-DBLARGG_BUILD_DLL)
+set_property(TARGET gme PROPERTY DEFINE_SYMBOL BLARGG_BUILD_DLL)
 
-# For the gme_types.h
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
+target_compile_definitions(gme PRIVATE GEN_TYPES_H)
+if(WORDS_BIGENDIAN)
+    target_compile_definitions(gme PRIVATE BLARGG_BIG_ENDIAN=1)
+else()
+    target_compile_definitions(gme PRIVATE BLARGG_LITTLE_ENDIAN=1)
+endif()
 
-# Add library to be compiled.
-add_library(gme ${libgme_SRCS})
+# Try to protect against undefined behavior from signed integer overflow
+# This has caused miscompilation of code already and there are other
+# potential uses; see https://bitbucket.org/mpyne/game-music-emu/issues/18/
+target_compile_options(gme PRIVATE -fwrapv)
 
-if(ZLIB_FOUND)
-    message(" ** ZLib library located, compressed file formats will be supported")
-    target_compile_definitions(gme PRIVATE -DHAVE_ZLIB_H)
-    target_include_directories(gme PRIVATE ${ZLIB_INCLUDE_DIRS})
-    target_link_libraries(gme ${ZLIB_LIBRARIES})
-    # Is not to be installed though
+target_include_directories(gme
+    PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"  # For gen_types.h
+    INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>"
+    INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
 
-    set(PKG_CONFIG_ZLIB -lz) # evaluated in libgme.pc.in
-else()
-    message("ZLib library not found, disabling support for compressed formats such as VGZ")
-endif()
+## FIXME: Properly find the C++ library !!!
+set(PC_LIBS -lstdc++)
 
-if(USE_GME_SPC AND GME_UNRAR_RSN)
-    if(UNRAR_FOUND)
-        message(" ** unRAR library located, the RSN file format will be supported")
-        target_compile_definitions(gme PRIVATE -DRARDLL)
-        if(RAR_HDR_UNRAR_H)
-            target_compile_definitions(gme PRIVATE -DRAR_HDR_UNRAR_H)
-        elseif(RAR_HDR_DLL_HPP)
-            target_compile_definitions(gme PRIVATE -DRAR_HDR_DLL_HPP)
-        endif()
-        target_include_directories(gme PRIVATE ${UNRAR_INCLUDE_DIRS})
-        target_link_libraries(gme ${UNRAR_LIBRARIES})
-        # Is not to be installed though
+if(NOT MSVC)
+    # Link with -no-undefined, if available
+    cmake_push_check_state()
+    set(CMAKE_REQUIRED_FLAGS "-Wl,-no-undefined")
+    check_cxx_source_compiles("int main(void) { return 0;}" LINKER_SUPPORTS_NO_UNDEFINED)
+    cmake_pop_check_state()
+    if(LINKER_SUPPORTS_NO_UNDEFINED)
+        set_property(TARGET gme APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-no-undefined")
+    endif()
 
-        set(PKG_CONFIG_UNRAR -lunrar) # evaluated in libgme.pc.in
-    else()
-        message("unRAR library not found, disabling support for the RSN file format")
+    # Link to libm, if necessary
+    check_cxx_source_compiles("
+        #include <math.h>
+        int main(int argc, char** argv) {
+            return (int) pow(argc, 2.5);
+        }" LIBM_NOT_NEEDED)
+    if(NOT LIBM_NOT_NEEDED)
+        cmake_push_check_state()
+        set(CMAKE_REQUIRED_LIBRARIES "-lm")
+        check_cxx_source_compiles("
+            #include <math.h>
+            int main(int argc, char** argv) {
+                return (int) pow(argc, 2.5);
+            }" HAVE_LIBM)
+        cmake_pop_check_state()
+        if(HAVE_LIBM)
+            target_link_libraries(gme PRIVATE -lm)
+            list(APPEND PC_LIBS -lm) # for libgme.pc
+        endif()
     endif()
 endif()
+
+if(USE_GME_SPC AND GME_UNRAR)
+  if(UNRAR_FOUND)
+      message(STATUS "UnRAR library located, the RSN file format will be supported")
+      target_compile_definitions(gme PRIVATE RARDLL)
+      if(RAR_HDR_UNRAR_H)
+          target_compile_definitions(gme PRIVATE RAR_HDR_UNRAR_H)
+      elseif(RAR_HDR_DLL_HPP)
+          target_compile_definitions(gme PRIVATE RAR_HDR_DLL_HPP)
+      endif()
+      target_include_directories(gme PRIVATE ${UNRAR_INCLUDE_DIRS})
+      target_link_libraries(gme PRIVATE ${UNRAR_LIBRARIES})
+      # Is not to be installed though
+      list(APPEND PC_LIBS -lunrar) # for libgme.pc
+      if (NOT WIN32) # POSIX Threading for unRAR
+          target_compile_options(gme PRIVATE -pthread)
+      endif()
+  else()
+      message(STATUS "** UnRAR library not found, disabling support for the RSN file format")
+  endif()
+else()
+  message(STATUS "RSN file format excluded")
+endif()
+
+if(GME_ZLIB)
+  if(ZLIB_FOUND)
+      message(STATUS "ZLib library located, compressed file formats will be supported")
+      target_compile_definitions(gme PRIVATE HAVE_ZLIB_H)
+      target_link_libraries(gme PRIVATE ZLIB::ZLIB)
+      # Is not to be installed though
+      list(APPEND PC_LIBS -lz) # for libgme.pc
+  else()
+      message(STATUS "** ZLib library not found, disabling support for compressed formats such as VGZ")
+  endif()
+else()
+  message(STATUS "Zlib-Compressed formats excluded")
+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.
@@ -219,18 +300,16 @@ if(BUILD_FRAMEWORK)
                    PUBLIC_HEADER "${EXPORTED_HEADERS}")
 endif()
 
-install(TARGETS gme LIBRARY DESTINATION lib${LIB_SUFFIX}
-                    RUNTIME DESTINATION bin # DLL platforms
-                    ARCHIVE DESTINATION lib # DLL platforms
-                    FRAMEWORK DESTINATION /Library/Frameworks) # macOS framework
+install(TARGETS gme LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}  # DLL platforms
+                    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}  # DLL platforms
+                    FRAMEWORK DESTINATION /Library/Frameworks)   # macOS framework
 
 
 # Run during cmake phase, so this is available during make
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gme_types.h.in
-    ${CMAKE_CURRENT_BINARY_DIR}/gme_types.h)
-
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libgme.pc.in
-    ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc @ONLY)
+configure_file(gme_types.h.in gen_types.h @ONLY)
+string(JOIN " " PC_LIBS ${PC_LIBS})
+configure_file(libgme.pc.in libgme.pc @ONLY)
 
 install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
diff --git a/gme/gme.cpp b/gme/gme.cpp
index 9c22ec8..be64d2b 100644
--- a/gme/gme.cpp
+++ b/gme/gme.cpp
@@ -2,7 +2,11 @@
 
 #include "Music_Emu.h"
 
+#ifdef GEN_TYPES_H
+#include "gen_types.h" /* same as gme_types.h but generated by build system */
+#else
 #include "gme_types.h"
+#endif
 #if !GME_DISABLE_STEREO_DEPTH
 #include "Effects_Buffer.h"
 #endif
diff --git a/gme/libgme.pc.in b/gme/libgme.pc.in
index 09a78b2..0f379d7 100644
--- a/gme/libgme.pc.in
+++ b/gme/libgme.pc.in
@@ -13,4 +13,4 @@ URL: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
 Version: @GME_VERSION@
 Cflags: -I${includedir}
 Libs: -L${libdir} -lgme
-Libs.private: -lstdc++ @PKG_CONFIG_ZLIB@ @PKG_CONFIG_UNRAR@
+Libs.private: @PC_LIBS@
diff --git a/player/CMakeLists.txt b/player/CMakeLists.txt
index c2d7138..f96c01e 100644
--- a/player/CMakeLists.txt
+++ b/player/CMakeLists.txt
@@ -7,16 +7,17 @@ set(player_SRCS Audio_Scope.cpp
                 player.cpp)
 
 if(SDL2_FOUND)
-    message(" ** SDL 2 library located, player demo is available to be built in the /player directory")
-
-    include_directories(${SDL2_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}
-        "${CMAKE_HOME_DIRECTORY}" "${CMAKE_HOME_DIRECTORY}/gme"
-        "${CMAKE_BINARY_DIR}/gme")
+    message(STATUS "SDL2 library located, player demo is available to be built in the /player directory")
 
     add_executable(gme_player ${player_SRCS})
-    target_link_libraries(gme_player ${SDL2_LIBRARIES} gme)
-
+    target_include_directories(gme_player PRIVATE
+        ${SDL2_INCLUDE_DIRS}
+        ${PROJECT_SOURCE_DIR}/gme
+    )
+    set_property(TARGET gme_player PROPERTY CXX_STANDARD_REQUIRED ON)
+    set_property(TARGET gme_player PROPERTY CXX_STANDARD 11)
+    target_link_libraries(gme_player PRIVATE ${SDL2_LIBRARIES} gme::gme)
     # Is not to be installed though
 else()
-    message("SDL library not found, disabling player demo build")
+    message(STATUS "** SDL library not found, disabling player demo build")
 endif()
diff --git a/readme.txt b/readme.txt
index eb3b560..9debfec 100644
--- a/readme.txt
+++ b/readme.txt
@@ -47,7 +47,7 @@ Getting Started
 Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
 all source files in gme/.
 
-Or, if you have CMake 2.6 or later, execute at a command prompt (from the
+Or, if you have CMake 3.3 or later, execute at a command prompt (from the
 extracted source directory):
 
     mkdir build