libiconv交叉编译提示arm-none-linux-gnueabi-gcc


title: libiconv交叉编译提示arm-none-linux-gnueabi-gcc
date: 2019/3/6 17:45:48
toc: true

libiconv交叉编译提示arm-none-linux-gnueabi-gcc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>

int main(int argc, char **argv)
{
  /* 目的编码, TRANSLIT:遇到无法转换的字符就找相近字符替换
   *          IGNORE  :遇到无法转换字符跳过*/
  //char *encTo = "UNICODE//TRANSLIT";
    int i;
  char *encTo = "UTF-8";
  /* 源编码 */
  char *encFrom = "GBK";

  iconv_t cd = iconv_open (encTo, encFrom);
  if (cd == (iconv_t)-1)
  {
      perror ("iconv_open");
      return -1;
  }
      
  /* 需要转换的字符串 */
  // GBK         D6D0  B9FA
  // unicode  4E2D 56FD
  // UTF-8     E4B8AD   E59BBD
  char inbuf[1024] = {0xD6,0xD0,0xB9,0xFA}; 
  size_t srclen = strlen (inbuf);
  /* 打印需要转换的字符串的长度 */
  printf("srclen=%ld
", srclen);

  i=0;
  printf("input= ");
  while (inbuf[i]) {
      printf("%x  ",(unsigned char)inbuf[i]);
      i++;
  }
  printf("
");

  /* 存放转换后的字符串 */
  size_t outlen = 1024;
  char outbuf[outlen];
  memset (outbuf, 0, outlen);

  /* 由于iconv()函数会修改指针,所以要保存源指针 */
  char *srcstart = inbuf;
  char *tempoutbuf = outbuf;

  /* 进行转换
   *@param cd iconv_open()产生的句柄
   *@param srcstart 需要转换的字符串
   *@param srclen 存放还有多少字符没有转换
   *@param tempoutbuf 存放转换后的字符串
   *@param outlen 存放转换后,tempoutbuf剩余的空间
   *
   * */
  size_t ret = iconv (cd, &srcstart, &srclen, &tempoutbuf, &outlen);
  if (ret == -1)
  {
      perror ("iconv err
");
      return  -1;
  }
  printf ("ret is %ld
",ret);
   printf ("outlen is %ld
",1024-outlen);

  printf("out is 
");
  for (i=0;i<10;i++) {
      printf("%x ",(unsigned char)outbuf[i]);
  }
  printf("
");


  iconv_close (cd);
  return 0;
}

最终显示结果

/mnt/repo/test/libiconv-1.15 #  ../arm
srclen=4
input= d6  d0  b9  fa
ret is 0
outlen is 6
out is
e4 b8 ad e5 9b bd 0 0 0 0

移植到ARM

1.14版本直接成功,1.15(最新)失败了,折腾了好久

先下载了最先的libiconv-1.15.tar.gz版本,解压配置

./configure --prefix=$PWD/out --host=arm-linux
make
make install

然后提示

arm-none-linux-gnueabi-gcc: 0": No such file or directory
<command-line>: warning: missing terminating " character
Makefile:50: recipe for target 'preloadable_libiconv.so' failed
make[1]: *** [preloadable_libiconv.so] Error 1
make[1]: Leaving directory '/home/book/stu/repo/test/libiconv-1.15/preload'
Makefile:33: recipe for target 'all' failed
make: *** [all] Error 2

查看下自己的编译工具,是有这个的arm-none-linux-gnueabi-gcc

book@100ask:~$ echo $PATH
/home/book/bin:/home/book/.local/bin:/opt/slickedit-pro2017/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/arm/4.3.2/bin/:/snap/bin
book@100ask:~$


book@100ask:~$ cd /usr/local/arm/4.3.2/bin/
book@100ask:/usr/local/arm/4.3.2/bin$ ls
arm-linux-addr2line  arm-linux-gcc        arm-linux-nm       arm-linux-strings                 arm-none-linux-gnueabi-cpp        arm-none-linux-gnueabi-gprof    arm-none-linux-gnueabi-size
arm-linux-ar         arm-linux-gcc-4.3.2  arm-linux-objcopy  arm-linux-strip                   arm-none-linux-gnueabi-g++        arm-none-linux-gnueabi-ld       arm-none-linux-gnueabi-sprite
arm-linux-as         arm-linux-gcov       arm-linux-objdump  arm-none-linux-gnueabi-addr2line  arm-none-linux-gnueabi-gcc        arm-none-linux-gnueabi-nm       arm-none-linux-gnueabi-strings
arm-linux-c++        arm-linux-gdb        arm-linux-ranlib   arm-none-linux-gnueabi-ar         arm-none-linux-gnueabi-gcc-4.3.2  arm-none-linux-gnueabi-objcopy  arm-none-linux-gnueabi-strip
arm-linux-c++filt    arm-linux-gdbtui     arm-linux-readelf  arm-none-linux-gnueabi-as         arm-none-linux-gnueabi-gcov       arm-none-linux-gnueabi-objdump
arm-linux-cpp        arm-linux-gprof      arm-linux-size     arm-none-linux-gnueabi-c++        arm-none-linux-gnueabi-gdb        arm-none-linux-gnueabi-ranlib
arm-linux-g++        arm-linux-ld         arm-linux-sprite   arm-none-linux-gnueabi-c++filt    arm-none-linux-gnueabi-gdbtui     arm-none-linux-gnueabi-readelf


book@100ask:/usr/local/arm/4.3.2/bin$ ls arm-none-linux-gnueabi-gcc
arm-none-linux-gnueabi-gcc

网上搜素一圈都说安装一个库,然而都安装补上了

sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0

后来找到这里,指定CC然后make就好了

./configure --prefix=$PWD/out --host=arm-linux CC=/usr/local/arm/4.3.2/bin/arm-linux-gcc

总结

./configure --prefix=$PWD/out --host=arm-linux CC=/usr/local/arm/4.3.2/bin/arm-linux-gcc
make
make install

然后复制到单板的lib下
cp  out/lib/preloadable_libiconv.so /lib/
配置动态库
export LD_PRELOAD=/lib/preloadable_libiconv.so
# 卸载这个动态库,如果要删除so,需要先卸载
unset LD_PRELOAD

LD_PRELOAD 使用

  1. 定义与目标函数完全一样的函数,包括名称、变量及类型、返回值及类型等
  2. 将包含替换函数的源码编译为动态链接库
  3. 通过命令 export LD_PRELOAD="库文件路径",设置要优先替换动态链接库
  4. 如果找不替换库,可以通过 export LD_LIBRARY_PATH=库文件所在目录路径,设置系统查找库的目录
  5. 替换结束,要还原函数调用关系,用命令unset LD_PRELOAD 解除
  6. 想查询依赖关系,可以用ldd 程序名称

LD_PRELOAD,是个环境变量,用于动态库的加载,动态库加载的优先级最高,一般情况下,其加载顺序为LD_PRELOAD>LD_LIBRARY_PATH>/etc/ld.so.cache>/lib>/usr/lib。

参考文档

arm移植libiconv(字符编码转换) https://blog.csdn.net/dyzhen/article/details/50864419

LD_PRELOAD的偷梁换柱之能 https://www.cnblogs.com/net66/p/5609026.html

原文地址:https://www.cnblogs.com/zongzi10010/p/10492519.html