Xcode 4 with External Static Library for iPhone Development

Mac OS X 16 Comments

xcodeI upgraded to the latest Xcode 4 and had a tough time using it as things have changed quite a bit. (I’m not too familiar with Xcode 3 either so that didn’t help.) I also needed to make and include a static library (Live555) for the iPhone application that I am building. Because Xcode 4 is so new, there weren’t a lot of resources out on the internet. I finally got my app working with the static library and wanted to post some hints here. Hopefully this post will help those who are also having problems getting up to speed with Xcode 4.

Adding a Framework or Static Library File (with .a extension)

  1. Click on the folder icon under the giant top-left Run icon to “Show the Project navigator”
  2. Click on the Project name right underneath
  3. Click on the project name under “TARGETS”
  4. Click on “Build Phases” and then open up “Link Binary With Libraries” section
  5. Click on the plus button to add a Framework such as “AVFoundation.framework”.
    • If you want to add an external library, click on “Add Other…” and find your library file
  6. Doing the above will update the “Library Search Paths” setting automatically with the path to your library file. You can see what was set by doing the following:
    • Click on “Build Settings” (right before “Build Phases”)
    • Expand “Search Paths” and you should see “Library Search Paths”
  7. Most likely, you will need to use corresponding header files for your library file. To get this to work, you must add the header include path to “Header Search Paths” (if you use: #include <header.h>) and/or “User Header Search Paths” (if you use: #include “header.h”). Alternatively, if you set “Always Search User Paths” (also under “Search Paths” section) to “Yes”, then you just need to set “User Header Search Paths” for both include methods to work.
    • Click on “Build Settings” (right before “Build Phases”)
    • Click on “All” and scroll down to “Search Paths”
    • Double-click on the blank entry area to the right of “Header Search Paths” and/or “User Header Search Paths” to open up a dialog window.
      • Click the plus button and a checkbox will be added under “Recursive”. You can check the “Recursive” checkbox if you want Xcode to look into subdirectories also.
      • Double-click in the entry area to the right of the newly-added checkbox and input the path
    • You can then click on “Basic” and now “Header Search Paths” and/or “User Header Search Paths” will appear since they are no longer empty.

Building with an External Static Library File

  • The Xcode 4 SDK has been updated so make sure to update the sysroot directory in your Makefile to be “/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk”.
  • When compiling the library, if you see this error “ld: file not found: /usr/lib/system/libcache.dylib for architecture armv7”, then your linker command is using “–sysroot” which doesn’t work in Xcode 4. Instead, change the linker command to use “-isysroot”. (Note: This only applies to the linker command. The compile commands must continue to use “–sysroot”. See here for more details.)
  • When building the Xcode project with your library, if you see this error “file was built for archive which is not the architecture being linked (armv6)”, then the library you are linking to does not support armv6. In my case, I built the library using the “-arch armv7” so the resulting library did not support armv6. (I haven’t figured out how to compile a library for both armv6 and armv7 yet.) I had to force Xcode 4 to build only for armv7 to solve this error:
    1. Show the Project navigator
    2. Click on the Project name right underneath
    3. Click on the project name under “PROJECT”
    4. Expand the “Architectures” section (first section) and select “Optimized (armv7)” for the “Architectures” setting. (The default setting was “Standard (armv6 armv7)”.)

Using the Integrated (nice!) Interface Builder

  1. Show the Project navigator and click once on the project’s MainWindow.xib or Controller.xib file. The MainWindow.xib is the parent of the Controller.xib. You will want to put your UI components into Controller.xib.
  2. The Interface Builder will appear in the right content area.
  3. Show the utility pane by going to menu “View->Utilities->Show Utilities”. This pane is very useful and I leave it open all the time.
  4. To add a class which has UI hooks (IBOutlet and IBAction) to the Interface Builder:
    • Click on Controller.xib to show the Interface Builder. (Go ahead and add your buttons, text fields, sliders, etc., if you haven’t already done so.)
    • Go to menu “View->Utilities->Object Library”.
    • In the bottom-right of the Utilities pane, scroll down to “Object” and drag-n-drop it onto the Interface Builder content area. The Object will appear on the Interface Builder’s left vertical dock.
  5. Tie the IBOutlets/IBActions to the UI Components:
    • Select the Object in the dock and go to menu “View->Utilities->Identity Inspector”.
    • At the top of the Utilities pane, under the “Custom Class” section, hit the drop down to change “NSObject” to your custom class.
    • Leave the Object in the dock selected and go to menu “View->Utilities->Connections Inspector”.
    • At the top of the Utilities pane, click on the circle to the right of your Outlet or Receive Action and drag to the UI component you want to attach to. For Receive Action, you will be prompted to select the action, such as “Touch Down”.
  6. If you have added IBOutlet/IBAction hooks to your Controller class, do not add a custom Object to Controller.xib and change it to be your Controller class. Instead, use the pre-defined “File Owner” object in Controller.xib which is your Controller class. If you use your own custom Object instead of “File Owner” object, your iPhone application may crash.

Compiling the Live555 Streaming Media Library

For those interested, I had to make the following changes to compile the Live555 Streaming Media Library. Before running “./genMakefiles iphoneos”, update these two files:

  • Update the “config.iphoneos” file by adding one line to create a common variable, SYSROOT_DIR, and updating the compile and linker commands to use it:
    SYSROOT_DIR = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk
    COMPILE_OPTS = $(INCLUDES) -I. $(EXTRA_LDFLAGS) -DBSD=1 -O2 -DSOCKLEN_T=socklen_t -DHAVE_SOCKADDR_LEN=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -fPIC -arch armv7 --sysroot=$(SYSROOT_DIR)
    LINK_OPTS = -L. -arch armv7 -isysroot=$(SYSROOT_DIR)
  • Compiling the Live555 test executable programs would cause linker errors. To avoid these errors, update the “Makefile.tail” by commenting out these lines with the # character:
    #TESTPROGS_DIR = testProgs
    #MEDIA_SERVER_DIR = mediaServer

    all:
    ...
    #       cd $(TESTPROGS_DIR) ; $(MAKE)
    #       cd $(MEDIA_SERVER_DIR) ; $(MAKE)

    clean:
    ...
    #       cd $(TESTPROGS_DIR) ; $(MAKE) clean
    #       cd $(MEDIA_SERVER_DIR) ; $(MAKE) clean

Good luck with your iPhone development!

16 Comments