libsdl-org / SDL_mixer

An audio mixer that supports various file formats for Simple Directmedia Layer.
zlib License
430 stars 147 forks source link

[SDL2] Xcode does not add optional frameworks to dmg #638

Open madebr opened 1 month ago

madebr commented 1 month ago

The Create DMG target of SDL2_mixer's Xcode creates a dmg without the optional gme/ogg/opus/wavpack/xmp frameworks.

The dmg of official releases weights around 1.86MB, whereas a dmg created by xcode weight only 274kB.

SDL3_mixer might have the same issue.

This issue applies to SDL_image as well.

slouken commented 1 month ago

Here are the build.xcconfig files I use for the satellite libraries.

SDL_image 2.0:

//
//  build.xcconfig
//

// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974

// Uncomment these lines to enable AVIF support
// If you do this, you should run external/download.sh to download the decode libraries and add avif.framework to your application bundle.
CONFIG_PREPROCESSOR_DEFINITIONS = $(inherited) LOAD_AVIF
CONFIG_FRAMEWORK_LDFLAGS = $(inherited) -weak_framework avif

// Uncomment these lines to enable JPEG-XL support
// If you do this, you should run external/download.sh to download the decode libraries and add jxl.framework to your application bundle.
//CONFIG_PREPROCESSOR_DEFINITIONS = $(inherited) LOAD_JXL
//CONFIG_FRAMEWORK_LDFLAGS = $(inherited) -weak_framework jxl

// Uncomment these lines to enable WebP support
// If you do this, you should run external/download.sh to download the decode libraries and add webp.framework to your application bundle.
CONFIG_PREPROCESSOR_DEFINITIONS = $(inherited) LOAD_WEBP
CONFIG_FRAMEWORK_LDFLAGS = $(inherited) -weak_framework webp

SDL_image 3.0:

//
//  build.xcconfig
//

// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974

// Uncomment these lines to enable AVIF support
// If you do this, you should run external/download.sh to download the decode libraries and add avif.framework to your application bundle.
AVIF_PREPROCESSOR_DEFINITIONS = LOAD_AVIF
AVIF_FRAMEWORK_LDFLAGS = -weak_framework avif

// Uncomment these lines to enable JPEG-XL support
// If you do this, you should run external/download.sh to download the decode libraries and add jxl.framework to your application bundle.
JXL_PREPROCESSOR_DEFINITIONS = LOAD_JXL
JXL_FRAMEWORK_LDFLAGS = -weak_framework jxl

// Uncomment these lines to enable WebP support
// If you do this, you should run external/download.sh to download the decode libraries and add webp.framework to your application bundle.
WEBP_PREPROCESSOR_DEFINITIONS = LOAD_WEBP
WEBP_FRAMEWORK_LDFLAGS = -weak_framework webp

SDL_mixer 2.0:

//
//  build.xcconfig
//

// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974

// Uncomment these lines to enable native MIDI support on OSX
//MIDI_PREPROCESSOR_DEFINITIONS[sdk=macosx*] = MUSIC_MID_NATIVE

// Uncomment these lines to enable MOD support
// If you do this, you should run external/download.sh to download the decode libraries and add xmp.framework to your application bundle.
MOD_PREPROCESSOR_DEFINITIONS = MUSIC_MOD_XMP LIBXMP_HEADER=\"../external/libxmp/include/xmp.h\"
MOD_FRAMEWORK_LDFLAGS = -weak_framework xmp_lite

// Uncomment these lines to enable Opus support
// If you do this, you should run external/download.sh to download the decode libraries and add opus.framework to your application bundle.
OPUS_PREPROCESSOR_DEFINITIONS = MUSIC_OPUS
OPUS_FRAMEWORK_LDFLAGS = -weak_framework opus

SDL_mixer 3.0:

//
//  build.xcconfig
//

// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974

// Uncomment these lines to enable Game_Music_Emu support
// If you do this, you should run external/download.sh to download the decode libraries and add gme.framework to your application bundle.
GME_PREPROCESSOR_DEFINITIONS = MUSIC_GME
GME_FRAMEWORK_LDFLAGS = -weak_framework gme

// Uncomment these lines to enable native MIDI support on OSX
MIDI_PREPROCESSOR_DEFINITIONS[sdk=macosx*] = MUSIC_MID_NATIVE

