How do I configure and build ICU so I can link it to my iPhone app?
I'm maintaining an iPhone app that uses a SQLite database. Now I have to compile with ICU support enabled (SQLITE_ENABLE_ICU
). I've got the latest ICU source.
The configure
flags I'm using:
./configure --target=arm-apple-darwin --enable-static --disable-shared
After that, running gnumake
runs without errors.
Then I add the libraries to my Xcode project. But when I build, I get 50 lines of this:
Undefined symbols:
"_uregex_close_48", referenced from:
_icuRegexpDelete in libsqlite3-cerod.a(sqlite3_cerod.o)
"_ubrk_current_48", referenced from:
_icuNext in libsqlite3-cerod.a(sqlite3_cerod.o)
"_ucol_strcoll_48", referenced from:
_icuCollationColl in libsqlite3-cerod.a(sqlite3_cerod.o)
"_u_isspace_48", referenced from:
_icuRegexpFunc in libsqlite3-cerod.a(sqlite3_cerod.o)
"_utf8_countTrailBytes_48", referenced from:
_utf8_countTrailBytes_48$non_lazy_ptr in libsqlite3-cerod.a(sqlite3_cerod.o)
(maybe you meant: _utf8_countTrailBytes_48$non_lazy_ptr)
"_ubrk_next_48", referenced from:
_icuNext in libsqlite3-cerod.a(sqlite3_cerod.o)
Any idea what I'm doing wrong?
Edited to add:
When I add the libraries to the project (right-click on the project name, then Add Existing...), I get this:
ld: warning: in /Users/eric.grunin/dev/iOS/icu/source/lib/libicudata.a, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: in /Users/eric.grunin/dev/iOS/icu/source/lib/libicui18n.a, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: in /Users/eric.grunin/dev/iOS/icu/source/lib/libicuio.a, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: in /Users/eric.grunin/dev/iOS/icu/source/lib/libicule.a, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: in /Users/eric.grunin/dev/iOS/icu/source/lib/libiculx.a, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: in /Users/eric.grunin/dev/iOS/icu/source/lib/libicutu.a, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: in /Users/eric.grunin/dev/iOS/icu/source/lib/libicuuc.a, file was built for unsupported file format which is not the architecture being linked (i386)
That's why I think I'm building the library incorrectly. It's as if it's saying:
- It can't tell what architecture the .a files are built for
- libsqlite3-cerod.a is built for i386
I don't understand either possibility, but I'm new to iPhone development.
Edited to add
I tried @Sergio Moura's solution, and got the error mentioned in my comment.
I tried @sergio's solution, which built. But I'm still getting the equivalent errors, starting with:
ld: warning: in /Users/eric.grunin/dev/iOS/icu/iosbuild/lib/libicudata.a, file was built for unsupported file format which is not the architecture being linked (i386)
Might I be telling Xcode the wrong thing? I'm right-clicking on the project name, then selecting "Add->Existing File", and choosing the six or seven .a
files from /icu/iosbuild/lib
. Is that the correct process?
Note:
@sergio is recommending configure --host=arm-apple-darwin
, @Sergio Moura is using configure --target=arm-apple-darwin
. Neither made a difference, alas.
Edit #2
Targeting the device (instead of the emulator) solved all but one of the link errors! Here's what's left:
Undefined symbols for architecture armv6:
"___sync_synchronize", referenced from:
_ucol_initUCA_48 in libicui18n.a(ucol_res.ao)
udata_getHashTable() in libicuuc.a(udata.ao)
_umtx_init_48 in libicuuc.a(umutex.ao)
_initCache in libicuuc.a(uresbund.ao)
icu_48::hasService() in libicui18n.a(coll.ao)
_ucol_initInverseUCA_48 in libicui18n.a(ucol_bld.ao)
icu_48::locale_set_default_internal(char const*)in libicuuc.a(locid.ao)
...
ld: symbol(s) not found for architecture armv6
This was preceded by a cascade of these warnings:
ld: warning: CPU_SUBTYPE_ARM_ALL subtype is deprecated: /Users/eric.grunin/dev/iOS/icu/iosbuild/lib/libicuuc.a(resbund.ao)
ld: warning: CPU_SUBTYPE_ARM_ALL subtype is deprecated: /Users/eric.grunin/dev/iOS/icu/iosbuild/lib/libicuuc.a(ustrfmt.ao)
Edit #3
@Stephen R. Loomis's suggestion that I change #define U_HAVE_GCC_ATOMICS
from 1
to 0
(in platform.h
) made no difference, alas. I also realized that the last line of the error (not found for architecture arm6
) didn't mean it would work for arm7
, it was only an fyi that this was a cross-compile. When I specified an arm7
build, it failed with the same messages. Alas.
Edit #4
Success!
Summary: @sergio's build flags were essentially correct. I added -DU_HAVE_GCC_ATOMICS=0 to the ios build's CFLAGS. The one thing I had been doing wrong was not realizing I needed to cross-compile the library to create a device build.
I haven't tried to repeat this for the simulator, but that's outside the scope of my question.
Special thanks to Steven R. Loomis for pitching in, and to Sergio Moura for getting things rolling.
See Question&Answers more detail:
os