I’m currently involved in porting a multiplatform game (Windows, Linux, Mac) to iOS. I am using a MacBook Air M1 and the latest version of SDL2 and Xcode.
What I’m stuck on is getting anything running on my iPhone. I have followed the build instructions multiple times to the letter. I can build the SDL2 framework for iOS no problems, I can also build the static library.
It’s when it comes to trying to build a project that uses SDL2. Firstly I get an error with the file SDL_sysurl.m - which appears to be Mac related. It tries to include a Cocoa header file, I can comment that out and it compiles, but then I get an error about the Carbon library being unusable with iOS.
My question is - as of January 2023, who is using SDL2 for iOS development here? I assume many people? Which version of the library are you using? Are there any extra steps needed for this to work? I also have SDL installed via Homebrew on my Mac for Mac development, which I would assume wouldn’t affect it but I guess that’s plausible.
Basically - can anyone lead me towards a tutorial that works with the current version of SDL2 on iOS? If not, is there a prior version that works?
Many thanks in advance, I’ve spent hours on this now and wanted to ask in case it’s something obvious that hasn’t yet made it into the popular tutorials.
It sounds like you’re trying to use the macOS SDL2. I just checked, and the iOS SDL2.framework doesn’t link against Carbon or try to include it in any way.
When you’re building SDL2 for iOS, make sure you have an iDevice selected instead of Mac Catalyst.
/Users/ozzeruk/Projects/iOSGames/Test.xcodeproj: Multiple targets match implicit dependency for product reference ‘SDL2.framework’. Consider adding an explicit dependency on the intended target to resolve this ambiguity.
I don’t see any way to specifically set an explicit dependency. I add the framework that says iOS.
Build iOS framework (make sure you select “Framework-iOS”, and next to it select “Build->Any iOS Device (arm64)”)
Make a new Xcode project. For this one I chose the “Game” framework, since it doesn’t try to add as unneeded stuff (for macOS choose regular “App” template).
Remove all added source code and other detritus. Leave main.storyboard, LaunchScreen.storyboard, and Assets.xcassets
Copy the iOS SDL2.framework to wherever YouriOSApp.xcodeproject is
In build settings, under General, under Frameworks, Libraries, and Embedded Content, add a new framework. Choose Add Other and then Add Files and then choose your iOS SDL2.framework
This is the annoying part, and isn’t required for SDL3. On iOS, your app needs to run from a class that inherits from UIAppDelegate so it can handle all the various iOS things, like the app going to the background, low memory notifications, etc. Apparently, if you use the iOS static library it includes its own main() function that creates and runs SDL’s own UIAppDelegate for you, which then calls your main(). Since we aren’t using the static library, we have to create this ourself. So:
6.1) Create a file called iosmain.m
6.2) Fill it with the code below. It’s just doing the UIAppDelegate thing, which will then call your main()
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <SDL2/SDL_main.h>
#ifdef main
#undef main
#endif
int main(int argc, char *argv[])
{
return SDL_UIKitRunApp(argc, argv, SDL_main);
}
What do you mean by “I add the framework that says iOS”? Are you including the SDL2 Xcode project directly into your own Xcode project or something?
It sounds like you’ve got two SDL2.framework in your project (which makes sense, since there’s already a Mac port), and Xcode doesn’t know which one to use. Maybe create a separate Xcode project for iOS. Put the iOS project file and its own SDL2.framework in a separate folder.
In the SDL docs folder there is a file called README-ios.md, step 3 is:
Right click the project in the main view, select “Add Files…”, and add the SDL project, Xcode/SDL/SDL.xcodeproj
In step 9 the README instructs you to add your own source code to the project.
I’m now following your tutorial instead, thanks very much for this, one query though, step 4 - where would I find SDL2.framework? I have compiled SDL2 for the iOS/arm64 target. Though I don’t have a build folder in that project directory tree. When I added the entire SDL project previously, it did then see the frameworks inside of that.
I tried that in the past but it resulted in Xcode wanting to constantly rebuild SDL2, which was annoying. Hence I ignore the SDL docs for building macOS and iOS apps and just do it my way. (the docs’ way was easier for developing SDL-based iOS games on a Mac with an Intel CPU if you wanted to use the Simulator)
Open SDL2.xcodeproj, set Framework-ios and Build->Any iOS Device (arm64 in the status bar up top. (see screenshot)
Go Product->Archive. This will build SDL2 in Release mode. If you were building for macOS this would also build both Intel and ARM binaries.
If the build is successful, the Organizer window pops up and you’ll see the archive. Right click on it, chose Show in Finder
In the Finder window, right click on the archive and pick Show Package Contents. Go to Products->Library->Frameworks.
Copy this SDL2.framework to the same folder as your iOS app’s .xcodeproject. Note: Use the Finder for this! In the past I’ve used the command line and the symlinks inside the .framework got all messed up (maybe I didn’t use the right cp arguments).
FWIW, I think the “official” SDL2 way of doing this is copying SDL_uikit_main.c from the SDL2 source into your project instead of manually creating a file that contains main() which calls SDL_UIKitRunApp())
But as @sjr said, this will be better in SDL3 (there you only need to #include <SDL3/SDL_main.h> in the sourcefile that contains yourint main(int argc, char* argv[]) and that’s all).