Reputation: 25083
I've got an iPhone app that runs on the device. Now I need to run it in the Simulator.
It uses an open source project (http://site.icu-project.org/), which I build from the command line to create arm-compatible .a
files. I can link these with my iPhone project, and it runs on the device.
If I switch the target to Simulator, the build fails, as I expected:
ld: warning: in libicudata.a, file was built for unsupported file format which is not the architecture being linked (i386)
But if I use libs compiled for local use (x86_64), I get the same error, which has got be baffled. Do I have to specify a third architecture for the Simulator? Which one? How do I set the configuration?
For reference, this is how I configured the icu project for the two different targets: How to build ICU so I can use it in an iPhone app?
Edited to add:
As Guillaume suggested (and Connect iPhone App to PostgreSQL Using Libpq confirmed), I now see that the emulator needs a 32-bit build. So that's the last part: how do I set the configuration?
The library has a standard configure
script, as far as I know, but I'm still pretty new at this.
Edited to add:
I've gotten this far, but the references to i686 are obviously wrong.
I don't know if i386 is considered a cross-compile, if it is I need "host" and "target" options, too.
ICU_PATH=/Users/eric.grunin/Documents/dev/icu2
DEVROOT=/Developer/Platforms/iPhoneSimulator.platform/Developer
SDKROOT=$DEVROOT/SDKs/iPhoneSimulator4.3.sdk
SYSROOT=$SDKROOT
ICU_FLAGS="-I$ICU_PATH/source/common/ -I$ICU_PATH/source/tools/tzcode/ "
export CXXPP=
export CXXPPFLAGS=
export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/include/ -I$SDKROOT/usr/include/c++/4.2.1/armv7-apple-darwin10/ -I./include/ -miphoneos-version-min=2.2 $ICU_FLAGS"
export CFLAGS="$CPPFLAGS -pipe -no-cpp-precomp -isysroot $SDKROOT"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS"
export CC="$DEVROOT/usr/llvm-gcc-4.2/bin/i686-apple-darwin10-llvm-gcc-4.2"
export CXX="$DEVROOT/usr/llvm-gcc-4.2/bin/i686-apple-darwin10-llvm-g++-4.2"
export LDFLAGS="-L$SDKROOT/usr/lib/ -isysroot $SDKROOT -Wl,-dead_strip -miphoneos-version-min=2.0"
cd $ICU_PATH
mkdir simbuild
cd simbuild
$ICU_PATH/source/configure --enable-static --disable-shared
gnumake
Upvotes: 1
Views: 5811
Reputation: 25083
This is how I got it to work. I'm putting it here so I can look it up later.
It's likely this is imperfect, feel free to correct it. Comments try to separate what's generic from what's specific to the ICU library I was building.
// This is is required by the ICU configure step
# must be ABSOLUTE PATH
ICU_PATH=/Users/eric.grunin/Documents/dev/icu2
// First crucial bit: specify the Simulator
DEVROOT=/Developer/Platforms/iPhoneSimulator.platform/Developer
SDKROOT=$DEVROOT/SDKs/iPhoneSimulator4.3.sdk
SYSROOT=$SDKROOT
// for convenience
ICU_FLAGS="-I$ICU_PATH/source/common/ -I$ICU_PATH/source/tools/tzcode/ "
export CXXPP=
export CXXPPFLAGS=
// current version of gcc is missing some #include files, we have to get them elsewhere
export CPPFLAGS="-I$SDKROOT/usr/include/c++/4.2.1/i686-apple-darwin10/ -I$SDKROOT/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/include/ -I$SDKROOT/usr/include/c++/4.2.1/armv7-apple-darwin10/ -I./include/ -miphoneos-version-min=2.2 $ICU_FLAGS"
// MUST specify -arch i386
export CFLAGS="$CPPFLAGS -pipe -arch i386 -no-cpp-precomp -isysroot $SDKROOT"
export CPP="$DEVROOT/usr/bin/cpp $CPPFLAGS"
export CXXFLAGS="$CFLAGS"
export CC="$DEVROOT/usr/bin/gcc"
export CXX="$DEVROOT/usr/bin/g++"
// MUST add -arch i386 here.
// Also: to avoid "undefined symbol: _Unwind_Resume", add -lgcc_eh
export LDFLAGS="-arch i386 -L$SDKROOT/usr/lib/ -lgcc_eh -isysroot $SDKROOT -Wl,-dead_strip -miphoneos-version-min=2.0"
cd $ICU_PATH
mkdir simbuild
cd simbuild
// Not sure if --host is really needed
$ICU_PATH/source/configure --enable-static --disable-shared --host=i686-apple-darwin10
gnumake
I'm probably not going to make a fat binary, because the ICU library is already very large and I need to keep the final app as small as possible.
Edited to add
I tried the fat library approach: it tripled the size of my app, alas.
Upvotes: 1
Reputation: 4350
That's just the data library. You don't need to build it several times. Use --with-data-packaging=archive
when you build ICU, and then it will generate a file icudt*.dat
.. when your app starts up, call u_setDataDirectory()
to tell it which directory contains that .dat file. u_setDataDirectory()
Upvotes: 1
Reputation: 21736
You need to build a fat library: a fat library is a library that embed the code of many architectures in one file.
For the devices, you need to add the architectures armv6
and armv7
. For the simulator, i386
.
Look into this answer for details and a script on how to do this from Xcode: https://stackoverflow.com/a/3647187/272342
Upvotes: 4