Labs: XCode Detective Work

June 13, 2011 by
Categories: Labs

Taking the magic out of compilation gives me a lot of peace of mind. Sometimes there can be some really confusing behavior when it comes to static libraries. Its important to use the tools XCode gives you to get clues to solve your problems. Verifying the steps XCode is taking to create your application provides a much deeper understanding of the compilation process. Here are some tips to help out with linking, build products, and static libraries.

The Build Products directory

You can see a lot of what XCode is doing behind the scenes by checking out the ‘build products’ directory. This is the directory where XCode puts its compiled code.

The Build Products Dir for the Sample Library Workspace

You can see in the above image that in our sample library project from the last entry that the ‘.a’ files and the ‘.app’ folders are all built into this directory.

Its safe to delete everything in this directory. It can be helpful to delete a file and see if it shows up again when you recompile. If it doesn’t, that could be a source of a problem.

Linker Logs

When you compile you can watch all the different steps happening in the Log Navigator:

XCode's Log Navigator is a great source of info on what's going on.

More specifically you can see the line that says ‘Link’ near the end of your output.

Check the 'link' line for details on what's being linked.

You should see all kinds of gobbledy-gook, including stuff that looks like:

-F/Users/chris/Library/Developer/Xcode/DerivedData/LibraryProject-dikpahcizsmufsewugpyfrpdkkfv/Build/Products/Debug

Which means ‘This folder is where we want to look for libraries’. And:

-lStaticLibrary -lAnotherStaticLibrary

Which means ‘link the files libStaticLibrary.a and libAnotherStaticLibrary.a into our binary’.

Learning how to read the linker output is really helpful in determining whether what you think is being linked is actually being linked.

Make sure the Linker is Linking

You would think that if you saw the above lines in your log output, that it would link as expected. I have found this to not necessarily be the case. One of the more devilish details is determining if it is linking or not. The very end of the linker log line will be something like:

-o /Users/chris/Library/Developer/Xcode/DerivedData/LibraryProject-dikpahcizsmufsewugpyfrpdkkfv/Build/Products/Debug-iphoneos/SampleIOSApplication.app/SampleIOSApplication

‘Linking’ really just means combining, and this is the final binary blob of code that is generated. All your ‘.a’ files are smooshed together with the ‘.o’ files for your app and placed in that location, inside the .app folder.

So how can you tell if the linker linked? Check the binary’s creation date. If you don’t see the date change when you compile, linking is broken.

The final binary built resides within your .app directory. Check this file to see if compilation is occuring when you think it is.

‘Relative To’ settings.

Let’s say that you’re modifying the library, but not the application’s code. You compile, and it doesn’t update your binary. What happens if you see that the linker’s output is correct, but your binary’s file creation date isn’t changing? This may be related to the ‘Relative To’ dropdown on your library.

It seems that if the ‘Relative To’ is not set to ‘Relative To Build Products’ and the .pbxproj file is not modified as shown in my previous entry (under ‘Fix Static Library References’), then its possible that the linker will not re-generate your binary. Why? Uh…its a secret. Or I have no idea. Pick one.

And even if you do set the file up as relative to Build Products, it still may not work. In this instance, I would recommend trying again. Yes, it works for me if I keep trying. I don’t know why. :P

Summary

Use these tips to debug issues with static libraries in XCode 4:

  • Watch the Build Products folder and see what’s being built.
  • Delete libraries and apps in the Build Products folder to experiment and see what gets built when.
  • Inspect the linker’s output in the Log Navigator to make sure items are being correctly linked.
  • Check your binary’s file creation date to make sure that it is being re-linked upon re-compile.
  • Make sure that your libraries are correctly set to be ‘Relative to Build Products’, and modify your .pbxproj to accurately point to the correct location.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>