如何构建ICU以便我可以在iPhone应用程序中使用它? [英] How to build ICU so I can use it in an iPhone app?

查看:167
本文介绍了如何构建ICU以便我可以在iPhone应用程序中使用它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何配置和构建ICU以便将其链接到我的iPhone应用程序?

我正在维护一个iPhone应用程序使用SQLite数据库。现在我必须在启用ICU支持的情况下进行编译( SQLITE_ENABLE_ICU )。我有最新的ICU来源。

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.

我正在使用的 configure 标志:

./configure --target=arm-apple-darwin --enable-static --disable-shared

之后,运行 gnumake 运行时没有错误。

After that, running gnumake runs without errors.

然后我将库添加到我的Xcode项目中。但是当我构建时,我得到了50行:

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?

编辑添加:

当我添加库时到项目t(右键单击项目名称,然后添加现有...),我得到:

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:


  • 它无法分辨为.a文件构建的架构

  • libsqlite3-cerod.a是为i386而构建的

我不明白这两种可能性,但我是iPhone新手开发。

I don't understand either possibility, but I'm new to iPhone development.

编辑添加

我尝试了@Sergio Moura的解决方案,得到了我的评论中提到的错误。

I tried @Sergio Moura's solution, and got the error mentioned in my comment.

我试过了@ sergio的解决方案。但我仍然得到相同的错误,从以下开始:

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)

我可能告诉Xcode错误的东西吗?我右键单击项目名称,然后选择添加 - >现有文件,然后从中选择六个或七个 .a 文件/ ICU / iosbuild / lib中。这是正确的过程吗?

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?

注意:

@sergio推荐 configure --host = arm-apple-darwin ,@ Sergio Moura正在使用 configure --target = arm-apple-darwin 。两者都没有区别。唉。

@sergio is recommending configure --host=arm-apple-darwin, @Sergio Moura is using configure --target=arm-apple-darwin. Neither made a difference, alas.

编辑#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)

编辑#3

@Stephen R. Loomis建议我将 #define U_HAVE_GCC_ATOMICS 1 更改为 0 (在 platform.h )没有任何区别,唉。我也意识到错误的最后一行(找不到架构arm6 )并不意味着它适用于 arm7 ,这只是一个fyi,这是一个交叉编译。当我指定 arm7 构建时,它失败并显示相同的消息。唉。

@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.

编辑#4

总结:@ sergio的构建标志基本上是正确的。我将-DU_HAVE_GCC_ATOMICS = 0添加到ios build的CFLAGS中。我做错的一件事是没有意识到我需要交叉编译库来创建一个设备构建。

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.

特别感谢Steven R. Loomis投球,以及Sergio Moura让事情顺利进行。

Special thanks to Steven R. Loomis for pitching in, and to Sergio Moura for getting things rolling.

推荐答案

编辑:

如果你这样做,我可以确认,如Steven R. Loomis建议:

I can confirm that if you do, as Steven R. Loomis suggests:


  1. 在icu / source / common / unicode / platform.h中将U_HAVE_GCC_ATOMICS设置为0

  1. set U_HAVE_GCC_ATOMICS to 0 in icu/source/common/unicode/platform.h

make distclean

make distclean

sh cross_configure.sh(使用我的脚本,即使用它) / p>

sh cross_configure.sh (using my script, i.e., if you are using it)

问题应该解决。实际上,如果不这样做,构建的库包含违规的未定义符号:

the problem should be solved. Indeed, without doing this, the built libraries contain the offending undefined symbol:

sergio@sfogliatella$ nm -a ./lib/libicuuc.a | grep __sync_
     U ___sync_synchronize
     U ___sync_val_compare_and_swap_4
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize
     U ___sync_synchronize

按照上述建议后,这是同一命令的结果:

After following the above suggestion, this is the result for the same command:

sergio@sfogliatella$ nm -a ./lib/libicuuc.a | grep __sync_
nm: no name list
nm: no name list

所以当然,二进制文件中不存在违规符号。

So, definitely, the offending symbol is not present in the binaries.

END EDIT。

交叉编译libicu for iOS需要两个单独的步骤:

Cross-compiling libicu for iOS requires two separate steps:


  1. 在构建目录中为主机(MacOS)编译libicu;

  1. compiling libicu for your host (MacOS) in a build directory;

