From d08522274d1b34849db953a9e41ca6268be1d0e0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 2 Jun 2013 00:35:46 -0700 Subject: [PATCH] Switched Mac OS X framework to use weak linking on external libraries. This allows someone to just remove the smpeg2.framework if they don't want MP3 support, for example. The weak import attribute is necessary to prevent the optimizer from eliminating the symbol NULL check. --- Xcode/SDL_mixer.xcodeproj/project.pbxproj | 50 +++++++++++++---------- dynamic_flac.c | 12 +++++- dynamic_mod.c | 12 +++++- dynamic_mp3.c | 12 +++++- dynamic_ogg.c | 12 +++++- music.c | 2 +- 6 files changed, 73 insertions(+), 27 deletions(-) diff --git a/Xcode/SDL_mixer.xcodeproj/project.pbxproj b/Xcode/SDL_mixer.xcodeproj/project.pbxproj index db9e1a97..50c49d76 100755 --- a/Xcode/SDL_mixer.xcodeproj/project.pbxproj +++ b/Xcode/SDL_mixer.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 00938E1C108A36520009CF19 /* mikmod.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00938E1B108A36520009CF19 /* mikmod.framework */; }; 00938E33108A37800009CF19 /* load_flac.c in Sources */ = {isa = PBXBuildFile; fileRef = 00938E2B108A37800009CF19 /* load_flac.c */; }; 00938E34108A37800009CF19 /* load_flac.h in Headers */ = {isa = PBXBuildFile; fileRef = 00938E2C108A37800009CF19 /* load_flac.h */; }; 00938E35108A37800009CF19 /* music_flac.c in Sources */ = {isa = PBXBuildFile; fileRef = 00938E2D108A37800009CF19 /* music_flac.c */; }; @@ -32,11 +31,10 @@ 04A8FCA70A19CAEC0046373F /* dynamic_mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 04A8FCA40A19CAEC0046373F /* dynamic_mp3.c */; }; 04A8FCAB0A19CB070046373F /* dynamic_ogg.c in Sources */ = {isa = PBXBuildFile; fileRef = 04A8FCA90A19CB070046373F /* dynamic_ogg.c */; }; 04A8FCAC0A19CB070046373F /* dynamic_ogg.c in Sources */ = {isa = PBXBuildFile; fileRef = 04A8FCA90A19CB070046373F /* dynamic_ogg.c */; }; - AA64428F175AA7A500A2125A /* smpeg2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA64428E175AA7A500A2125A /* smpeg2.framework */; }; AA644290175AA7C900A2125A /* smpeg2.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = AA64428E175AA7A500A2125A /* smpeg2.framework */; }; - AA9F7DB514B15ADC00278D1E /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA9F7DB314B15ADC00278D1E /* Ogg.framework */; }; - AA9F7DB614B15ADC00278D1E /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA9F7DB414B15ADC00278D1E /* Vorbis.framework */; }; - AA9F7DB814B15AE700278D1E /* FLAC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA9F7DB714B15AE700278D1E /* FLAC.framework */; }; + AA6442D1175B181300A2125A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA6442D0175B181300A2125A /* AudioToolbox.framework */; }; + AA6442D3175B181D00A2125A /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA6442D2175B181D00A2125A /* AudioUnit.framework */; }; + AA6442D5175B185800A2125A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA6442D4175B185800A2125A /* CoreServices.framework */; }; AA9F7DB914B15D3300278D1E /* FLAC.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = AA9F7DB714B15AE700278D1E /* FLAC.framework */; }; AA9F7DBA14B15D4100278D1E /* mikmod.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 00938E1B108A36520009CF19 /* mikmod.framework */; }; AA9F7DBB14B15D4400278D1E /* Ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = AA9F7DB314B15ADC00278D1E /* Ogg.framework */; }; @@ -212,6 +210,9 @@ 5CC1B89B012FB8CD7F000001 /* wavestream.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = wavestream.c; path = ../wavestream.c; sourceTree = ""; }; 5CC1B89C012FB8CD7F000001 /* wavestream.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = wavestream.h; path = ../wavestream.h; sourceTree = ""; }; AA64428E175AA7A500A2125A /* smpeg2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = smpeg2.framework; path = Frameworks/smpeg2.framework; sourceTree = ""; }; + AA6442D0175B181300A2125A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + AA6442D2175B181D00A2125A /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; + AA6442D4175B185800A2125A /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; AA9F7DB314B15ADC00278D1E /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = Frameworks/Ogg.framework; sourceTree = ""; }; AA9F7DB414B15ADC00278D1E /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = Frameworks/Vorbis.framework; sourceTree = ""; }; AA9F7DB714B15AE700278D1E /* FLAC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FLAC.framework; path = Frameworks/FLAC.framework; sourceTree = ""; }; @@ -241,12 +242,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + AA6442D3175B181D00A2125A /* AudioUnit.framework in Frameworks */, + AA6442D1175B181300A2125A /* AudioToolbox.framework in Frameworks */, + AA6442D5175B185800A2125A /* CoreServices.framework in Frameworks */, BE1FA90207AF96B2004B6283 /* SDL2.framework in Frameworks */, - 00938E1C108A36520009CF19 /* mikmod.framework in Frameworks */, - AA9F7DB514B15ADC00278D1E /* Ogg.framework in Frameworks */, - AA9F7DB614B15ADC00278D1E /* Vorbis.framework in Frameworks */, - AA9F7DB814B15AE700278D1E /* FLAC.framework in Frameworks */, - AA64428F175AA7A500A2125A /* smpeg2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -385,6 +384,9 @@ BE1FA8AD07AF95DC004B6283 /* Linked Frameworks */ = { isa = PBXGroup; children = ( + AA6442D0175B181300A2125A /* AudioToolbox.framework */, + AA6442D2175B181D00A2125A /* AudioUnit.framework */, + AA6442D4175B185800A2125A /* CoreServices.framework */, AA9F7DB714B15AE700278D1E /* FLAC.framework */, 00938E1B108A36520009CF19 /* mikmod.framework */, AA9F7DB314B15ADC00278D1E /* Ogg.framework */, @@ -747,12 +749,14 @@ INSTALL_PATH = "@executable_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks"; OTHER_LDFLAGS = ( - "-framework", - AudioToolbox, - "-framework", - AudioUnit, - "-framework", - CoreServices, + "-weak_framework", + FLAC, + "-weak_framework", + mikmod, + "-weak_framework", + smpeg2, + "-weak_framework", + Vorbis, ); WRAPPER_EXTENSION = framework; }; @@ -771,12 +775,14 @@ INSTALL_PATH = "@executable_path/../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "@loader_path/Frameworks"; OTHER_LDFLAGS = ( - "-framework", - AudioToolbox, - "-framework", - AudioUnit, - "-framework", - CoreServices, + "-weak_framework", + FLAC, + "-weak_framework", + mikmod, + "-weak_framework", + smpeg2, + "-weak_framework", + Vorbis, ); WRAPPER_EXTENSION = framework; }; diff --git a/dynamic_flac.c b/dynamic_flac.c index 50f0d7c5..9a57b5c1 100644 --- a/dynamic_flac.c +++ b/dynamic_flac.c @@ -25,7 +25,7 @@ #ifdef FLAC_MUSIC #include "SDL_loadso.h" - +#include "SDL_mixer.h" #include "dynamic_flac.h" flac_loader flac = { @@ -142,6 +142,16 @@ void Mix_QuitFLAC() int Mix_InitFLAC() { if ( flac.loaded == 0 ) { +#ifdef __MACOSX__ + extern FLAC__StreamDecoder *FLAC__stream_decoder_new(void) __attribute__((weak_import)); + if ( FLAC__stream_decoder_new == NULL ) + { + /* Missing weakly linked framework */ + Mix_SetError("Missing FLAC.framework"); + return -1; + } +#endif // __MACOSX__ + flac.FLAC__stream_decoder_new = FLAC__stream_decoder_new; flac.FLAC__stream_decoder_delete = FLAC__stream_decoder_delete; flac.FLAC__stream_decoder_init_stream = diff --git a/dynamic_mod.c b/dynamic_mod.c index 0862f007..a1e42a23 100644 --- a/dynamic_mod.c +++ b/dynamic_mod.c @@ -22,7 +22,7 @@ #ifdef MOD_MUSIC #include "SDL_loadso.h" - +#include "SDL_mixer.h" #include "dynamic_mod.h" mikmod_loader mikmod = { @@ -238,6 +238,16 @@ void Mix_QuitMOD() int Mix_InitMOD() { if ( mikmod.loaded == 0 ) { +#ifdef __MACOSX__ + extern void Player_Start(MODULE*) __attribute__((weak_import)); + if ( Player_Start == NULL ) + { + /* Missing weakly linked framework */ + Mix_SetError("Missing mikmod.framework"); + return -1; + } +#endif // __MACOSX__ + mikmod.MikMod_Exit = MikMod_Exit; mikmod.MikMod_InfoDriver = MikMod_InfoDriver; mikmod.MikMod_InfoLoader = MikMod_InfoLoader; diff --git a/dynamic_mp3.c b/dynamic_mp3.c index 83a2a667..0ed38c57 100644 --- a/dynamic_mp3.c +++ b/dynamic_mp3.c @@ -22,7 +22,7 @@ #ifdef MP3_MUSIC #include "SDL_loadso.h" - +#include "SDL_mixer.h" #include "dynamic_mp3.h" smpeg_loader smpeg = { @@ -140,6 +140,16 @@ void Mix_QuitMP3() int Mix_InitMP3() { if ( smpeg.loaded == 0 ) { +#ifdef __MACOSX__ + extern SMPEG* SMPEG_new_rwops(SDL_RWops*, SMPEG_Info*, int, int) __attribute__((weak_import)); + if ( SMPEG_new_rwops == NULL ) + { + /* Missing weakly linked framework */ + Mix_SetError("Missing smpeg2.framework"); + return -1; + } +#endif // __MACOSX__ + smpeg.SMPEG_actualSpec = SMPEG_actualSpec; smpeg.SMPEG_delete = SMPEG_delete; smpeg.SMPEG_enableaudio = SMPEG_enableaudio; diff --git a/dynamic_ogg.c b/dynamic_ogg.c index 1225861c..a4b089a2 100644 --- a/dynamic_ogg.c +++ b/dynamic_ogg.c @@ -22,7 +22,7 @@ #ifdef OGG_MUSIC #include "SDL_loadso.h" - +#include "SDL_mixer.h" #include "dynamic_ogg.h" vorbis_loader vorbis = { @@ -106,6 +106,16 @@ void Mix_QuitOgg() int Mix_InitOgg() { if ( vorbis.loaded == 0 ) { +#ifdef __MACOSX__ + extern int ov_open_callbacks(void*, OggVorbis_File*, const char*, long, ov_callbacks) __attribute__((weak_import)); + if ( ov_open_callbacks == NULL ) + { + /* Missing weakly linked framework */ + Mix_SetError("Missing Vorbis.framework"); + return -1; + } +#endif // __MACOSX__ + vorbis.ov_clear = ov_clear; vorbis.ov_info = ov_info; vorbis.ov_open_callbacks = ov_open_callbacks; diff --git a/music.c b/music.c index ad9b79cb..d268fba8 100644 --- a/music.c +++ b/music.c @@ -575,7 +575,7 @@ Mix_Music *Mix_LoadMUS(const char *file) Mix_SetError(""); music = Mix_LoadMUSType_RW(src, type, SDL_TRUE); if ( music == NULL && Mix_GetError()[0] == '\0' ) { - Mix_SetError("Couldn't open '%s'", file); + Mix_SetError("Unrecognized music format"); } return music; }