// Uncomment these lines to enable MOD support
// If you do this, you should run external/download.sh to download the decode libraries and add xmp.framework to your application bundle.
MOD_PREPROCESSOR_DEFINITIONS = MUSIC_MOD_XMP LIBXMP_HEADER=\"../external/libxmp/include/xmp.h\"
MOD_FRAMEWORK_LDFLAGS = -weak_framework xmp

// Uncomment these lines to enable Opus support
// If you do this, you should run external/download.sh to download the decode libraries and add opus.framework to your application bundle.
OPUS_PREPROCESSOR_DEFINITIONS = MUSIC_OPUS
OPUS_FRAMEWORK_LDFLAGS = -weak_framework opus

// Uncomment these lines to enable WavPack support
// If you do this, you should run external/download.sh to download the decode libraries and add wavpack.framework to your application bundle.
WAVPACK_PREPROCESSOR_DEFINITIONS = MUSIC_WAVPACK MUSIC_WAVPACK_DSD
WAVPACK_FRAMEWORK_LDFLAGS = -weak_framework wavpack
madebr commented 1 month ago

Is this build procedure correct?

  1. Build the xcode projects of the 3rd party libraries
  2. Move this build.xcconfig file to the SDL_mixer xcode project, into the Xcode folder next to config.xcconfig
  3. Build the Create DMG target of the SDL_mixer xcode project
slouken commented 1 month ago

Is this build procedure correct?

  1. Build the xcode projects of the 3rd party libraries
  2. Move this build.xcconfig file to the SDL_mixer xcode project, into the Xcode folder next to config.xcconfig
  3. Build the Create DMG target of the SDL_mixer xcode project

I think you can skip step 1, if you've already downloaded the code to the external directory, Xcode will see the dependencies and build them.

madebr commented 1 month ago

I think you can skip step 1, if you've already downloaded the code to the external directory, Xcode will see the dependencies and build them.

You're right. I'd like to add these file to the repo, e.g. as Xcode/pkg-support/build.xcconfig. Is that okay for the xcode project? It won't be used accidentally when put in that location?

slouken commented 1 month ago

I think you can skip step 1, if you've already downloaded the code to the external directory, Xcode will see the dependencies and build them.

You're right. I'd like to add these file to the repo, e.g. as Xcode/pkg-support/build.xcconfig. Is that okay for the xcode project? It won't be used accidentally when put in that location?

Yep, that's fine.

madebr commented 1 month ago

Is the Xcode project of SDL3_image up-to-date or does it need other/extra arguments? Or perhaps we need to do things to enable the various platforms?

Running it with the arguments:

['xcodebuild', 'ONLY_ACTIVE_ARCH=NO', '-project', 'SDL3_image-3.0.0/Xcode/SDL_image.xcodeproj', '-scheme', 'SDL3_image.dmg', '-configuration', 'Release']

fails catastrophically like this.

(After copying build.xcconfig of above to the Xcode folder)

slouken commented 1 month ago

I'm not seeing the build error in that massive spew?

madebr commented 1 month ago

That's the thing. I don't know what's going wrong :)

slouken commented 1 month ago

Okay, this is necessary to build the projects, and I have a couple more fixes coming: git submodule update --init --recursive

slouken commented 1 month ago

Okay, I pushed avif build fixes, try now?

madebr commented 1 month ago

Yes! It successfully builds! Great job! https://github.com/madebr/SDL_image/actions/runs/11227263662/job/31209209996 It is around 23MB big.

madebr commented 1 month ago

How do I build only the core SDL3_image dmg archive without the external modules? I tried not copying the build.xcconfig and not checking out the submodules, but it fails somewhere. https://github.com/madebr/SDL_image/actions/runs/11227660619/job/31210262783#step:7:3752

I'd like to build a lean SDL3_image.dmg to test the CMake scripts with quick feedback.

slouken commented 1 month ago

You do need SDL, but the other external modules are optional.

slouken commented 1 month ago

FYI, I had the SDL_mixer build configs swapped, I've updated them above.

madebr commented 1 month ago

Thanks, I've updated them.

Building SDL3_mixer on ci, I see these link errors:

