views:

175

answers:

3

I'm trying to link third party libraries like fftw3 and sndfile to my iPhone project in Xcode3.2. I got it working in a regular Mac project by setting the "Header Search Path" to "/usr/local/include" and the "Other Linker Flags" to "-lfftw3 -lsndfile" under the project build configuration. However, it gave me "library not found for -lfftw3" with exit code 1 error message when I tried to build it in the iPhone project using the same settings.

Does apple not allow this on the iPhone? Is there a way to get around this? Any idea would be much appreciated.

+2  A: 

You need to build your libraries as universal static libraries. The process varies from library to library but it generally goes something like this.

  1. build the library as a static lib for the different platforms (armv6 and i386 at the least)
  2. use lipo to create a universal library from the individual static libraries built above
  3. drag and drop the universal lib into your xcode project
  4. drag and drop the header files into your xcode project

Step 1 is generally the trickiest since many libraries have different build procedures. It is usually done by setting the proper compiler flags to use the iphone sdk instead of the system wide compiler.

Elfred
+1  A: 

It's not that Apple isn't allowing the library, it's that the version you are linking to is x86, and so it won't run on the iPhone. You need to build the library using the iPhone SDK, then link to that version.

Alternatively, you can be a little naughty and include the 3rd-party source in your main project. Naughty, but it'll prove the point that Apple isn't stopping you, and show whether the library will run on the phone OK.

It's cleaner to keep the code in a separately-built library project though.

Graham Perks
A: 

For compiling fftw3 for use in an iOS project, i've adapted the script posted here: http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884

Used with fftw3.2.2 on OS X 10.6 with iOs SDK 3.2

#!/bin/sh

# build_iphone.sh
# build an arm / i386 lib of fftw3
# make sure to check that all the paths used in this script exist on your system
#
# adopted from:
# http://robertcarlsen.net/2009/07/15/cross-compiling-for-iphone-dev-884


# make sure we start out clean
make distclean

# this is the folder where the results of our efforts will end up:
export RESULT_DIR=ios-library

# Select the desired iPhone SDK
export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer
export SDKROOT=$DEVROOT/SDKs/iPhoneOS3.2.sdk

# Set up relevant environment variables
export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/arm-apple-darwin9/4.0.1/include/ -I$SDKROOT/usr/include/ -miphoneos-version-min=2.2"
export CFLAGS="$CPPFLAGS -arch armv6 -pipe -no-cpp-precomp -isysroot $SDKROOT"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS"

# TODO: add custom flags as necessary for package
./configure CC=$DEVROOT/usr/bin/arm-apple-darwin10-gcc-4.0.1 LD=$DEVROOT/usr/bin/ld --host=arm-apple-darwin

make -j4

# Copy the ARM library to a temporary location
mkdir $RESULT_DIR
cp .libs/libfftw3.a $RESULT_DIR/libfftw3_arm.a

# Copy the header file too, just for convenience
cp api/fftw3.h ios-library/fftw3.h

# Do it all again for i386
make distclean

# Restore default environment variables
unset CPPFLAGS CFLAGS CPP LDFLAGS CXXFLAGS DEVROOT SDKROOT

export DEVROOT=/Developer
export SDKROOT=$DEVROOT/SDKs/MacOSX10.6.sdk

export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/i686-apple-darwin10/4.0.1/include/ -I$SDKROOT/usr/include/ -mmacosx-version-min=10.5"
export CFLAGS="$CPPFLAGS -pipe -no-cpp-precomp -isysroot $SDKROOT -arch i386"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS"

# TODO: error checking
./configure
make -j4

# Copy the native library to the temporary location
cp .libs/libfftw3.a $RESULT_DIR/libfftw3_386.a

# Create fat lib by combining the two versions
lipo -arch arm $RESULT_DIR/libfftw3_arm.a -arch i386 $RESULT_DIR/libfftw3_386.a -create -output $RESULT_DIR/libfftw3.a

# Remove intermediate binaries
rm $RESULT_DIR/libfftw3_arm.a
rm $RESULT_DIR/libfftw3_386.a

# Unset used environment variables
unset CPPFLAGS CFLAGS CPP LDFLAGS CPP CXXFLAGS DEVROOT SDKROOT

Run this script from the directory containing fftw3. The files you need should end up in the ios-library folder.

Epskampie