通过指定交叉编译目录来交叉编译iOS的libicu。

cross-compiling libicu for iOS by also specifying the cross-compile directory.

第1步的必要之处在于libicu会自行引导一下,即它会编译一些中间工具,然后在构建过程的其余部分使用它们;这些工具需要在主机平台上运行,因此它们是可用的。

The reason why step 1 is necessary is that libicu will bootstrap itself a bit, i.e., it will compile some intermediate tools, which will be then used in the rest of the build process; those tools need to be ran on the host platform, so they are to be available.

总而言之,你可以按照步骤(1.编译为主持人):

Well, all in all, you can follow the steps (1. compile for the host):

$ cd $icu
$ mkdir hostbuild
$ cd hostbuild
$ ../icu/source/configure <configure settings you need>
$ gnumake

一旦完成,就可以进行交叉编译(2.编译for iOS):

Once this is done, it's time to cross-compile (2. compile for iOS):

$ cd $icu  (or cd ../ from the previous directory)
$ mkdir iosbuild
$ cd iosbuild
$ sh ../cross_configure_icu.sh
$ gnumake

其中 cross_configure_icu.sh 是一个类似于上面Sergio Moura提出的shell脚本,但是为libicu定制并使用更高级的llvm编译器:

Where cross_configure_icu.sh is a shell script similar to those proposed by Sergio Moura above, but customized for libicu and using the more advanced llvm compiler:

DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer
SDKROOT=$DEVROOT/SDKs/iPhoneOS4.3.sdk
SYSROOT=$SDKROOT

ICU_PATH=<ABSOLUTE_PATH_TO_YOUR_ICU_DIR>
ICU_FLAGS="-I$ICU_PATH/source/common/ -I$ICU_MYSRC/source/tools/tzcode/ "

export CXXPP=
export CXXPPFLAGS=
export CPPFLAGS="-I$SDKROOT/usr/lib/gcc/arm-apple-darwin10/4.2.1/include/ -I$SDKROOT/usr/llvm-gcc-4.2/lib/gcc/arm-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/arm-apple-darwin10-llvm-gcc-4.2"
export CXX="$DEVROOT/usr/llvm-gcc-4.2/bin/arm-apple-darwin10-llvm-g++-4.2"
export LDFLAGS="-L$SDKROOT/usr/lib/ -isysroot $SDKROOT -Wl,-dead_strip -miphoneos-version-min=2.0"

sh $ICU_PATH/source/configure --host=arm-apple-darwin --enable-static --disable-shared -with-cross-build=$ICU_PATH/hostbuild

在上面的脚本中( source ), ICU_PATH 是一个绝对路径,因为libicu configure需要 with-cross-build 选项。再次,检查SDK和编译器的值,但这应该适用于4.3。

In the above script (source), ICU_PATH is an absolute path because libicu configure so requires for the with-cross-build option. Again, check your values for the SDK and compilers, but this should be ok for 4.3.

最后,您应该考虑到Apple已经(一半)拒绝了至少一个与libicu链接的应用程序,因为它使用了保留的API。看看这个 S.O.主题

Finally, you should take into account that Apple has (half) rejected at least one app that was linked against libicu, because it uses reserved APIs. Have a look at this S.O. topic.

编辑:

听说你可以编译了!

现在,链接问题。

首先,请检查libicu库的格式是否正确:

first of all, please check that the libicu libraries are in the correct format:

sergio@sfogliatella$ lipo -info ./lib/libicuuc.a 

输出应该是(对于任何一个库):

output should be (for any of the libs):

input file ./lib/libicuuc.a is not a fat file
Non-fat file: ./lib/libicuuc.a is architecture: arm

如果没问题,那么下一个问题是:你是在为模拟器还是为设备构建?模拟器需要i386库,设备臂库...来自您显示的错误消息:

If this is fine, then next question: are you building for the simulator or for the device? simulator needs i386 libraries, device arm libraries... from the error message you show:


ld:警告:...文件已构建对于不支持的文件格式,这不是被链接的体系结构(i386)

ld: warning: ... file was built for unsupported file format which is not the architecture being linked (i386)

在我看来,你正在构建模拟器。为此你需要普通的macos x libs ...

it seems to me that you are building against the simulator... for that you will need "normal" macos x libs...

这篇关于如何构建ICU以便我可以在iPhone应用程序中使用它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