星期四, 十二月 26, 2013

icu 52.1 for android window 下交叉编译 mingw-64/msys

00.下载android ndk http://developer.android.com/tools/sdk/ndk/index.html
01.下载安装MSys http://www.mingw.org/wiki/MSYS 1.01
02.下载gcc 3.8.1 w64版本,比官方版本修复了一些c++11bug,http://mingw-w64.sourceforge.net/
03.下载icu 代码52.1版本 http://site.icu-project.org/download/52#TOC-ICU4C-Download
04.展开icu代码到d:\icu
05.进入msys 环境
,使用export PATH将msys 1.0 bin目录和mingw bin目录加入到PATH里.
06.cd /d/icu;mkdir mingw;mkdir android;cd mingw
   这里主要是按照icu 目录下的README.html里的cross compile的步骤.
07. ../source/runConfigureICU MinGW ;#生成配置文件  然后执行make 开始编译
这里将自动在当前mingw目录下的bing子目录里生成后面需要的一些icu打包工具
  并生成mingw 下的icu相应的库,见本文后面详细的库名解释.所有的库在lib子目录里
在msys+mingw的编译是很顺利的,没有任何错误,麻烦就在于交叉编译。

08.cd ../android 准备使用交叉编译生成android下使用的库.
09. 准备生成编译icu的android ndk 独立工具链包执行
  比如:
  /d/android-ndk-r9b/build/tools/make-standalone-toolchain.sh --platform=android-9 --install-dir=/c/temp/my-toolchain -- toolchain=arm-linux-androideabi-4.8
如果是window 7/8 64 bit 需要加上 --system=windowx86_64
然后将export PATH将msys 1.0 bin目录和/c/temp/my-toolchain/bin及ndk 独立工具链目录下的arm-linux-androideabi/bin/
目录都放入到PATH变量中,在arm-linux-androideabi/bin/目录下有需要建库的ar.exe工具,所以必须加入到PATH变量里。
   export PATH=/d/msys/1.0/bin/:/d/androidgcc/bin/:/d/androidgcc/arm-linux-androideabi/bin/
用的是gcc 4.8.1 reversion 5版本。
10. ../source/configure --host=arm-linux-androideabi --target=arm-linux-androideabi --build=i686-pc-mingw32 --with-cross-build=/d/icu/mingw -enable-shared --disable-static

以下语法顺利生成静态链接库!!!()
$ sh ../source/configure --host=armv6-google-linux --enable-static --disable-shared -with-cross-build=/d/icu/mingw CC=a
rm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ AR=arm-linux-androideabi-ar
make 

再尝试只生成动态库,在data 目录下make出现许多问题,这个data模式只在尝试将data打包成动态库的方式的出现问题,
所以尝试用其他选项避开该问题。
$ sh ../source/configure --host=armv6-google-linux --enable-shared=yes --disable-static -with-cross-build=/d/icu/mingw CC=a
rm-linux-androideabi-gcc CXX=arm-linux-androideabi-g++ AR=arm-linux-androideabi-ar --with-data-packaging=archive

make
经过阅读 http://userguide.icu-project.org/icudata 可以看到这个data库并不是必须的,不影响常规的功能使用,如果是用
archive的方式,可以让数据和应用分类,更新该.dat数据文档,不需要重新编译icu的程序. 这样使用 --with-data-packaging=archive
最后生成的动态库如图,而字典.dat文件在/d/icu/android/data/out/icudt52l.dat ,可以将该文件和ICU程序一起发布
该文件比较巨大,可以在网站下下载定制的字典数据文件:http://apps.icu-project.org/datacustom/

可能的错误:
   注意,如果这里出现错误说不支持arm-linux-androideabi,需要下载补丁覆盖修改
     source目录config.sub和config.guess,然后再次执行该命令
需要下载支持android版本 config.sub
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD

以及config.guess source目录下
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
11.make开始编译,这里52.1版本编译data目录下的时候出现一些错误.
错误一:../../source/common/putil.cpp:133:22: fatal error: langinfo.h: No such file or directory
#include <langinfo.h>
从http://ftp.cc.uoc.gr/mirrors/OpenBSD/src/include/ 下载langinfo.h和nl_types.h 到/d/ic/source/common目录下,
再重新make clean;make.

错误二:
android/common: make 
rm -f ../lib/libicuuc.so.52 && ln -s libicuuc.so.52.1 ../lib/libicuuc.so.52
ln: creating symbolic link `../lib/libicuuc.so.52' to `libicuuc.so.52.1': No such file or directory
通过使用make -d 查询到规则是.o规则,最后在
D:\icu\source\config\mh-linux 中修改对应%.o的规则加上目录../lib修复该错误。
%.$(SO).$(SO_TARGET_VERSION_MAJOR): %.$(SO).$(SO_TARGET_VERSION)
     $(RM) $@ && ln -s ../lib/${<F} $@
