1. 程式人生 > >Linux編譯的時候由於連結庫出現的各種問題

Linux編譯的時候由於連結庫出現的各種問題

一 動態庫與機器位數不符合

報錯內容:

/usr/bin/ld: skipping incompatible /usr/lib/libcrypto.so when searching for -lcrypto
/usr/bin/ld: skipping incompatible /usr/lib/libc.so when searching for -lc

此種情況就是libc.so以及libcrypto.so編譯的時候是64位而本機器的位數為32位,或者相反情況,我遇到的情況是動態庫是32位編譯的,但是本機器是64位,所以需要連線的庫應該連線到64位,這兩個庫都是系統庫,在/usr/lib64/這個目錄下就有現成的64位對應動態庫,所以只要將Makefile裡面的-L/usr/lib改成-L/usr/lib64就可以,非系統庫的話就需要自己去找與自己機器匹配的位數對應的庫

如果自己的機器是32位,但是隻有64位的庫,那麼可以修改編譯的引數,gcc編譯的時候加上-m64:
gcc -m64 test.c (test會按照64位機器來進行編譯)

二 找不到系統庫

報錯內容:
/usr/bin/ld: cannot find -lcrypto

1.定位庫的位置:
    a.find / -name libcrypto*(需要root許可權)
    b.locate crypto(無需root許可權)
2.如果找到了/usr/local/lib/libcrypto.so.1
則做一個軟連線(系統預設庫路徑:/usr/lib,/lib):
    ln -s /usr/local/lib/libcrypto.so.1 /usr/lib/libcrypto.so

三 找不到自定義庫(非系統提供的庫)

報錯內容:

/usr/bin/ld:cannot find -lcomm
/usr/bin/ld:cannot find -lipc
找不到這兩個庫,這種情況基本上就是沒有加上這兩個庫所在的路徑,Makefile中加上-L/home/test/example/lib就可以(庫在此目錄下)

四 未定義的符號