2024-10-08T21:30:50.6409800Z Undefined symbols for architecture arm64:
2024-10-08T21:30:50.6412310Z   "_native_midi_active", referenced from:
2024-10-08T21:30:50.6412910Z       _NATIVEMIDI_IsPlaying in music_nativemidi.o
2024-10-08T21:30:50.6413420Z   "_native_midi_detect", referenced from:
2024-10-08T21:30:50.6413900Z       _open_music_type in music.o
2024-10-08T21:30:50.6414420Z   "_native_midi_error", referenced from:
2024-10-08T21:30:50.6414960Z       _NATIVEMIDI_CreateFromIO in music_nativemidi.o
2024-10-08T21:30:50.6416680Z   "_native_midi_freesong", referenced from:
2024-10-08T21:30:50.6417520Z       _NATIVEMIDI_Delete in music_nativemidi.o
2024-10-08T21:30:50.6418030Z   "_native_midi_loadsong_IO", referenced from:
2024-10-08T21:30:50.6418520Z       _NATIVEMIDI_CreateFromIO in music_nativemidi.o
2024-10-08T21:30:50.6419520Z   "_native_midi_pause", referenced from:
2024-10-08T21:30:50.6421660Z       _NATIVEMIDI_Pause in music_nativemidi.o
2024-10-08T21:30:50.6422200Z   "_native_midi_resume", referenced from:
2024-10-08T21:30:50.6422750Z       _NATIVEMIDI_Resume in music_nativemidi.o
2024-10-08T21:30:50.6423480Z   "_native_midi_setvolume", referenced from:
2024-10-08T21:30:50.6424810Z       _NATIVEMIDI_SetVolume in music_nativemidi.o
2024-10-08T21:30:50.6426310Z   "_native_midi_start", referenced from:
2024-10-08T21:30:50.6426820Z       _NATIVEMIDI_Play in music_nativemidi.o
2024-10-08T21:30:50.6428120Z   "_native_midi_stop", referenced from:
2024-10-08T21:30:50.6431490Z       _NATIVEMIDI_Stop in music_nativemidi.o
2024-10-08T21:30:50.6437160Z ld: symbol(s) not found for architecture arm64
2024-10-08T21:30:50.6440440Z clang: error: linker command failed with exit code 1 (use -v to see invocation)
2024-10-08T21:30:50.6440820Z 

https://github.com/madebr/SDL_mixer/actions/runs/11243964073/job/31261052550

madebr commented 1 month ago

Can you also look at this SDL_ttf xcode error?

2024-10-09T02:31:21.7747910Z error: Build input file cannot be found: '/Users/runner/work/SDL_ttf/SDL_ttf/tardir/SDL3_ttf-3.0.0/Xcode/SDL_surface_textengine.c'. Did you forget to declare this file as an output of a script phase or custom build rule which produces it? (in target 'SDL3_ttf' from project 'SDL_ttf')

https://github.com/madebr/SDL_ttf/actions/runs/11247126037/job/31270084242#step:8:2195

slouken commented 1 month ago

Building SDL3_mixer on ci, I see these link errors:

2024-10-08T21:30:50.6409800Z Undefined symbols for architecture arm64:
2024-10-08T21:30:50.6412310Z   "_native_midi_active", referenced from:
2024-10-08T21:30:50.6412910Z       _NATIVEMIDI_IsPlaying in music_nativemidi.o

https://github.com/madebr/SDL_mixer/actions/runs/11243964073/job/31261052550

This looks like the native MIDI stuff is being enabled on iOS, which shouldn't happen because of the [sdk=macosx*] conditional. In any case, I've added a workaround which should fix that for you.

slouken commented 1 month ago

Can you also look at this SDL_ttf xcode error?

2024-10-09T02:31:21.7747910Z error: Build input file cannot be found: '/Users/runner/work/SDL_ttf/SDL_ttf/tardir/SDL3_ttf-3.0.0/Xcode/SDL_surface_textengine.c'. Did you forget to declare this file as an output of a script phase or custom build rule which produces it? (in target 'SDL3_ttf' from project 'SDL_ttf')

https://github.com/madebr/SDL_ttf/actions/runs/11247126037/job/31270084242#step:8:2195

Fixed!

madebr commented 1 month ago

Thanks! Everything's building. I've got a question about SDL3_mixer. Using the bottom build.xcconfig from https://github.com/libsdl-org/SDL_mixer/issues/638#issuecomment-2387181754, I get a dmg that is missing gme and wavpack.

Is that expected? https://github.com/madebr/SDL_mixer/actions/runs/11261633476

slouken commented 1 month ago

