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

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

问题描述

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

我正在维护一个使用 SQLite 数据库的 iPhone 应用程序.现在我必须在启用 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 标志:

The configure flags I'm using:

./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)

知道我做错了什么吗?

编辑添加:

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

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 错了?我右键单击项目名称,然后选择添加->现有文件",然后从 /icu/iosbuild/lib.a 文件>.这是正确的过程吗?

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_ATOMICS1 更改为 0(在 platform.h代码>)没有区别,唉.我还意识到错误的最后一行(not found for architecture arm6)并不意味着它适用于 arm7,只是仅供参考,这是一个交叉编译.当我指定一个 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 的构建标志基本上是正确的.我在 ios 版本的 CFLAGS 中添加了 -DU_HAVE_GCC_ATOMICS=0.我一直做错的一件事是没有意识到我需要交叉编译库来创建设备构建.

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

使 distclean

make distclean

sh cross_configure.sh(使用我的脚本,即,如果你正在使用它)

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.

结束编辑.

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

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

很高兴听到你可以编译!

happy the hear that you could compile!

现在是链接问题.

首先,请检查 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 库...

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天全站免登陆