GCC編譯錯誤
1./usr/bin/ld:/tmp/ccd/UkmoA.o :undefined reference to symbol ‘ERR_free_strings@OPENSSL_1.0.0’
//lib/i386-linux-gnu/libcrypto.so.1.0.0:error adding symbols:DSO missing from command line
error1:
解決方法:
makefile 文件中加入 –lcrypto (放在-lssl之后)
指定程序的動態鏈接庫libcrypto.so.1.0.0
2./usr/lib/ld :can’t find -lmysqlclient
error2:
解決方法:
因為動態庫文件mysqlclient沒在默認路徑下(/usr/lib /lib /usr/local/lib).
所以需要指明動態鏈接庫的路徑 :-L/usr/lib/mysql/ -lmysqlclient
3.error while loading shared libraries:libmysqlclient.so.18:can’t open shared object file :no such file or directory
error3:
解決方法:
1. 編輯/etc/ld.so.conf文件,加入 libmysqlclient.so.18所在在的路徑:/usr/lib/mysql
2. 然后執行命令:
$ ldconfig
ldconfig 命令的用途主要是在默認目錄 (/usr/lib、/lib)以及動態庫配置文件/etc/ld.so.conf所列目錄下搜索出可共享的動態鏈接庫(libxxxx.so*),進而創建出動態裝入程序(ld.so)。所需的連接和緩存文件。緩存文件默認是/etc/ld.so.cache,此文件保存以排好序的動態鏈接庫名字列表。
GCC編譯基本過程
預處理->編譯->連接->加載
- 預處理:#開頭
- 編譯:程序構建過程, 生成.o文件,gcc 依賴順序問題(從后向前),如果文件a依賴於文件b,那么編譯的時候必須把a放前面,b放后面。
- 連接:將所有的對象文件和庫串聯起來,成為可運行程序。靜態庫已經植入程序,共享庫在程序中包含其引用。
- 加載:程序啟動,引用共享庫,GCC編譯器假定所有的共享庫以lib開頭,以.so或者.a結尾。
GCC動態庫與共享庫
-
什么是動態庫與共享庫?
每個人的代碼不可能從0寫起,需要調用各種庫函數,靜態庫編譯時加載,動態庫運行時加載。
靜態庫的格式:libxxxx.a
動態庫的格式:libxxxx.so.major.minor xxxx為該lib的名稱 major主版本號 minor副版本號 -
如何知道一個可執行程序依賴哪些庫
解釋:
可執行程序ln依賴於libc庫和ld-linux庫 - 如何定位共享庫文件
a. -l(小寫的l)
用於指定程序要鏈接的庫,-l后面緊接着(沒有空格)就是庫名xxxx(去掉lib和.so)
Ps:放在默認路徑(/lib ,/usr/lib , /usr/local/lib)的庫直接用-i參數就能鏈接,只需編譯時加上 –lxxxx 就能使用libxxxx.so,程序中include libxxxx.so對應的頭文件,就可以調用該庫的函數。
b. -L(大寫的L)
但是libxxxx.so沒有放在默認的三個路徑下時,就需要-L指定libxxxx.so的路徑,否則程序就會報錯(can’t find -lxxxx)。
假設libxxxx.so所在目錄為/aa/bb/cc,那么使用格式如下:-L/aa/bb/cc –lxxxx
ldconfig指令詳解
ldconfig 命令的用途主要是在默認目錄 (/usr/lib、/lib)以及動態庫配置文件/etc/ld.so.conf所列目錄下搜索出可共享的動態鏈接庫(libxxxx.so*),進而創建出動態裝入程序(ld.so)。所需的連接和緩存文件。緩存文件默認是/etc/ld.so.cache,此文件保存以排好序的動態鏈接庫名字列表。
程序連接(運行)時首先在/etc/ld.so.cache查找共享庫,找不到的話然后再到/etc/ld.so.conf的路徑里面去查找。
linux啟動時會執行一次該命令,之后如果修改了/lib/或/usr/lib,安裝了新的動態鏈接庫時,一定要執行一次$ldconfig。
Ps:
- 往/lib和/usr/lib里面加東西,是不用修改/etc/ld.so.conf的,但是完了之后要調一下ldconfig
- 默認目錄以外添加動態鏈接庫,一定要修改/etc/ld.so.conf,然后再調用ldconfig
- 比如之前安裝mysql-connector-c-6.1.11-linux-glibc2.12-i686,將其lib文件夾中的mysqlclient動態鏈接庫拷貝到/usr/lib/mysql文件夾下,這時就需要在/etc/ld.so.conf下面加一行/usr/lib/mysql/,保存過后ldconfig一下,新的library才能在程序運行時被找到。
- 如果想在這兩個目錄以外放lib,但是又不想在/etc/ld.so.conf中加東西(或者是沒有權限加東西)。那也可以,就是export一個全局變量LD_LIBRARY_PATH,然后運行程序的時候就會去這個目錄中找library。一般來講這只是一種臨時的解決方案,在沒有權限或臨時需要的時候使用。
- ldconfig做的這些東西都與運行程序時有關,跟編譯時一點關系都沒有。編譯的時候還是該加-L就得加,不要混淆了。
- 總之,就是不管做了什么關於library的變動后,最好都ldconfig一下,不然會出現一些意想不到的結果。不會花太多的時間,但是會省很多的事。
轉自:https://blog.csdn.net/u013693367/article/details/78929985