Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report – Solving iOS Build Issues

A few weeks ago, I reported about needing to figure out how to build my project for iOS, something that was solved but needed re-solving due to Apple changing some requirements about how things should work.

I am late with my reports due to traveling out of town for the first time in over a year, so here’s my report for the next two sprints.

Sprint 24: Make publishable

Planned and Completed:

  • Create iOS build

Not completed:

  • Defect: game seems unresponsive on main menu screen (Android)
  • Defect: game plays in portrait mode instead of landscape (Android)
  • Create iOS icons

I managed to put in a few more hours than usual, and I finally managed to figure out how to build the project.

Part of the problem was that Apple’s requirements changed, yet the docs for SDL2 for iOS haven’t, so I knew I was going to need to figure out things on my own. I tried looking online for clues, because obviously someone has done this successfully recently, right?

I got so frustrated that I eventually posted on the SDL2 Discourse about it, adding detail to an existing thread.

If you recall from the last report, I had this linker error:

Xcode is annoying

Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_CHHapticDynamicParameter", referenced from:
objc-class-ref in SDL2(SDL_mfijoystick.o)
"_OBJC_CLASS_$_CHHapticEventParameter", referenced from:
objc-class-ref in SDL2(SDL_mfijoystick.o)
"_CHHapticDynamicParameterIDHapticIntensityControl", referenced from:
l002 in SDL2(SDL_mfijoystick.o)
"_CHHapticEventParameterIDHapticIntensity", referenced from:
l002 in SDL2(SDL_mfijoystick.o)
"_OBJC_CLASS_$_CHHapticPattern", referenced from:
objc-class-ref in SDL2(SDL_mfijoystick.o)
"_OBJC_CLASS_$_CHHapticEvent", referenced from:
objc-class-ref in SDL2(SDL_mfijoystick.o)
"_CHHapticEventTypeHapticContinuous", referenced from:
l002 in SDL2(SDL_mfijoystick.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I thought it was related to hidapi, and it wasn’t clear to me if it was something I was expected to build myself or not.

When I looked up the symbols in question, I found them in the Apple Developer docs. It turns out that they come from the CoreHaptics framework. So once I added that dependency to my CMakeLists.txt file, the project built just fine.

Toy Factory Fixer running in iOS simulator

It sounds like this might be a bug in SDL2 for not specifying it as a dependency? It’s not clear, but at least I can solve it for this project for now.

I tried creating an SDL2 framework and an XCFramework again, now that I can specify that dependency, but I could not figure out a way to get the project to actually link to what it was supposed to. It seemed like Xcode/clang couldn’t find the SDL2 library when it was in a framework, but it linked just fine if it was a static library, so I ended up creating static libraries for the simulator and static libraries for the device. It’s a bit annoying to have to switch between them either manually or at CMake configuration time.

One person suggested that I could add the target as a dependency of my project, but I’ll leave that as an exercise for future me to figure out. For now, I’ll just generate an Xcode project with CMake with an argument that says which libraries to point to.

Sprint 25: Make publishable

Planned and Completed:

  • Nothing. B-(

Not completed:

  • Defect: game seems unresponsive on main menu screen (Android)
  • Defect: game plays in portrait mode instead of landscape (Android)
  • Create iOS icons

Ok, so after the previous sprint’s success, I actually spent a big part of the next sprint trying to get the various scripts and CMake files coordinated and a bit more automated.

And one of my favorite things was solving an annoying manual step I have had to do.

Basically, each time I generate my Xcode project, I would need to do a few things within the Xcode IDE itself, which is not my favorite thing to do.

I would need to drag and drop my Images.xcassets into my Resources folder, then I would need to specify that I want to use the Asset catalog, but then Xcode would generate one for me, so I would need to delete the icon set that it created, then specify the icons I have.

Every time.

It’s error prone and tedious and annoying.

But I finally got CMake to do it for me, and I giggled and cheered and did a little dance in my chair when I saw the icon appear in the iPhone simulator.

Years ago, I tried to research how to do it myself, and the problem was that, again, Apple changed how things are done, so what worked in older versions of CMake and with older versions of Xcode/iOS no longer worked. And unfortunately, the Internet is littered with obsolete solutions.

Well, today I find that there is a CMake Discourse, and there is a person named Craig Scott who posted in a thread where someone asked a similar question.

Rather than adding each part of the asset catalog individually, see if adding it as a whole directory works instead:

target_sources(${TARGETNAME} PRIVATE Assets.xcassets)
set_source_files_properties(Assets.xcassets PROPERTIES
MACOSX_PACKAGE_LOCATION Resources
)

Adding directories rather than files is not officially supported by CMake as far as I’m aware, but doing it this way should allow Xcode to see the asset catalog and compile it for you. I don’t recall if setting the source file properties is required or not, but give it a go and see.

Wouldn’t you know it, but that actually worked for me. Now I didn’t need to drag and drop my Images.xcassets into the right place. But the asset catalog was still not being used.

But I see in that same thread the original poster had the following:

XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"

Now, I’m embarrassed to say that I still had trouble and thought it was still not working, but I later saw I had a typo with the set_source_files_properties line in which I accidentally typed IImages.xcassets instead of Images.xcassets.

And correcting that line meant that now the asset catalog with my icons is automatically getting used.

The only manual step left is related to code-signing, but I can otherwise run cmake and then build the Xcode project without a lot of manual fiddling.

And it feels great! In fact, I’m doing another little dance in my chair right now.

If you are curious, here’s the section of my CMakeLists.txt:


TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework AudioToolbox")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework AVFoundation")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework CoreAudio")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework CoreGraphics")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework CoreHaptics")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework CoreMotion")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework Foundation")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework GameController")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework ImageIO")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework MobileCoreServices")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework OpenGLES")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework QuartzCore")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework UIKit")
TARGET_LINK_LIBRARIES(${GB_PROJECT_NAME}-bin "-framework Metal")
TARGET_SOURCES(${GB_PROJECT_NAME}-bin PRIVATE "${PROJECT_BINARY_DIR}/data/resources/Images.xcassets")
SET_SOURCE_FILES_PROPERTIES(${PROJECT_BINARY_DIR}/data/resources/Images.xcassets PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
SET_TARGET_PROPERTIES(${GB_PROJECT_NAME}-bin PROPERTIES
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/ios/Info.plist.in
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${CODE_SIGN_IDENTITY}"
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
XCODE_ATTRIBUTE_INSTALL_PATH "$(LOCAL_APPS_DIR)"
XCODE_ATTRIBUTE_SKIP_INSTALL "NO"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${MACOSX_BUNDLE_GUI_IDENTIFIER}"
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
RESOURCE "${OTHER_RESOURCE_FILES}")

Unfortunately I still haven’t created iOS icons yet, but once I do, I think I am done with creating a successful and repeatable iOS build, and I can refocus on getting SDL2 and Android 11 working together again.

But last weekend I was out of town again and so I had less time to work on the project, which is why this report is a few days late, too. I did spend some time thinking of game mechanics and other ideas that I can’t wait to prototype.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 24-page, full color PDF of the Toytles: Leaf Raking Player’s Guide for free!