%.$(SO): %.$(SO).$(SO_TARGET_VERSION_MAJOR)
     $(RM) $@ && ln -s ../lib/${*F}.$(SO).$(SO_TARGET_VERSION) $@

回到/d/icu/android 继续make 还会出现其他错误,但都可以通过提示反复修改mk-linx并继续make通过错误,
这是由于相对路径的错误造成的,具体原因可能是sed获取路径模式出现问题。

错误三:
android/data:
pkgdata: bash -c "arm-linux-androideabi-gcc -D_REENTRANT  -DU_HAVE_ELF_H=1 -DU_HAVE_ATOMIC=1  -DU_ATTRIBUTE_DEPRECATED=
-O2 -std=c99 -Wall -pedantic -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings   -c -I../../source/common -I
../common -DPIC -fPIC -o ./out/tmp/icudt52l_dat.o ./out/tmp/icudt52l_dat.s"
pkgdata: bash -c "arm-linux-androideabi-gcc -O2 -std=../lib/libicudata.lib -nodefaultlibs -nostdlib -o ../lib/icudata.so
.52 ./out/tmp/icudt52l_dat.o -Wl,-soname -Wl,icudata.so.52  -Wl,-Bsymbolic"
arm-linux-androideabi-gcc.exe: error: unrecognized command line option '-std=../lib/libicudata.lib'
-- return status = 1
Error generating library file. Failed command: arm-linux-androideabi-gcc -O2 -std=../lib/libicudata.lib -nodefaultlibs -
nostdlib -o ../lib/icudata.so.52 ./out/tmp/icudt52l_dat.o -Wl,-soname -Wl,icudata.so.52  -Wl,-Bsymbolic
Error generating assembly code for data.
很明显是 -std 后面的选项出现了错误
cd android\data ;make -d 查看是那个规则出现的错误
发现是D:\icu\source\tools\pkgdata\pkgdata.cpp  method pkg_checkFlag,代码逻辑错误:
1858行代码,将部分数据丢,Mingw 下不需要如此处理:
     #if U_PLATFORM == U_PF_CYGWIN
         uprv_memset(flag + position, 0, length - position);
     #endif

修正该错误后,依然不能通过,依然是无法发现:../lib/libicudata.lib

10.
首先要看README.html 

How To Cross Compile ICU 里有如何骄交叉编译的步骤

Here are some useful links regarding ICU and internationalization in general.
ICU, ICU4C & ICU4J Homepagehttp://icu-project.org/
FAQ - Frequently Asked Questions about ICUhttp://userguide.icu-project.org/icufaq
ICU User's Guidehttp://userguide.icu-project.org/
How To Use ICUhttp://userguide.icu-project.org/howtouseicu
Download ICU Releaseshttp://site.icu-project.org/download
ICU4C API Documentation Onlinehttp://icu-project.org/apiref/icu4c/
Online ICU Demoshttp://demo.icu-project.org/icu-bin/icudemos
Contacts and Bug Reports/Feature Requestshttp://site.icu-project.org/contacts

Library NameWindows FilenameLinux FilenameComment
Data LibraryicudtXYl.dlllibicudata.so.XY.ZData required by the Common and I18n libraries. There are many ways to package and customize this data, but by default this is all you need.
Common LibraryicuucXY.dlllibicuuc.so.XY.ZBase library required by all other ICU libraries.
Internationalization (i18n) LibraryicuinXY.dlllibicui18n.so.XY.ZA library that contains many locale based internationalization (i18n) functions.
Layout EngineiculeXY.dlllibicule.so.XY.ZAn optional engine for doing font layout.
Layout Extensions EngineiculxXY.dlllibiculx.so.XY.ZAn optional engine for doing font layout that uses parts of ICU.
ICU I/O (Unicode stdio) LibraryicuioXY.dlllibicuio.so.XY.ZAn optional library that provides a stdio like API with Unicode support.
Tool Utility LibraryicutuXY.dlllibicutu.so.XY.ZAn internal library that contains internal APIs that are only used by ICU's tools. If you do not use ICU's tools, you do not need this library.


参看README.html里有关cross complile的步骤:

Three initially-empty directories will be used in this example:
/icua copy of the ICU source
/buildAan empty directory, it will contain ICU built for A
(MacOSX in this case)
/buildBan empty directory, it will contain ICU built for B
(HaikuOS in this case)
  1. Check out or unpack the ICU source code into the /icu directory.You will have the directories /icu/source, etc.
  2. Build ICU in /buildA normally (using runConfigureICU or configure):
    cd /d/icu/mingw
    sh /d/icu/source/runConfigureICU MinGW
    gnumake
    
  3. Set PATH or other variables as needed, such as CPPFLAGS.
  4. Build ICU in /buildB
    Note: "--with-cross-build" takes an absolute path.
    cd /d/icu/android
    sh /d/icu/source/configure  --host=arm-linux-androideabi --with-cross-build=/d/icu/mingw
    gnumake
    
  5. Tests and testdata can be built with cd test;make