That's not expected, and I'm seeing that here as well. Digging in...

slouken commented 1 month ago

Fixed!

madebr commented 1 month ago

I've been told the ogg xcframework also needs to be part of the dmg because opus depends on it.

the ldd equivalent of macOS (otool -L) gives the following output for SDL3_mixer:

/Library/Frameworks/SDL3_mixer.xcframework/macos-arm64_x86_64/SDL3_mixer.framework/SDL3_mixer:
    @rpath/SDL3_mixer.framework/Versions/A/SDL3_mixer (compatibility version 1.0.0, current version 1.0.0)
    @rpath/gme.framework/Versions/A/gme (compatibility version 1.0.0, current version 1.0.0, weak)
    @rpath/xmp.framework/Versions/A/xmp (compatibility version 1.0.0, current version 1.0.0, weak)
    @rpath/opus.framework/Versions/A/opus (compatibility version 1.0.0, current version 1.0.0, weak)
    @rpath/wavpack.framework/Versions/A/wavpack (compatibility version 1.0.0, current version 1.0.0, weak)
    @rpath/SDL3.framework/Versions/A/SDL3 (compatibility version 106.0.0, current version 106.0.0)
    /System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox (compatibility version 1.0.0, current version 1000.0.0)
    /System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 1226.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1345.120.2)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 2503.1.0)

And for opus:

/Library/Frameworks/opus.xcframework/macos-arm64_x86_64/opus.framework/opus (architecture arm64):
    @rpath/opus.framework/Versions/A/opus (compatibility version 1.0.0, current version 1.0.0)
    @rpath/ogg.framework/Versions/A/ogg (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1345.120.2)

SDL3_Mixer's xcode project contains OPTIONAL_FRAMEWORKS="FLAC gme mpg123 ogg opus vorbis wavpack xmp", but not all of these are present in the xcframework. Is that intentional?

slouken commented 1 month ago

I've been told the ogg xcframework also needs to be part of the dmg because opus depends on it.

That's correct.

SDL3_Mixer's xcode project contains OPTIONAL_FRAMEWORKS="FLAC gme mpg123 ogg opus vorbis wavpack xmp", but not all of these are present in the xcframework. Is that intentional?

Nope, that's unintentional. I can add them.

madebr commented 1 month ago

Also:

Building SDL3_mixer with CMake using the SDLMIXER_DEPS_SHARED option and _SHARED options does not add any lib to the otool -L output

In CMake, when loading the dependencies using SDL_LoadObject, they are not passed to the linker and won't show up in ldd or otool -L.

slouken commented 1 month ago

Yes, the Xcode project handles it differently. In that case we don't dynamically load them, instead we link them as a weak framework, which allows it to be optional.

madebr commented 1 month ago

Can you have a look at the SDL_mixer project? I think that's the only remaining issue for generating "working" packages. On the other hand, SDL_mixer is not release-ready so if you want to postpone, that's also ok.

About the logs:

slouken commented 1 month ago

I will look at the SDL_mixer project next week. We'll have the next SDL prerelease on November 1, and SDL_ttf won't be ready by then, so we're fine.

slouken commented 1 month ago

Okay, I double checked and the FLAC and MP3 support are using the mini-versions included in the codecs directory, so we're good to go here.

madebr commented 1 month ago

This is the current situation:

/Volumes/SDL3_mixer/optional/FLAC.xcframework MISSING
/Volumes/SDL3_mixer/optional/gme.xcframework OK
/Volumes/SDL3_mixer/optional/mpg123.xcframework MISSING
/Volumes/SDL3_mixer/optional/ogg.xcframework MISSING
/Volumes/SDL3_mixer/optional/opus.xcframework OK
/Volumes/SDL3_mixer/optional/vorbis.xcframework MISSING
/Volumes/SDL3_mixer/optional/wavpack.xcframework OK
/Volumes/SDL3_mixer/optional/xmp.xcframework OK

vorbis support is provided by stb_vorbis, mp3 by minimp3.h and FLAC by dr_flac.

Isn't ogg needed as a dependency for opus?

sezero commented 1 month ago

Isn't ogg needed as a dependency for opus?

Yes, it is.

Note that opus framework here in SDL_mixer(s Xcode is a combination of opus and opusfile, possibly for simplicity as decided by @slouken. Maybe we can merge libogg into that for further simplicity?