In case you’re not getting it from the title, I may not have learned anything substantial while writing this article. I just created yet another static library, tried linking it against another, and there goes XCode (build 4C104) NYAAAAN.
Since I used to write my own coding tools, I bloody well knew how to compile a java (sigh) program on the command line. I also wrote tools in such a way that they found jars in myland (comforting it was, however restrictive).
XCode workspaces are meant to improve the (sodding) developer experience when dealing with complex projects. Don’t get me wrong, I’m all for wizardry – Clearly, however an ignoramus ex machina is usually at work when I try stringing libraries together.
Check this article from the Carbon Five blog for useful notes about linking static libraries. I’ll provide a new article on this topic at some point. I just wasted a couple of hours clear because this stuff is having its way. Here’s a lame summary of what I found:
- Like pixies, build issues appear when you least expect it. Sadly they also disappear mysteriously as soon as you try getting to the root of the problem.
- You can fix build issues by fiddling:
- If at first you don’t succeed…
- Don’t assume a library won’t get found because it appears ‘marked red’
- Don’t assume a library will get found because it doesn’t appear ‘marked red’
- Assume duplicate items can easily arise when adding libraries to a project.
- Remove duplicate items whenever you stumble on them.
- Play with the ‘Location’ combo (relative to group, relative to project etc…).
- Don’t be afraid to check build logs. The paths often look infuriatingly convoluted, but while you’re poking around to find what’s really gone wrong, the problem is getting itself fixed (and at least you’re kidding yourself that you have something to do with it).
Okay, let’s say I made a library called ‘foobar’ (I actually did)
Initially, under ‘products’, libfoobar.a is red. In my file inspector the location is relative to build products (and cannot be changed)
For sake, build (don’t add any source file) and check what happens: nothing. Well that’s good, innit? No source files, no library.
Now, add a source file and rebuild. Check the messages window. We now have 3 items: Precompile…, Compile… and Libtool.
Under Libtool, we can see the intended location of the output:
Feeling paranoid (would Libtool ever lie?) we can verify that the library has been created by browsing to this path (Finder is gracefully setup to overlook whatever path this stuff goes under).
But the item still appears ‘marked red’ under ‘Products’. Suspicious?
Can’t copy libfoobar.a?
Now let’s try linking foobar against a target inside another project (same workspace, right?). Open project settings (yea click on the project in the navigator), go to Build Phases > Link Binary With Libraries, hit the [+] button. A cute browser now appears with libfoobar.a under Workspace (or whatever your workspace is named). Select libfoobar.a, press return and… *build*.
Mind, this operation adds an item to your project, now also visible in the navigator (libfoobar.a, still marked red).
If there is an error, it may look like this:
error: /Users/johndoe/Library/Developer/Xcode/DerivedData/workspace-fdpyddpbphekphdqtzzutyjcagva/Build/Products/Debug-iphonesimulator/../../../../../../../../svn/components/base/build/Release-iphoneos/libfoobar.a: No such file or directory
Command builtin-copy failed with exit code 1
What’s going on here? Let’s go and check the added library item inside our project (select the item and make check sure the inspector is open). I see this:
Location: relative to group
Clearly not right (yet, consistent with the failed copy operation)
Fancy patching the path manually?
Location: relative to build products
Worked for me, but not right away. Digging around I found yet another duplicate of the same library reference (marked red!). Removed it, cleared (what appears to be) the same item under ‘build phases’ and re-re-re-added it all over again (this time by checking the box I wanted in ‘target memberships’).
I felt somewhat unconvinced (notably, I’m not happy with the Debug-iphonesimulator part of the relative-to-build-products-path – how’s that supposed to backfire?).
So I removed the library altogether and started over. Just repeated the initial steps going by the book… sadly it… worked.
Until next time.