Need help with SDL2 for iOS using CMake

Hello together,

I’m stuck with SDL2 for iOS using CMake.

Since SDL supports iOS, I’d like to port my apps for iPhone/iPad. Actually I don’t like development on Mac, and XCode is not really a satisfying option to me. Therefore I’d like to use CMake for development and portability, but I’m neither a Mac nor a CMake guru.

What I’ve done:
Build SDL2 from sources as mentioned in the README with the iosbuild.sh script.

Copied the header files and libSDL2.a + libSDL2main.a into my project folder (libs/SDL + libs/SDL/include).

Installed the ios-cmake (https://code.google.com/p/ios-cmake/) toolchain into my project folder.

Have a simple SDL demo (main.cpp and myapp.hpp from this SDL 1.3 on iOS (http://immersedcode.org/2011/4/25/sdl-on-ios/) tutorial with some typos removed).

Copied the CMakeLists.txt file from the same tutorial (fixing pathes and using SDL2 instead).

Created an xcodeproj file with CMake ($ cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain/iOS.cmake -GXcode ..).

Manually build the XCode project ($ xcodebuild -sdk iphonesimulator).

Now, it compiles, but linking failed. Here’s the unshortened error message:

Ld build/Debug-iphonesimulator/MyApp.app/MyApp normal i386
cd /Users/michael/Documents/Sources/SDL/02_iOS
setenv MACOSX_DEPLOYMENT_TARGET 10.6
setenv PATH “/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/X11/bin:/opt/local/bin”
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang++ -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -L/Users/michael/Documents/Sources/SDL/02_iOS/build/Debug-iphonesimulator -L/Users/michael/Documents/Sources/SDL/02_iOS/libs/SDL/Debug-iphonesimulator -L/Users/michael/Documents/Sources/SDL/02_iOS/libs/SDL -F/Users/michael/Documents/Sources/SDL/02_iOS/build/Debug-iphonesimulator -filelist /Users/michael/Documents/Sources/SDL/02_iOS/build/MyApp.build/Debug-iphonesimulator/MyApp.build/Objects-normal/i386/MyApp.LinkFileList -mmacosx-version-min=10.6 -Xlinker -objc_abi_version -Xlinker 2 -framework Foundation -framework AudioToolbox -framework CoreGraphics -framework QuartzCore -framework UIKit -framework OpenGLES -Wl,-headerpad_max_install_names -lSDL2 -lSDL2main -Xlinker -no_implicit_dylibs -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 -o /Users/michael/Documents/Sources/SDL/02_iOS/build/Debug-iphonesimulator/MyApp.app/MyApp
Undefined symbols for architecture i386:
"_SDL_SYS_GetInstanceIdOfDeviceIndex", referenced from:
_SDL_GameControllerOpen in libSDL2.a(SDL_gamecontroller.o)
_SDL_JoystickOpen in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickUpdate", referenced from:
_SDL_GameControllerOpen in libSDL2.a(SDL_gamecontroller.o)
_SDL_JoystickUpdate in libSDL2.a(SDL_joystick.o)
_SDL_JoystickOpen in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickInit", referenced from:
_SDL_JoystickInit in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickGetGUID", referenced from:
_SDL_JoystickGetGUID in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickNeedsPolling", referenced from:
_SDL_PrivateJoystickNeedsPolling in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickClose", referenced from:
_SDL_JoystickClose in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickDetect", referenced from:
_SDL_JoystickUpdate in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickQuit", referenced from:
_SDL_JoystickQuit in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickAttached", referenced from:
_SDL_JoystickGetAttached in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_NumJoysticks", referenced from:
_SDL_NumJoysticks in libSDL2.a(SDL_joystick.o)
_SDL_JoystickGetDeviceGUID in libSDL2.a(SDL_joystick.o)
_SDL_JoystickOpen in libSDL2.a(SDL_joystick.o)
_SDL_JoystickNameForIndex in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickGetDeviceGUID", referenced from:
_SDL_JoystickGetDeviceGUID in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickOpen", referenced from:
_SDL_JoystickOpen in libSDL2.a(SDL_joystick.o)
"_SDL_SYS_JoystickNameForDeviceIndex", referenced from:
_SDL_JoystickOpen in libSDL2.a(SDL_joystick.o)
_SDL_JoystickNameForIndex in libSDL2.a(SDL_joystick.o)
"_UIKit_ShowMessageBox", referenced from:
_SDL_ShowMessageBox in libSDL2.a(SDL_video.o)
"_UIKIT_bootstrap", referenced from:
_bootstrap in libSDL2.a(SDL_video.o)
".objc_class_name_NSBundle", referenced from:
pointer-to-literal-objc-class-name in libSDL2.a(SDL_rwopsbundlesupport.o)
".objc_class_name_NSFileManager", referenced from:
pointer-to-literal-objc-class-name in libSDL2.a(SDL_rwopsbundlesupport.o)
".objc_class_name_NSAutoreleasePool", referenced from:
pointer-to-literal-objc-class-name in libSDL2.a(SDL_rwopsbundlesupport.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

** BUILD FAILED **

The following build commands failed:
Ld build/Debug-iphonesimulator/MyApp.app/MyApp normal i386
(1 failure)

Have no clue what to do about this. Tried to build with XCode, too. Added the frameworks, and libSDL2 + libSDL2main, but it still fails.

It’s the third day I’m trying to get this done. The demos from the SDL sources compile and run perfectly in the simulator.

I appreciate any help.

Thx

Solved it myself somehow. Instead of using the iosbuild.sh, I compiled the Xcode project to build the libSDL2.a, but have to select the iphonesimulator. To me it seems like the iosbuild.sh doesn’t create the libSDL2.a for the simulator (as I thought).

Thanks anyway

2013/9/9 Laz-Roc

**
Solved it myself somehow. Instead of using the iosbuild.sh, I compiled the
Xcode project to build the libSDL2.a, but have to select the
iphonesimulator. To me it seems like the iosbuild.sh doesn’t create the
libSDL2.a for the simulator (as I thought).

Thanks anyway

I haven’t tried that in a while, but IIRC it used to build the i386
architecture which was what the simulator required at the time.
The script could use an update though as it doesn’t build the armv7s
architecture required for newer devices.–
Gabriel.

That’s probably right, but fixing the script is a little too much for me right now. Mac development is just too new for me, and I’m happy not to depend on Apple’s toolchain to much at the moment.

Btw, I’ve build the SDL2 Fireworks demo with CMake for the simulator, and published a tutorial (http://www.michaelborgmann.com/tutorials/build-sdl2-app-on-ios-with-cmake/) about it on my website. Works for me, but is nonetheless somewhat messy.

Hello,
I was browsing a lot the forum, and Internet too, to find if someone has the same issue of me.
As you said, I had the linking issue with an application that uses libSDL2.

these are the steps that I’ve done:

  • Open SDL.xcodeproj from XCODE-iOS folder from the SDL2 repository.
  • Build selecting ios device and an ios simulator.
  • Copy the xcode project Template from XCODE-ios for a test Project.
  • set the reference for SDL include folder.
  • Copy the libSDL2.a from simulator and device and reference the in the test project.
  • build.

the code compile but the linking fails:

Undefined symbols for architecture i386:
"_SDL_CreateRenderer", referenced from:
_SDL_main in main.o
(maybe you meant: _SDL_CreateRenderer_REAL)
"_SDL_CreateWindow", referenced from:
_SDL_main in main.o
(maybe you meant: _SDL_CreateWindow_REAL, _SDL_CreateWindowAndRenderer_REAL , _SDL_CreateWindowFrom_REAL )
"_SDL_Delay", referenced from:
_SDL_main in main.o
(maybe you meant: _SDL_Delay_REAL)
"_SDL_Init", referenced from:
_SDL_main in main.o
(maybe you meant: _SDL_Init_REAL, _SDL_InitFormat , _SDL_InitTicks , _SDL_InitSubSystem_REAL )
"_SDL_PollEvent", referenced from:
_SDL_main in main.o
(maybe you meant: _SDL_PollEvent_REAL)
"_SDL_Quit", referenced from:
_SDL_main in main.o
(maybe you meant: _SDL_QuitQuit, _SDL_Quit_REAL , _SDL_QuitSubSystem_REAL , _SDL_QuitInit )
"_SDL_RenderClear", referenced from:
_render in main.o
(maybe you meant: _SDL_RenderClear_REAL)
"_SDL_RenderFillRect", referenced from:
_render in main.o
(maybe you meant: _SDL_RenderFillRect_REAL, _SDL_RenderFillRects_REAL )
"_SDL_RenderPresent", referenced from:
_render in main.o
(maybe you meant: _SDL_RenderPresent_REAL)
"_SDL_SetRenderDrawColor", referenced from:
_render in main.o
(maybe you meant: _SDL_SetRenderDrawColor_REAL)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

as you can see the errors are about not finding i386 symbols in the lib. In the lib that I created there are all the symbols for function like _SDL_Function_REAL and not _SDL_Function (like the linker suggest in the output).
Do I have to modify anything in the SDL.xcodeproj to compile correctly and allow the linker to find the correct symbols?
Has anyone already seen this issue?

I’m working on OSX 10.9 with XCode 5.0.2 and ios 7 SDK.

Thank you.

I think I found the problem by myself.

in SDL_dynapi.h there’s a PREPROCESSR Macro to set the value of SDL_DYNAMIC_API to 0 or 1 depending on:

  • if APPLE is defined
  • if TARGET_OS_IPHONE is set to 1

the problem is that TARGET_OS_IPHONE is defined in “TargetConditionasl.h” from apple, so only in case of defined(APPLE) is satisfied. This header is not directly included in SDL_dynapi.h and the consequence is that SDL_DYNAMIC_API is always 1 and then every SDL function is redefined to be SDL_FunctionName_REAL (as per SDL_dynapi_overrides.h).

The solutions, or workarounds, are:

  • define the macro in the project settings
  • add these lines to SDL_dynapi.h:

Code:

#if defined(APPLE)
#include “TargetConditionals.h”
#endif

I don’t know if this is a problem of my system or a general bug.
My system is OS X Mavericks, with XCODE 5.0.2, ios SDK 7.

Cheers.

the problem is that TARGET_OS_IPHONE is defined in
"TargetConditionasl.h" from apple, so only in case of defined(APPLE)
is satisfied. This header is not directly included in SDL_dynapi.h and
the consequence is that SDL_DYNAMIC_API is always 1 and then every SDL
function is redefined to be SDL_FunctionName_REAL (as per
SDL_dynapi_overrides.h).

Fixed in https://hg.libsdl.org/SDL/rev/1b62b081a83b, thanks!

–ryan.

That is correct.
It is a system header, so angle brackets are better.

#if defined(APPLE)
#include <TargetConditionals.h>
#endif

Additionally, you need to also check for the iOS simulator because it
is considered distinct from the device. Here’s the common pattern:

#if defined(APPLE)
#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)
// iOS device or simulator here
#else
// probably Mac
#endif
#endif

-EricOn 1/22/14, PaoloOrange <paolo.oranges at gmail.com> wrote:

I think I found the problem by myself.

in SDL_dynapi.h there’s a PREPROCESSR Macro to set the value of
SDL_DYNAMIC_API to 0 or 1 depending on:

  • if APPLE is defined
  • if TARGET_OS_IPHONE is set to 1

the problem is that TARGET_OS_IPHONE is defined in "TargetConditionasl.h"
from apple, so only in case of defined(APPLE) is satisfied. This header
is not directly included in SDL_dynapi.h and the consequence is that
SDL_DYNAMIC_API is always 1 and then every SDL function is redefined to be
SDL_FunctionName_REAL (as per SDL_dynapi_overrides.h).

The solutions, or workarounds, are:

  • define the macro in the project settings
  • add these lines to SDL_dynapi.h:

Code:

#if defined(APPLE)
#include “TargetConditionals.h”
#endif

I don’t know if this is a problem of my system or a general bug.
My system is OS X Mavericks, with XCODE 5.0.2, ios SDK 7.

Cheers.


Beginning iPhone Games Development
http://playcontrol.net/iphonegamebook/

It is a system header, so angle brackets are better.

Weird, we are using quotes for SDL_platform.h, too.

–ryan.