{"id":99,"date":"2026-07-19T16:39:12","date_gmt":"2026-07-19T16:39:12","guid":{"rendered":"https:\/\/demensdeum.com\/blog\/2026\/07\/19\/linux-to-ios-crosscompile-sdl\/"},"modified":"2026-07-19T16:39:12","modified_gmt":"2026-07-19T16:39:12","slug":"linux-to-ios-crosscompile-sdl","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/es\/2026\/07\/19\/linux-to-ios-crosscompile-sdl\/","title":{"rendered":"Building a C++ SDL application for iOS on Linux"},"content":{"rendered":"<p>In this note, I will describe the procedure for building a C++ SDL application for iOS on Linux, signing an ipa archive without a paid Apple Developer subscription, and installing it on a clean device (iPad) using macOS without Jailbreak.<br \/>\n<iframe loading=\"lazy\" title=\"1984 Apple&#039;s Macintosh Commercial (HD)\" width=\"620\" height=\"465\" src=\"https:\/\/www.youtube.com\/embed\/VtvjbmoDx-I?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<p>First, let&#8217;s install the build toolchain for Linux:<br \/>\n<a href=\"https:\/\/github.com\/tpoechtrager\/cctools-port\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/tpoechtrager\/cctools-port<\/a><\/p>\n<p>The toolchain needs to be downloaded from the repository, then follow the instructions on the Godot Engine website to complete the installation:<br \/>\n<a href=\"https:\/\/docs.godotengine.org\/ru\/latest\/development\/compiling\/cross-compiling_for_ios_on_linux.html\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/docs.godotengine.org\/ru\/latest\/development\/compiling\/cross-compiling_for_ios_on_linux.html<\/a><\/p>\n<p>At the moment, you need to download Xcode dmg and copy the sdk from there to build cctools-port. This stage is easier to complete on macOS; just copy the necessary sdk files from the installed Xcode. After successful assembly, the terminal will contain the path to the cross-compiler toolchain.<br \/>\nNext, you can start building the SDL application for iOS. Let&#8217;s open cmake and add the necessary changes to build the C++ code:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism undefined-numbers lang-unknown\" data-lang=\"unknown\"><code>SET(CMAKE_SYSTEM_NAME Darwin)\nSET(CMAKE_C_COMPILER arm-apple-darwin11-clang)\nSET(CMAKE_CXX_COMPILER arm-apple-darwin11-clang++)\nSET(CMAKE_LINKER arm-apple-darwin11-ld)\n\n<\/code><\/pre>\n<\/div>\n<p>Now you can compile using cmake and make, but do not forget to add $PATH to the cross-compiler toolchain:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism undefined-numbers lang-unknown\" data-lang=\"unknown\"><code>\nPATH=$PATH:~\/Sources\/cctools-port\/usage_examples\/ios_toolchain\/target\/bin\n\n<\/code><\/pre>\n<\/div>\n<p>For correct linking with frameworks and SDL, we write them in cmake, dependencies of the game Space Jaguar for example:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism undefined-numbers lang-unknown\" data-lang=\"unknown\"><code>\ntarget_link_libraries(\n${FSEGT_PROJECT_NAME}\n${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/libclang_rt.ios.a\n${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/libSDL2.a\n${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/libSDL2_mixer.a\n${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/libSDL2_image.a\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/CoreServices.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/ImageIO.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/Metal.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/AVFoundation.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/GameController.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/CoreMotion.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/CoreGraphics.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/AudioToolbox.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/CoreAudio.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/QuartzCore.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/OpenGLES.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/UIKit.framework\"\n\"${FLAME_STEEL_PROJECT_ROOT_DIRECTORY}\/scripts\/buildScripts\/ios\/resources\/libs\/Foundation.framework\"\n)\n\n<\/code><\/pre>\n<\/div>\n<p>In my case, the SDL, SDL_Image, SDL_mixer libraries are compiled in Xcode on macOS in advance for static linking; Frameworks copied from Xcode. Also added is the libclang_rt.ios.a library, which includes iOS-specific runtime calls, for example isOSVersionAtLeast. Included a macro for working with OpenGL ES, disabling unsupported functions in the mobile version, similar to Android.<br \/>\nAfter solving all the build problems, you should get the assembled binary for arm. Next, let&#8217;s consider running the assembled binary on a device without Jailbreak.<br \/>\nOn macOS, install Xcode, register on the Apple portal, without paying for the developer program. Add an account in Xcode -&gt; Preferences -&gt; Accounts, create a blank application and build on a real device. During assembly, the device will be added to your free developer account. After assembly and launch, you need to build the archive; to do this, select Generic iOS Device and Product -&gt; Archive. Once the archive is built, extract the embedded.mobileprovision and PkgInfo files from it. From the build log to the device, find the codesign line with the correct signature key, the path to the entitlements file with the extension app.xcent, copy it.<br \/>\nCopy the .app folder from the archive, replace the binary in the archive with one compiled by a cross-compiler in Linux (for example, SpaceJaguar.app\/SpaceJaguar), then add the necessary resources to the .app, check the integrity of the PkgInfo and embedded.mobileprovision files in the .app from the archive, copy again if necessary. We re-sign the .app using the codesign command &#8211; codesign requires an input key for sign, the path to the entitlements file (can be renamed with a .plist extension)<br \/>\nAfter re-signing, create a Payload folder, move the folder with the .app extension there, create a zip archive with Payload in the root, rename the archive with the .ipa extension. After that, in Xcode, open the list of devices and Drag\u2019n\u2019Drop the new ipa to the device\u2019s list of applications; Installation via Apple Configurator 2 does not work for this method. If the re-signing is done correctly, then the application with the new binary will be installed on an iOS device (for example, iPad) with a 7-day certificate, this is enough for the testing period.<\/p>\n<h3>Sources<\/h3>\n<p><a href=\"https:\/\/github.com\/tpoechtrager\/cctools-port\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/tpoechtrager\/cctools-port<\/a><\/p>\n<p><a href=\"https:\/\/docs.godotengine.org\/ru\/latest\/development\/compiling\/cross-compiling_for_ios_on_linux.html\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/docs.godotengine.org\/ru\/latest\/development\/compiling\/cross-compiling_for_ios_on_linux.html<\/a><\/p>\n<p><a href=\"https:\/\/jonnyzzz.com\/blog\/2018\/06\/13\/link-error-3\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/jonnyzzz.com\/blog\/2018\/06\/13\/link-error-3\/<\/a><\/p>\n<p><a href=\"https:\/\/stackoverflow.com\/questions\/6896029\/re-sign-ipa-iphone\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/stackoverflow.com\/questions\/6896029\/re-sign-ipa-iphone<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/Security\/Conceptual\/CodeSigningGuide\/Procedures\/Procedures.html\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/developer.apple.com\/library\/archive\/documentation\/Security\/Conceptual\/CodeSigningGuide\/Procedures\/Procedures.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this note, I will describe the procedure for building a C++ SDL application for iOS on Linux, signing an ipa archive without a paid Apple Developer subscription, and installing it on a clean device (iPad) using macOS without Jailbreak. First, let&#8217;s install the build toolchain for Linux: https:\/\/github.com\/tpoechtrager\/cctools-port The toolchain needs to be downloaded [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-99","post","type-post","status-publish","format-standard","hentry","category-notes"],"translation":{"provider":"WPGlobus","version":"3.0.3","language":"es","enabled_languages":["en","ru","zh","de","ja","fr","es","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"es":{"title":false,"content":false,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":true,"content":true,"excerpt":false}}},"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/posts\/99","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=99"}],"version-history":[{"count":0,"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/posts\/99\/revisions"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=99"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=99"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=99"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}