Use of (now) required "Embed Framework" causes previously working #includes to fail with "file not found"

Problem Description

MacBookPro M2, MacOS Sonoma 14.3.1, Xcode 15.3.

I'm trying to recompile my project that uses SDL2, from:

SDL.org's github

using their SDL2-2.30.2.dmg release. "Embed Framework" is required to get around this runtime error:

dyld[85171]: Library not loaded: @rpath/SDL2.framework/Versions/A/SDL2 Referenced from: <525E2631-2C23-3E66-96F5-031C734CF0B5>

Once the "Embed Framework" step is performed, the Xcode mapping of #include files stored in the loaded framework is undone. Undoing the "Embed Framework" step, puts the name mapping back but the program aborts as before. Either I can compile and obtain a run-time abort or I can not compile and not run the program. I've included a cludge to get around the issue, awaiting your fix (or advice).

Replication Details

Starting from a “from scratch”, Apple-supplied, “one-liner” (“Hello World”) as follows:

  1. Start new project in Xcode, selecting “MacOS”, “Command Line Tool”.

  2. Product Name:FrameWorkTest, Team:None, Organization Identifier:frameworktest, Language:C.

  3. Create the project in a new folder. with the given (default) settings.

  4. hit Apple-R… yay… it compiles and runs!

  5. add this line under the #include <stdio.h>

#include "SDL2/SDL.h"

Now “main.c” source is showing “file not found” against this new #include line. That’s expected.

  1. (6) Select FrameWorkTest from Navigator Pane (left hand side)

  2. (7) Select “General” tab (middle pane)

  3. (8) Finder drag “SDL2.framework” into Xcode’s middle-pane “Frameworks and Libraries” section (check the navigator pane (left pane) and now you have a “Frameworks” group containing “SDL2.framework”

After a few seconds the “file not found” indicator in “main.c” vanishes and the program is compilable (Apple+B). The Framework has been integrated (Hooray).

After a few seconds the “file not found” returns, though the program is still compilable (this seems to be a real-time parser mismatch with the compiler results, but not the main issue). I found the program is actually runable (Apple+R), probably because “main.c” has not been recompiled.

  1. (9) Force a recompile by adding a space to “main.c” (and remove the space) and, once again hit Apple+R.

Now compile fails because “SDL2/SDL.h” is not found.

  1. (10) Change the
#include "SDL2/SDL.h"

to

#include <SDL2/SDL.h>

“file not found” goes away after “Apple+R” forces a recompile. though now the runtime “abort” issue is present. Xcode is seriously confused at this point as putting double-quote version:

#include "SDL2/SDL.h" back is fine now (no longer “file not found”) even though the source is back to a failing state. Fine. now to fix the runtime “abort” issue:

  1. (11) Select “file view” in the Navigator pane (little folder icon). Select Project name, (topmost “FrameWorkTest” to show settings in middle pane). Select “Build Phases” tab.

  2. (12) Drag “SDL2.framework” from the “Frameworks” group in the project Navigator pane (leftmost pane) into “Embed Frameworks” (middle pane)

  3. (13) Now Apple+R will not compile (again) with “file not found” and I cannot get the project to compile and run without my “Trick” detailed above. Once the “Trick” is applied and the “file not found” goes away, the embed step (#12) lets the program compile and run - without “abort”.

Apple’s prepending of framework name to included files is inconsistent and faulty. The step 12 appears to undo the framework name mapping for #included files found in the framework. This step-by-step repeatable bug crib is not fixed by a “Product->Clean Build Folder…”.

Note: If step 12 is applied by doing a Finder drag and not a pane-to-pane drag, a (pointless) second Framework entry is introduced into the project, this confuses things further!

CLUDGE WARNING

Get around the “file not found” issue (total cludge but awaiting Apple’s real fix) is:

Logged in as an admin, in a terminal shell, do this:

cd /usr/local/include

(if you don’t have this directory; mkdir -p /usr/local/include; cd /usr/local/include)

ln -s /Library/Frameworks/SDL2.framework/Headers; mv Headers SDL2

Now in target settings, “Build Settings” tab, find “Header Search Paths” section and add “/usr/local/include” with “recursive” option selected (if it’s not already there).

I used a symbolic link (-s) for the trick so that the link is not disrupted when you next upgrade your SDL2.framework.

Now, even when you do a Product->Clean Build Folder, the project should build and run without Xcode issues.

Additionally, if you’d like to perform “the trick” for SDL2_ttf.framework #include files, do:

cd /usr/local/include ln -s /Library/Frameworks/SDL2_ttf.framework/Headers; mv Headers SDL2_ttf in an admin terminal.

Aside...

Reporting web page renumbers my 1) through 13), though the renumbering does not appear in the preview as it does in the actual post!

  • Corrections (sorry, I cannot format this Comments section...gah!):

    In point 10: #include "SDL2/SDL.h" is meant to be a code block on its own line.

    In Step 13: '"Trick" detailed above' should read '"Trick" detailed below'.

    The line before "Aside..." section is missing a semicolon. Code line should read:

    cd /usr/local/include; ln -s /Library/Frameworks/SDL2_ttf.framework/Headers; mv Headers SDL2_ttf

  • The issue appears to be associated with using Frameworks in a Command Line Tool. Though designating an app instead of a Command Line Tool has a different set of issues related to sandboxing. There will be another bug report (later) where chdir(path) returns success but errno is set to 1 (not allowed) and getcwd() subsequently returns NULL.

  • Two more corrections (clarifications): Step (6) refers to the upper "FrameWorkTest" item in the Navigation Pane. Step (8) refers to an already installed SDL2 Framework downloaded from "https://github.com/libsdl-org/SDL/releases/tag/release-2.30.2". I usually download the .dmg found at that link and, once that .dmg is mounted in the Finder, I drag the contained SDL2.framework to /Library/Frameworks to complete its MacOS installation.