報錯內容:
/home/test/src/../lib/libSDKcomm.a(cli_sndrcv_v1.o): In function `cli_sndrcv_v1`:
/home/sunlan/SDK2.6/obj/../tcp/cli_sndrcv_v1.c:73: undefined reference to `MD5_Update’

代表這些函式的標頭檔案之類的已經包含,但是沒有提供函式庫
編譯選項中需要加入:-lmd5(假設libmd5.so庫未連結)
假設libev.a libcoro.a ,其中libcoro.a中呼叫來libev.a中的函式,則連結的順序是:
BUILD_LIBS = -lcoro -lev

當C檔案中出現的結構體,寫對了但是編譯報錯找不到裡面的對應成員,1.可能標頭檔案未包含 2.標頭檔案包含了,則很有可能是依賴庫的原因,標頭檔案路徑或者庫檔案路徑沒有加到連結選項中(-L),總之就是makefile中缺少了一個依賴的檔案或檔案路徑,致使它找不到

五 執行的時候出錯

報錯內容:
/usr/local/bin/luajit ./test.lua
/usr/local/bin/luajit: error loading module ‘lualog’ from file ‘./lualog.so’:
libluajit-5.1.so.2: cannot open shared object file: No such file or directory
stack traceback:
[C]: at 0x0044d340
[C]: in function ‘require’
./test.lua:3: in main chunk
[C]: at 0x00404180

第一步:確認有哪些Lib無法Load
[[email protected]]# ldd /home/xuli/Desktop/supex/open/lib/lua-log/lualog.so
linux-vdso.so.1 => (0x00007fff23e00000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fbf2cbe8000)
libluajit-5.1.so.2 => not found
libc.so.6 => /lib64/libc.so.6 (0x00007fbf2c850000)
/lib64/ld-linux-x86-64.so.2 (0x000000371ea00000)

第二步:查詢到缺失的動態庫在哪裡:libluajit-5.1.so.2 => not found
[[email protected] supex]# find / -name libluajit-5.1.so.2
/usr/local/lib/libluajit-5.1.so.2

第三步:將缺失的動態庫軟連結到系統預設會搜尋的動態庫的地方 /usr/lib
[[email protected] supex]# ln -s /usr/local/lib/libluajit-5.1.so.2 /usr/lib

第四步:執行ldconfig命令重建/etc/ld.so.cache
[[email protected] supex]# ldconfig

總結:

由於庫的原因導致編譯失敗,第一步就是要確認電腦中確實存在此庫,如果不存在當然是需要獲取此庫到電腦中,電腦中確實有庫的存在但是還是編譯失敗基本上就是路徑問題,系統無法找到,以下三種方法解決:

1.用ln -s將需要的so檔案連結到/usr/lib或者/lib這兩個預設的目錄下邊,之後ldconfig 一下
如:ln -s /where/you/install/lib/libyourlib.so /usr/lib/libyourlib.so


2.修改/etc/ld.so.conf配置檔案,然後重新整理(root)
 vim /etc/ld.so.conf.d/local.conf
在自己新建的local.conf檔案中加上一句:
/where/you/install/lib
最後執行一下ldconfig

3.修改LD_LIBRARY_PATH系統環境變數
export LD_LIBRARY_PATH=/where/you/install/lib:$LD_LIBRARY_PATH
最後執行一下ldconfig
不過這個只是臨時的更改了

註釋:

  1. 往/lib和/usr/lib裡面加東西,是不用修改/etc/ld.so.conf的,但是完了之後要調一下ldconfig,不然這個library會找不到
  2. 想往上面兩個目錄以外加東西的時候,一定要修改/etc/ld.so.conf,然後再呼叫ldconfig,不然也會找不到
    比如安裝了一個mysql到/usr/local/mysql,mysql有一大堆library在/usr/local/mysql/lib下面,這時就需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib,儲存過後ldconfig一下,新的library才能在程式執行時被找到。
  3. 如果想在這兩個目錄以外放lib,但是又不想在/etc/ld.so.conf中加東西(或者是沒有許可權加東西)。那也可以,就是export一個全域性變數LD_LIBRARY_PATH,然後執行程式的時候就會去這個目錄中找library。一般來講這只是一種臨時的解決方案,在沒有許可權或臨時需要的時候使用。
  4. ldconfig做的這些東西都與執行程式時有關,跟編譯時一點關係都沒有。編譯的時候還是該加-L就得加,不要混淆了。
  5. 總之,就是不管做了什麼關於library的變動後,最好都ldconfig一下,不然會出現一些意想不到的結果。不會花太多的時間,但是會省很多的事。
    再有,諸如libdb-4.3.so檔案頭中是會含有庫名相關的資訊的(即含“libdb-4.3.so”,可用strings命令察看),因此僅通過修改檔名以冒充某已被識別的庫(如libdb-4.8.so)是行不通的。為此可在編譯庫的Makefile中直接修改配置資訊,指定特別的庫名

/usr/bin/ld: skipping incompatible /home/xuli/monitor/lib/libpubfunc.so when searching for -lpubfunc
/usr/bin/ld: skipping incompatible /home/xuli/monitor/lib/libpubfunc.so when searching for -lpubfunc
/usr/bin/ld: cannot find -lpubfunc
/usr/bin/ld: skipping incompatible /home/xuli/monitor/lib/libsyddb.so when searching for -lsyddb
/usr/bin/ld: skipping incompatible /home/xuli/monitor/lib/libsyddb.so when searching for -lsyddb
/usr/bin/ld: cannot find -lsyddb

解決方案:此處兩個庫是自己編譯的,但還是不相容,則很可能是自己定義的環境變數的問題,我這裡的問題時PLATFORM變數被定義成了Linux64,而從自己本地獲取的PLATFORM=Linux,所以兩者出現了不一致

在程式執行的時候出現
./monitor: error while loading shared libraries: libodbc.so.1: cannot open shared object file: No such file or directory

在root使用者下執行下面的操作
則需要修改/etc/ld.conf.d/local.conf檔案(CSDN)
之後執行ldconfig

在執行./monitor程式時報錯,在下載某庫的時候找不到的處理方式(這裡缺失的庫是自定義庫):

第一步確認缺失的庫:
[[email protected] bin]$ ldd monitor
linux-vdso.so.1 => (0x00007ffe90374000)
libpubfunc.so => not found
libsyddb.so => not found
libodbc.so.1 => not found

第二步查詢庫的位置:
[[email protected] bin]$ locate libodbc.so.1
/home/hztc/HZTC/support/unixODBC/Linux64/lib/libodbc.so.1
/home/hztc/HZTC_V1.0/support/unixODBC/Linux64/lib/libodbc.so.1
/home/hztc/HZTC_V1.11/support/unixODBC/Linux64/lib/libodbc.so.1
/home/hztc/monitor/support/unixODBC/Linux64/lib/libodbc.so.1

第三步進入root使用者去修改ldconfig配置檔案
[[email protected] bin]$ su root
Password:
[[email protected] bin]# vim /etc/ld.so.conf.d/local.conf
在local.conf檔案中新增庫的路徑:/home/hztc/monitor/support/unixODBC/Linux64/lib/

第四步:重新整理配置檔案,執行下面的命令
[[email protected] bin]# ldconfig

第五步:退出root使用者
[[email protected] monitor]# exit
exit
[[email protected] bin]$ ls

相關推薦

Linux編譯的時候由於連結出現各種問題

一 動態庫與機器位數不符合 報錯內容: /usr/bin/ld: skipping incompatible /usr/lib/libcrypto.so when searching for -lcrypto /usr/bin/ld: skipping i

linux下靜態連結存在,但是在連結過程會出現undefined reference的錯誤

如題,使用linux編譯程式時,需要靜態連結庫。 在連結過程也已指定靜態庫的路徑及庫名,且連結器能找到指定的庫,但會提示庫中被呼叫的函式undefined reference 這是需要檢查連結庫在連結命令中的位置,要保證依賴該庫的中間檔案或庫在它的前面。 即若一個程式需要l

解決Qt編譯動態連結could not find or load the Qt platform plugin "windows" in.問題

最近用Qt5做了一個專案的介面,在編譯成可執行檔案EXE之後,執行檔案,提示: This application failed to start because it could not find or load the Qt platfo rm plugin "windows" in "".

Linux學習筆記 三 linux下的連結以及實現

1、連結庫概述 Linux下得庫有動態與靜態兩種,動態通常用.so為字尾,靜態用.a為字尾。面對比一下兩者:     靜態連結庫:當要使用時,聯結器會找出程式所需的函式,然後將它們拷貝到執行檔案,由於這種拷貝是完整的,所以一旦連線成功,靜態程式庫也就不再需要了。

linux 把靜態連結.a連結到動態連結.so裡

個人分類: linux編譯連結         最近公司的專案中突然出現了這樣一個需求,我簡化再概括後如下:有兩大模組,其中一個模組a最終編譯出一個可執行檔案exec_a,另一個模組b編譯出一個動態連結庫lib_b.so被模組a的程式exec_a所連結。現在模組b中分出

Linux 中動態連結的版本號以及ldconfig

動態連結庫的三個名字 1. realname, 真正的名字,一般情況下如果你有版本,應該在後面加上lib[libraryname].so.[version] eg: libtest.so.1.0.0 2. soname, 在編譯動態庫的時候指定的名字,這個名字將會被新增到

linux 新增動態連結路徑

1 2 export LD_LIBRARY_PATH=你的庫的路徑:$LD_LIBRARY_PATH echo $LD_LIBRARY_PATH linux 預設回去/lib和/usr/lib目錄下查詢庫,可以通過ln建立軟連線 轉:

linux 下安裝 MySQL 經常出現各種問題終極解決方法 /var/run/mysqld/mysqld.sock /var/run/mysqld/mysqld.pid

以為 ubuntu 12.04 為例: 安裝 MySQL  5.5 ,方法如下: wget http://sourceforge.net/projects/mysql.mirror/files/MySQL%205.5.27/mysql-5.5.27-linux

g++ 編譯動態連結和靜態連結

現在我有hello1.cpp和hello2.cpp兩個檔案,現在我要生成動態連結庫libhello.so和靜態連結庫libhello.a。以下為步驟: 1.生成動態連結庫: g++ -m32 hello1.cpp hello2.cpp -fPIC -shared -o ..

C++ jsoncpp編譯連結的使用

1. Jsoncpp介紹   (1)JsonCpp主要包含三種類型的class:Value Reader Writer;     Json::Value 是jsoncpp 中最基本、最重要的類,用於表示各種型別的物件,jsoncpp 支援的物件型別可見 Json::Va

linux 編譯 依賴靜態的靜態問題

前言---------------------------------- 最近工作中遇到一個linux編譯問題,其實是小問題,但經驗不足,弄了2天,特做記錄。 背景--------------------------------- 這次是做一個新的專案,專案軟體編譯架構如

Linux下動態連結的建立和使用及C呼叫matlab動態問題

其實這個資料網路上已經很多了,但是還是有一些細節讓我搗鼓了很久,以及最近在做matlab mcc做成so檔案供給c++呼叫的時候的一些問題。 一、首先如何製作Linux下的so 檔案 【1】http://bbs.chinaunix.net/thread-1281954-1-

Linux下動態連結的建立和使用

1、連結庫的基本知識 庫是一種軟體元件技術,庫裡面封裝了資料和函式。它的使用,可以是程式模組化。在程式中使用,我們可以稱之為程式函式庫。 程式函式庫可分為3種類型:靜態函式庫(static libraries)、共享函式庫(shared lib

靜態連結編譯與使用 linux下的動態連結和靜態連結到底是個什麼鬼?(一)靜態連結編譯與使用

linux下的動態連結庫和靜態連結庫到底是個什麼鬼?(一)靜態連結庫的編譯與使用       知識不等於技術,這句話真的是越工作的時間長越深有體會,學習到的知識只有不斷的實踐,才成真正在自已的心裡紮下根,成為自身的一部分,所以無論如何,我希望我的部落格可以

在x64位Linux上生成動態連結必須使用編譯選項-fPIC的問題

在 Linux 下製作動態連結庫,“標準” 的做法是編譯成位置無關程式碼(Position Independent Code,PIC),然後連結成一個動態連結庫。經常遇到的一個問題是 -fPIC 是不是必需,因為好像不加經常也能正常執行,只是建立 .so 的時候

Linux編譯連結

簡要記錄linux下編譯靜態庫和動態庫的方法, 1.靜態庫(*.a) 編譯:cc -Wall -c ctest1.c ctest2.c 建立靜態庫:ar -cvq libctest.a ctest.o ctest2.o 顯示靜態庫中的檔案列表(建立符號表):ar -t li

linux下gcc編譯 .c檔案生成動態連結 .so檔案,並測試呼叫該連結

簡單介紹:linux中so檔案為共享庫,和windows下dll相似;so可以共多個程序呼叫,不同程序呼叫同一個so檔案,所使用so檔案不同;so原檔案不需要main函式;例項,1.通過mysqlTest.c中的函式mysql(),生成一個libmysql.so連結庫#inc

linux下g++ 編譯時動態和靜態連結和標頭檔案問題

原來編譯的時候都是用的很隨意,沒用系統的總結一下,這幾天在編譯的時候遇到一些下問題,於是就總結一下,省得過幾天又給忘了。 1.動態庫和靜態庫簡介 靜態庫在程式連結的時候會自動的連結到程式裡,所以一旦編譯完成,靜態庫就不需要了,靜態庫以.a結尾。  動態庫在編譯時不會被連線到目的碼中,而是在程式執行

使用CMake編譯出現動態連結錯誤no version information available的解決方案

出現問題 在使用cmake編譯時出現如下錯誤: /usr/local/bin/cmake: /home/0123/anaconda2/lib/libssl.so.1.0.0: no version information available (require

Linux下gcc編譯生成動態連結*.so檔案並呼叫它

動態庫*.so在linux下用c和c++程式設計時經常會碰到,最近在網站找了幾篇文章介紹動態庫的編譯和連結,總算搞懂了這個之前一直不太瞭解得東東,這裡做個筆記,也為其它正為動態庫連結庫而苦惱的兄弟們提供一點幫助。1、動態庫的編譯下面通過一個例子來介紹如何生成一個動態庫。這裡