makefile 語法 /usr/bin/ld: cannot find -lxxxx


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM