日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

red hat linux没有库文件libiconv.so,libiconv库链接问题一则(备忘)

發(fā)布時間:2023/12/10 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 red hat linux没有库文件libiconv.so,libiconv库链接问题一则(备忘) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

與在Solaris系統(tǒng)上不同,Linux的libc庫中包含了libiconv庫中函數(shù)的定義,因此在Linux上使用libiconv庫相關函數(shù),編譯時是不需要顯式-liconv的。但最近我的一位同事在某redhat enterprise server 5.6機器上編譯程序時卻遇到了找不到iconv庫函數(shù)符號的鏈接問題,到底是怎樣一回事呢?這里分享一下問題查找過程。

一、現(xiàn)場重現(xiàn)

這里借用一下這位同事的測試程序以及那臺機器,重現(xiàn)一下問題過程:

/test.c/include

int main(void)

{

int r;

char *sin, *sout;

size_t lenin, lenout;

char *src = "你好!";

char dst[256] = {0};

iconv_t c_pt;

sin = src;

lenin = strlen(src)+1;

sout = dst;

lenout = 256;

if ((c_pt = iconv_open("UTF-8", "GB2312")) == (iconv_t)(-1)){

printf("iconv_open error!. errno[%d].\n", errno);

return -1;

}

if ((r = iconv(c_pt, (char **)&sin, &lenin, &sout, &lenout)) != 0){

printf("iconv error!. errno[%d].\n", r);

return -1;

}

iconv_close(c_pt);

printf("SRC[%s], DST[%s].\n", src, dst);

return 0;

}

根據(jù)之前的經(jīng)驗,我們按如下命令編譯該程序:$> gcc -g -o test test.c

/tmp/ccyQ5blC.o: In function `main':

/home/tonybai/tmp/test.c:28: undefined reference to `libiconv_open'

/home/tonybai/tmp/test.c:33: undefined reference to `libiconv'

/home/tonybai/tmp/test.c:38: undefined reference to `libiconv_close'

咦,這是咋搞的呢?怎么找不到iconv庫的符號!!!顯式加上iconv的鏈接指示再試試。$> gcc -g -o test test.c -liconv

這回編譯OK了。的確如那位同事所說出現(xiàn)了怪異的情況。

二、現(xiàn)場取證

慣性思維讓我首先提出疑問:難道是這臺機器上的libc版本有差異,檢查一下libc中是否定義了iconv相關符號。$ nm /lib64/libc.so.6 |grep iconv

000000397141e040 T iconv

000000397141e1e0 T iconv_close

000000397141ddc0 T iconv_open

iconv的函數(shù)都定義了呀!怎么會鏈接不到?

我們再來看看已經(jīng)編譯成功的那個test到底連接到哪個iconv庫了。$ ldd test

linux-vdso.so.1 => (0x00007fff77d6b000)

libiconv.so.2 => /usr/local/lib/libiconv.so.2 (0x00002abbeb09e000)

libc.so.6 => /lib64/libc.so.6 (0×0000003971400000)

/lib64/ld-linux-x86-64.so.2 (0×0000003971000000)

哦,系統(tǒng)里居然在/usr/local/lib下面單獨安裝了一份libiconv。gcc顯然是鏈接到這里的libiconv了,但gcc怎么會鏈接到這里了呢?

三、大偵探的分析^_^

Gcc到底做了什么呢?我們看看其verbose的輸出結果。$ gcc -g -o test test.c -liconv -v

使用內(nèi)建 specs。

目標:x86_64-redhat-linux

配置為:../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix –enable- checking=release –with-system-zlib –enable-__cxa_atexit –disable-libunwind-exceptions –enable-libgcj-multifile –enable-languages=c,c++, objc,obj-c++,java,fortran,ada –enable-java-awt=gtk –disable-dssi –disable-plugin –with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre –with-cpu=generic –host=x86_64-redhat-linux

線程模型:posix

gcc 版本 4.1.2 20080704 (Red Hat 4.1.2-50)

/usr/libexec/gcc/x86_64-redhat-linux/4.1.2/cc1 -quiet -v test.c -quiet -dumpbase test.c -mtune=generic -auxbase test -g -version -o /tmp/ ccypZm0v.s

忽略不存在的目錄“/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../x86_64-redhat-linux/include”

#include "…" 搜索從這里開始:

#include 搜索從這里開始:

/usr/local/include

/usr/lib/gcc/x86_64-redhat-linux/4.1.2/include

/usr/include

搜索列表結束。

GNU C 版本 4.1.2 20080704 (Red Hat 4.1.2-50) (x86_64-redhat-linux)

由 GNU C 版本 4.1.2 20080704 (Red Hat 4.1.2-50) 編譯。

GGC 準則:–param ggc-min-expand=100 –param ggc-min-heapsize=131072

Compiler executable checksum: ef754737661c9c384f73674bd4e06594

as -V -Qy -o /tmp/ccaqvDgX.o /tmp/ccypZm0v.s

GNU assembler version 2.17.50.0.6-14.el5 (x86_64-redhat-linux) using BFD version 2.17.50.0.6-14.el5 20061020

/usr/libexec/gcc/x86_64-redhat-linux/4.1.2/collect2 –eh-frame-hdr -m elf_x86_64 –hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so. 2 -o test /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crti.o /usr/ lib/gcc/x86_64-redhat-linux/4.1.2/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2 -L/usr/lib/gcc/ x86_64-redhat-linux/4.1.2/../../../../lib64 -L/lib/../lib64

-L/usr/lib/../lib64 /tmp/ccaqvDgX.o -liconv -lgcc –as-needed -lgcc_s –no-as-needed -lc -lgcc –as-needed -lgcc_s –no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crtn.o

從這個結果來看,gcc在search iconv.h這個頭文件時,首先找到的是/usr/local/include/iconv.h,而不是/usr/include/iconv.h。這兩個文件有啥不同么?

在/usr/local/include/iconv.h中,我找到如下代碼:…

#ifndef LIBICONV_PLUG

#define iconv_open libiconv_open

#endif

extern iconv_t iconv_open (const char* tocode, const char* fromcode);

libiconv_open vs iconv_open,臥槽!!!再對比一下前面編譯時輸出的錯誤信息:

/tmp/ccyQ5blC.o: In function `main':

/home/tonybai/tmp/test.c:28: undefined reference to `libiconv_open'

/home/tonybai/tmp/test.c:33: undefined reference to `libiconv'

/home/tonybai/tmp/test.c:38: undefined reference to `libiconv_close'

大偵探醒悟了!大偵探帶你還原一下真實情況。

我們在執(zhí)行gcc -g -o test test.c時, 根據(jù)gcc -v中include search dir的順序,gcc首先search到的是/usr/local/include/iconv.h,而這里iconv_open等函數(shù)被預編譯器替換成 了libiconv_open等加上了lib前綴的函數(shù),而這些函數(shù)符號顯然在libc中是無法找到的,libc中只有不帶lib前綴的 iconv_open等函數(shù)的定義。大偵探也是一時眼拙了,沒有細致查看gcc的編譯錯誤信息中的內(nèi)容,這就是問題所在!

而gcc -g -o test test.c -liconv為何可以順利編譯通過呢?gcc是如何找到/usr/local/lib下的libiconv的呢?大偵探再次為大家還原一下真相。

我們在執(zhí)行gcc -g -o test test.c -liconv時,gcc同 樣首先search到的是/usr/local/include/iconv.h,然后編譯test.c源碼,ok;接下來啟動ld程序進行鏈接;ld找 到了libiconv,ld是怎么找到iconv的呢,libiconv在/usr/local/lib下,ld顯然是到這個目錄下search了。我們 通過執(zhí)行下面命令可以知曉ld的默認搜索路徑:$> ld -verbose|grep SEARCH

SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");

ld的默認search路徑中有/usr/local/lib(我之前一直是以為/usr/local/lib不是gcc/ld的默認搜索路徑的),因此找到libiconv就不足為奇了。方案一:

可以將/usr/local/lib下的那份libiconv卸載掉!

方案二:

gcc 加上 -liconv

方案三:

make編譯強制使用libc中的iconv實現(xiàn)了,CCFLAGS = -DLIBICONV_PLUG

總結

以上是生活随笔為你收集整理的red hat linux没有库文件libiconv.so,libiconv库链接问题一则(备忘)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。