libiconv官方源码:https://ftp.gnu.org/pub/gnu/libiconv/
参考1:http://bbs.chinaunix.net/thread-3775808-1-1.html
裁剪libiconv,项目里面只需要UTF8与GB2312的转换。 1.下载源代码编译,编写测试代码,gdb调试,查看UTF8和GB2312转换调用的函数,分别是xxx_wctomb和xxx_mbtowc(文件就是utf8.h/euc_cn.h),aliases.gperf文件里面有定义UTF-8, ei_utf8和GB2312, ei_euc_cn。 2.encoding.def文件进行修改,最后只剩下:
DEFENCODING(( “US-ASCII”, / IANA / “ASCII”, / IANA, JDK 1.1 / “ISO646-US”, / IANA / “ISO_646.IRV:1991”, / IANA / “ISO-IR-6”, / IANA / “ANSI_X3.4-1968”, / IANA / “ANSI_X3.4-1986”, / IANA / “CP367”, / IANA / “IBM367”, / IANA / “US”, / IANA / “csASCII”, / IANA / /“ISO646.1991-IRV”, X11R6.4 / ), ascii, { ascii_mbtowc, NULL }, { ascii_wctomb, NULL })
/ General multi-byte encodings /
DEFENCODING(( “UTF-8”, / IANA, RFC 2279 / /“UTF8”, JDK 1.1 / /“CP65001”, Windows / ), utf8, { utf8_mbtowc, NULL }, { utf8_wctomb, NULL })
DEFENCODING(( “GB_2312-80”, / IANA / “ISO-IR-58”, / IANA / “csISO58GB231280”, / IANA / “CHINESE”, / IANA / /“GB2312.1980-0”, X11R6.4 / ), gb2312, { gb2312_mbtowc, NULL }, { gb2312_wctomb, NULL })
DEFENCODING(( “EUC-CN”, / glibc / “EUCCN”, / glibc, IRIX / “GB2312”, / IANA / “CN-GB”, / RFC 1922 / “csGB2312”, / IANA / /“EUC_CN”, JDK 1.1 / /“CP51936”, Windows / ), euc_cn, { euc_cn_mbtowc, NULL }, { euc_cn_wctomb, NULL })
3.然后对aliases.h进行修改,删除没有用的编码。
struct stringpool_t { char stringpool_str117[sizeof(“CHINESE”)]; char stringpool_str120[sizeof(“ASCII”)]; char stringpool_str165[sizeof(“GB2312”)]; char stringpool_str255[sizeof(“UTF-8”)]; }; static const struct stringpool_t stringpool_contents = { “CHINESE”, “ASCII”, “GB2312”, “UTF-8”, }; / 与上面的struct stringpool_t对应起来 / static const struct alias aliases[] = { #line 14 “lib/aliases.gperf” / 与gperf文件中的行号对应起来/ {(int)(long)&((struct stringpool_t )0)->stringpool_str117, ei_gb2312}, #line 12 “lib/aliases.gperf” {(int)(long)&((struct stringpool_t )0)->stringpool_str120, ei_ascii}, #line 15 “lib/aliases.gperf” {(int)(long)&((struct stringpool_t )0)->stringpool_str165, ei_euc_cn}, #line 13 “lib/aliases.gperf” {(int)(long)&((struct stringpool_t )0)->stringpool_str255, ei_utf8}, };
/修改为只支持UTF8和GB2312,不用在查找,可以删除多余的代码/ const struct alias aliases_lookup (register const char str, register unsigned int len) { if (!strcmp(str, “UTF-8”)) return &aliases[3]; else if (!strcmp(str, “GB2312”)) return &aliases[2]; return 0; }
4.修改aliases. gperf,删除大部分编码,只剩下你需要的编码类型。
struct alias { int name; unsigned int encoding_index; }; %struct-type %language=ANSI-C %define hash-function-name aliases_hash %define lookup-function-name aliases_lookup %7bit %readonly-tables %global-table %define word-array-name aliases %pic %% ASCII, ei_ascii UTF-8, ei_utf8 CHINESE, ei_gb2312 GB2312, ei_euc_cn
5.然后再make,会有几个文件报错(canonical.h等),对报错的地方进行屏蔽,具体看上传已裁减的libiconv源代码包:
修改了lib文件夹下的这几个文件:loop_unicode.h , iconv_open1.h , canonical_local.h , iconv.c ,aliases.gperf ,encodings.def , aliases.h, canonical.h。
参考2:https://blog.csdn.net/houxn22/article/details/39396983?utm_source=blogxgwz3
从网上下载了libiconv-1.14,编译后发现生成的库文件有1.2M之多,感觉太大了,自己认为在库中数据占很大部分,因为iconv支持世界上几乎所有常见语言的编码转换,但是我只需要UTF-8转换为GB2312,所以有必要裁剪一下。
在对libiconv-1.14裁剪时遇到了很多错误,特别是canonical.h的一大串错误,感觉canonical.h是由其它地方生成的文件,不太好解决,于是决定下载个低版本的libiconv试试,结果还真成功了,下面写一下自己裁剪的过程。
-
从GNU网站下载libiconv-1.8.tar.gz (http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.8.tar.gz 或者 交大开源镜像http://mirror.bjtu.edu.cn/gnu/libiconv/libiconv-1.8.tar.gz)
-
下载后解压缩,进入libiconv-1.8目录。
cd libiconv-1.8
新建一个目录作为安装路径:
mkdir iconv
3.修改源文件。
需要修改的文件只有两个,都在lib目录下,一个为aliases.gperf,另一个为encodings.def。
首先打开aliases.gperf,自上到下,直到CSISOLATIN1, ei_iso8859_1这一行,这些是需要保留的,然后剩下的就可以自由裁减了。
由于我只需要GB2312,所以后面的部分我只保留了下面几行:
EUC-CN, ei_euc_cn EUCCN, ei_euc_cn GB2312, ei_euc_cn CN-GB, ei_euc_cn CSGB2312, ei_euc_cn 其他的行全部删掉了,然后保存,修改后的aliases.gperf文件如下所示:
struct alias { const char* name; unsigned int encoding_index; }; %% US-ASCII, ei_ascii ASCII, ei_ascii ISO646-US, ei_ascii ISO_646.IRV:1991, ei_ascii ISO-IR-6, ei_ascii ANSI_X3.4-1968, ei_ascii ANSI_X3.4-1986, ei_ascii CP367, ei_ascii IBM367, ei_ascii US, ei_ascii CSASCII, ei_ascii UTF-8, ei_utf8 UCS-2, ei_ucs2 ISO-10646-UCS-2, ei_ucs2 CSUNICODE, ei_ucs2 UCS-2BE, ei_ucs2be UNICODEBIG, ei_ucs2be UNICODE-1-1, ei_ucs2be CSUNICODE11, ei_ucs2be UCS-2LE, ei_ucs2le UNICODELITTLE, ei_ucs2le UCS-4, ei_ucs4 ISO-10646-UCS-4, ei_ucs4 CSUCS4, ei_ucs4 UCS-4BE, ei_ucs4be UCS-4LE, ei_ucs4le UTF-16, ei_utf16 UTF-16BE, ei_utf16be UTF-16LE, ei_utf16le UTF-32, ei_utf32 UTF-32BE, ei_utf32be UTF-32LE, ei_utf32le UTF-7, ei_utf7 UNICODE-1-1-UTF-7, ei_utf7 CSUNICODE11UTF7, ei_utf7 UCS-2-INTERNAL, ei_ucs2internal UCS-2-SWAPPED, ei_ucs2swapped UCS-4-INTERNAL, ei_ucs4internal UCS-4-SWAPPED, ei_ucs4swapped C99, ei_c99 JAVA, ei_java ISO-8859-1, ei_iso8859_1 ISO_8859-1, ei_iso8859_1 ISO_8859-1:1987, ei_iso8859_1 ISO-IR-100, ei_iso8859_1 CP819, ei_iso8859_1 IBM819, ei_iso8859_1 LATIN1, ei_iso8859_1 L1, ei_iso8859_1 CSISOLATIN1, ei_iso8859_1 EUC-CN, ei_euc_cn EUCCN, ei_euc_cn GB2312, ei_euc_cn CN-GB, ei_euc_cn CSGB2312, ei_euc_cn
下面修改encodings.def,这个根据刚才修改的aliases.gperf来修改。自上而下,直到
DEFENCODING(( “ISO-8859-1”, / IANA / “ISO_8859-1”, / IANA / “ISO_8859-1:1987”, / IANA / “ISO-IR-100”, / IANA / “CP819”, / IANA / “IBM819”, / IANA / “LATIN1”, / IANA / “L1”, / IANA / “csISOLatin1”, / IANA / /“ISO8859-1”, X11R6.4, glibc / /“ISO8859_1”, JDK 1.1 / ), iso8859_1, { iso8859_1_mbtowc, NULL }, { iso8859_1_wctomb, NULL }) 这一部分,上面所有的是需要保留的(包括这一部分)。后面再保留:
DEFENCODING(( “EUC-CN”, / glibc / “EUCCN”, / glibc / “GB2312”, / IANA / “CN-GB”, / RFC 1922 / “csGB2312”, / IANA / /“EUC_CN”, JDK 1.1 / ), euc_cn, { euc_cn_mbtowc, NULL }, { euc_cn_wctomb, NULL }) 这个是关于GB2312编码的。剩余的部分可以全部删除了,这与aliases.gperf对应起来了。
- 由aliases.gperf重新生成aliases.h。
aliases.gperf文件的目的是为了生成aliases.h。打开aliases.h,发现前面几行有些注释:
/ ANSI-C code produced by gperf version 3.0.3 / / Command-line: gperf -t -L ANSI-C -H aliases_hash -N aliases_lookup -G -W aliases -7 -C -k ‘1,3-11,$’ -i 1 aliases.gperf /
看到了生成aliases.h的命令行,于是在lib目录下,执行:
gperf -t -L ANSI-C -H aliases_hash -N aliases_lookup -G -W aliases -7 -C -k ‘1,3-11,$’ -i 1 aliases.gperf > aliases.h
便可以了。
- 配置,编译
进入libiconv-1.81的根目录,执行
./configure CC=powerpc-linux-gcc –target=powerpc-linux –host=powerpc-linux –enable-shared=yes –enable-static=yes –prefix=/opt/externel/libiconv-1.8/iconv
配置完成后,make;make install便可以了。
最后在iconv/lib目录下生成了我所需要的动态库和静态库(libiconv.so.2.1.0和libiconv.a)。
没有精简之前,生成的libiconv.so.2.1.0有1.1M,精简后只有220K。
注:上面配置过程中,–enable-static=yes是为了生成静态库libiconv.a,这样我在编译自己的程序时可以静态链接libiconv.a,把代码编译到自己的可执行程序中,就不再需要在运行时链接libiconv.so.2.1.0库了。