1. 程式人生 > >執行時庫路徑指定

執行時庫路徑指定

這裡補充一點,動態庫(.so)是直接可以呼叫的,並不會被編譯程序序。只讀檔案系統,將其中一個目錄通過nfs方式mount到其它地方(比如PC機),將動態庫放於該目錄下,並將該目錄指定為庫的搜尋路徑(export LD_LIBRARY_PATH=),程式執行時會呼叫該目錄下的庫,而不是去呼叫存放在只讀檔案系統中的原有的庫(已親自實測),這樣在除錯某一個動態庫時只需要編譯替換該庫即可,大大縮減了除錯開發時間。

分類:

  1. 連線和執行時庫檔案搜尋路徑到設定

    庫檔案在連線(靜態庫和共享 庫)和執行(僅限於使用共享庫的程式)時被使用,其搜尋路徑是在系統中進行設定的。一般 Linux 系統把 /lib 和 /usr/lib 兩個目錄作為預設的庫搜尋路徑,所以使用這兩個目錄中的庫時不需要進行設定搜尋路徑即可直接使用。對於處於預設庫搜尋路徑之外的庫,需要將庫的位置新增到 庫的搜尋路徑之中。設定庫檔案的搜尋路徑有下列兩種方式,可任選其一使用:
    

    (1). 在 /etc/ld.so.conf 檔案中新增庫的搜尋路徑。(或者在/etc/ld.so.conf.d 下新建一個.conf檔案,將搜尋路徑一行一個加入-junziyang)

    將自己可能存放庫檔案的路徑都加入到/etc /ld.so.conf中是明智的選擇新增方法也極其簡單,將庫檔案的絕對路徑直接寫進去就OK了,一行一個。例如: 
    
        /usr/X11R6/lib
    
        /usr/local/lib
        /opt/lib
    
        需要注意的是:這種搜尋路徑的設定方式對於程式連線時的庫(包括共享庫和靜態庫)的定位已經足夠了,但是對於使用了共享庫的程式的執行還是不夠的。這是 因為為了加快程式執行時對共享庫的定位速度,避免使用搜索路徑查詢共享庫的低效率,所以是直接讀取庫列表檔案 /etc/ld.so.cache 從中進行搜尋的。/etc/ld.so.cache 是一個非文字的資料檔案,不能直接編輯,它是根據 /etc/ld.so.conf 中設定的搜尋路徑由 /sbin/ldconfig 命令將這些搜尋路徑下的共享庫檔案集中在一起而生成的(ldconfig 命令要以 root 許可權執行)。
    
        因此,為了保證程式執行時對庫的定位, 在 /etc/ld.so.conf 中進行了庫搜尋路徑的設定之後,還必須要執行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 檔案之後才可以。ldconfig ,簡單的說,它的作用就是將/etc/ld.so.conf列出的路徑下的庫檔案快取到/etc/ld.so.cache 以供使用。因此當安裝完一些庫檔案,(例如剛安裝好glib),或者修改ld.so.conf增加新的庫路徑後,需要執行一下 /sbin/ldconfig使所有的庫檔案都被快取到ld.so.cache中,如果沒做,即使庫檔案明明就在/usr/lib下的,也是不會被使用 的,結果編譯過程中抱錯,缺少xxx庫,去檢視發現明明就在那放著,搞的想大罵computer蠢豬一個。 
    
        在程式連線時,對於庫檔案(靜態庫和共享庫)的搜尋路徑,除了上面的設定方式之外,還可以通過 -L 引數顯式指定。因為用 -L 設定的路徑將被優先搜尋,所以在連線的時候通常都會以這種方式直接指定要連線的庫的路徑。
    
        這種設定方式需要 root 許可權,以改變 /etc/ld.so.conf 檔案並執行 /sbin/ldconfig 命令。而且,當系統重新啟動後,所有的基於 GTK2 的程式在執行時都將使用新安裝的 GTK+ 庫。不幸的是,由於 GTK+ 版本的改變,這有時會給應用程式帶來相容性的問題,造成某些程式執行不正常。為了避免出現上面的這些情況,在 GTK+ 及其依賴庫的安裝過程中對於庫的搜尋路徑的設定將採用另一種方式進行。這種設定方式不 需要 root 許可權,設定也簡單。
    

    (2). 在環境變數 LD_LIBRARY_PATH 中指明庫的搜尋路徑。

    設定方式:
    
        export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH 
    
    可以用下面的命令檢視 LD_LIBRAY_PATH 的設定內容:
    
        echo $LD_LIBRARY_PATH
    
    至此,庫的兩種設定就完成了。
    

2.交叉編譯時候如何配置連線庫的搜尋路 徑

    交叉編譯的時候不能使用本地(i686機器,即PC機器,研發機器)機器上的庫,但是在做編譯連結的時候預設的是使用本地庫,即/usr/lib, /lib兩個目錄。因此,在交叉編譯的時候,要採取一些方法使得在編譯連結的時候找到需要的庫。

    首先,要知道:編譯的時候只需要頭文件,真正實際的庫文件在連結的 時候用到。 (這是我的理解,假如有不對的地方,敬請網上各位大俠指教) 然後,講講如何在交叉編譯連結的時候找到需要的庫。

(1)交叉編譯時候直接使用-L和-I引數指定搜尋非標準的庫文件和頭文件的路徑。例如:

    arm-linux-gcc test.c -L/usr/local/arm/2.95.3/arm-linux/lib -I/usr/local/arm/2.95.3/arm-linux/include 

(2)使用ld.so.conf文件,將用到的庫所在文件目錄新增到此文件中,然後使用ldconfig命令重新整理快取。

(3)使用如下命令:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/2.95.3/arm-linux-lib

    參見《ld.so.conf 文件和PKG_CONFIG_PATH變數》這篇文章。

    通過環境變數LD_LIBRARY_PATH指定動態庫搜尋路徑(!)。

    通過設定環境變數LD_LIBRARY_PATH也可以指定動態庫搜尋路徑。當通過該環境變數指定多個動態庫搜尋路徑時,路徑之間用冒號":"分隔。

    不過LD_LIBRARY_PATH的設定作用是全域性的, 過多的使用可能會影響到其他應用程式的執行,所以多用在除錯。(LD_LIBRARY_PATH 的缺陷和使用準則,可以參考《Why LD_LIBRARY_PATH is bad》 )。通常情況下推薦還是使用gcc的-R或-rpath選項來在編譯時就指定庫的查詢路徑,並且該庫的路徑資訊儲存在可執行檔案中,執行時它會直接到該路 徑查詢庫,避免了使用LD_LIBRARY_PATH環境變數查詢。

(4)交叉編譯時使用軟體的configure引數。例如我編譯minigui-1.3.3,使用如下配置:

    #!/bin/bash

    rm -f config.cache config.status

    ./configure --build=i686-linux --host=arm-linux --target=arm-linux \

    CFLAGS=-I/usr/local/arm/2.95.3/arm-linux/include \

    LDFLAGS=-L/usr/local/arm/2.95.3/arm-linux/lib \

    --prefix=/usr/local/arm/2.95.3/arm-linux \

    --enable-lite \

    --disable-galqvfb \

    --disable-qvfbial \

    --disable-vbfsupport \

    --disable-ttfsupport \

    --disable-type1support \

    --disable-imegb2312py \

    --enable-extfullgif \

    --enable-extskin \

    --disable-videoqvfb \

    --disable-videoecoslcd

    這裡我配置了CFLAGS和LDFLAGS引數,這樣一來,我就不用去修改每個Makefile裡-L和-I引數了,也不用再去配置 LD_LIBRARY_PATH或改寫ld.so.conf文件了。

Linux下動態庫使用小結

  1. 靜態庫和動態庫的基本概念

    靜態庫,是在可執行程式連線時就已經加入到執行碼中,在物理上成為執行程式的一部分;使用靜態庫編譯的程式執行時無需該庫檔案支援,哪裡都可以用,但是生 成的可執行檔案較大。動態庫,是在可執行程式啟動時載入到執行程式中,可以被多個可執行程式共享使用。使用動態庫編譯生成的程式相對較小,但執行時需要庫 檔案支援,如果機器裡沒有這些庫檔案就不能執行。
    

2. 如何使用動態庫

    如何程式在連線時使用了共享庫,就必須在執行的時候能夠找到共享庫的位置。linux的可執行程式在執行的時候預設是先搜尋/lib和/usr/lib這兩個目錄,然後按照/etc/ld.so.conf裡面的配置搜尋絕對路徑。同時,Linux也提供了環境變數LD_LIBRARY_PATH供使用者選擇使用,使用者可以通過設定它來查詢除預設路徑之外的 其他路徑,如查詢/work/lib路徑,你可以在/etc/rc.d/rc.local或其他系統啟動後即可執行到的指令碼新增如 下語句:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH)。並且LD_LIBRARY_PATH路徑優先於系統預設路徑之前查詢(詳細參考《使 用 LD_LIBRARY_PATH》)。

    不過LD_LIBRARY_PATH的設定作用是全域性的,過多的使用可能會影響到其他應用程式的執行,所以多用在除錯。(LD_LIBRARY_PATH 的缺陷和使用準則,可以參考《Why LD_LIBRARY_PATH is bad》 )。通常情況下推薦還是使用gcc的-R或-rpath選項來在編譯時就指定庫的查詢路徑,並且該庫的路徑資訊儲存在可執行檔案中,執行時它會直接到該路 徑查詢庫,避免了使用LD_LIBRARY_PATH環境變數查詢。

3.庫的連結時路徑和執行時路徑
現代聯結器在處理動態庫時將連結時路徑(Link-time path)和執行時路徑(Run-time path)分開,使用者可以通過-L指定連線時庫的路徑,通過-R(或-rpath)指定程式執行時庫的路徑,大大提高了庫應用的靈活性。比如我們做嵌入式 移植時#arm-linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉編譯好的zlib庫),將target編譯好後我們只要把zlib庫拷貝到開發板的系統預設路徑下即可。或者通過- rpath(或-R )、LD_LIBRARY_PATH指定查詢路徑。

相關推薦

執行路徑指定

這裡補充一點,動態庫(.so)是直接可以呼叫的,並不會被編譯程序序。只讀檔案系統,將其中一個目錄通過nfs方式mount到其它地方(比如PC機),將動態庫放於該目錄下,並將該目錄指定為庫的搜尋路徑(export LD_LIBRARY_PATH=),程式執行時會呼

Linux動態載入失敗/設定執行搜尋路徑

程式執行時有以下錯誤 ./dom1: error while loading shared libraries: libmemcached.so.11: cannot open shared object file: No such file or direc

[轉]C和C++執行

轉自csdn原文:https://blog.csdn.net/ithzhang/article/details/20160009 圖片請去原文檢視 在使用VC構建專案時,經常會遇到下面的連結錯誤:   初學者面對這些錯誤常常不知所錯:libcmt.lib是什麼東西?msvcrtd.dll又是幹嗎用的?在

什麼是c執行

nafxcw.lib 和 libcmt.lib衝突問題。 解決辦法: 屬性設定裡讓程式先找到nafxcw.lib. 解決辦法參考:https://www.cnblogs.com/suiyingjie/archive/2012/10/29/2745031.html 從vs2008 工程

eclipse配置apache tomcat執行訪問路徑不需要專案名稱

問題:tomcat執行專案預設是要帶上專案名的,有時候不想要專案名來訪問,如何解決呢? 方法: 1:雙擊開啟tomcat 2:選擇Modules,選擇你要修改的專案 3:點選Edit,把path修改成空或者你自己想要的路徑即可! 轉載自

執行 MT\MD的區分和優劣

  VC專案屬性→配置屬性→C/C++→程式碼生成→執行時庫 可以採用的方式有:多執行緒(/MT)、多執行緒除錯(/MTd)、多執行緒DLL(/MD)、多執行緒除錯DLL(/MDd)、單執行緒(/ML)、單執行緒除錯(/MLd)。 Reusable Library&nb

qt程式執行路徑問題

程式執行時的路徑是該程式在被呼叫時的目錄 假如系統剛啟動時,是在/目錄處, 這時系統啟動指令碼/etc/rc.local呼叫/home/root/qt_broadcast_client/qt_broadcast_client程式 則目錄就是/目錄,qt_broadcast_client在呼叫s

Qt在pro中設定執行MT、MTd、MD、MDd,只適合VS版本的Qt

轉自:http://blog.csdn.net/caoshangpa/article/details/51416077 一.在pro中設定執行時庫 最近在用Qt5.6.0(VS2013版本)呼叫一份用Visual Studio 2013編譯的Debug版本靜態庫時出現如下錯誤:

VC 執行 /MD、/MDd 和 /MT、/MTd

有段時間在寫cuda程式是出現過 error LNK2005: _exit 已經在 MSVCRTD.lib(MSVCR71D.dll) 中定義 等類似錯誤 原因應該是在vs2010 工程屬性中 c/c++的程式碼生成(code generation)中的設定與cuda

判斷是否已經安裝vc2008執行

Visual C++ Redistributable(簡稱VC執行庫),現在的系統VC2005是必須安裝,QQ、遊戲、網路應用都離不開VC2005的支援,(也就是說VC不安裝這些都不能用),VC2008執行庫呢是可選的,現在或將來新遊戲都依賴VC2008程式碼呢沒什麼精闢之處

GCC編譯、連結、執行查詢順序(最真實可信)

參考了不少資料,其中最靠譜是這個:http://www.mingw.org/wiki/librarypathhowto和http://www.kaizou.org/2015/01/linux-libraries/經過線上實際驗證,GCC編譯、連結、執行時庫查詢順序如下,這個順

終於理解了什麼是c/c++執行,以及libcmt msvcrt等內容

在各個版本的編譯器中,我們可以通過配置選項來設定程式使用的C和C++執行時庫的型別。如下圖(其他版本編譯器大同小異):MT選項:連結LIB版的C和C++執行庫。在連結時就會在將C和C++執行時庫整合到程式中成為程式中的程式碼,程式體積會變大。 MTd選項:LIB的除錯版。 M

VS的執行(Runtime lIB)

在開發window程式是經常會遇到編譯好好的程式拿到另一臺機器上面無法執行的情況,這一般是由於另一臺機器上面沒有安裝響應的執行時庫導致的,那麼這個與編譯選項MT、MTd、MD、MDd有什麼關係呢?這是msdn上面的解釋: MT:mutithread,多執行緒庫

C執行(C Run-time Library)詳解

一、什麼是C執行時庫1)C執行時庫就是 C run-time library,是 C 而非 C++ 語言世界的概念:取這個名字就是因為你的 C 程式執行時需要這些庫中的函式.2)C 語言是所謂的“小核心”語言,就其語言本身來說很小(不多的關鍵字,程式流程控制,資料型別等);所以,C 語言核心開發出來之後,De

CRT(C Runtime Library)—— C/C++執行

C runtime library(part of the C standard library) 任何一個 C 程式,它的背後都有一套龐大的程式碼來進行支撐,使得該程式得以執行在更高級別上,而不必擔心同計算機底層操作的細節,這套程式碼至少包括:

執行MT、MTd、MD、MDd的研究

在開發window程式是經常會遇到編譯好好的程式拿到另一臺機器上面無法執行的情況,這一般是由於另一臺機器上面沒有安裝響應的執行時庫導致的,那麼這個與編譯選項MT、MTd、MD、MDd有什麼關係呢?這是msdn上面的解釋: MT:mutithread,多執行緒庫,編譯器會

【VS開發】MFC執行與debug、release版本之間的配置關係

參考內容:  前段時間從網上下來一個有意思的程式碼,用VS2010開啟時需要將工程轉換為2010的工程,轉化後卻出現了編譯不通過的問題,類似這樣的錯誤:c:\program files\microsoft visual studio 10.0\vc\atlmfc\inc

VS執行下載地址

Microsoft Visual C++ 2008 SP1 Redistributable Package (x86) 地址:http://www.microsoft.com/en-us/download/details.aspx?id=5582 Microsoft Vi

C/C++執行到底在Windows中起什麼作用(猜想)

以下是作者的一些猜想: 1. 我們在用VC程式設計時,會在執行我們的main函式前,系統先通過Kernel32呼叫一些函式,執行一些C的初始化準備工作,我們一般叫C執行時庫的初始化。那麼這些初始化的作用是什麼?是否是必要的?不知道大家有沒有思考過這個問題。 以下是我對這

vs2015部署---下一代VC執行系統:the Universal CRT

前言 其實the Universal CRT(通用C執行時庫)已經不能算是“下一代”,因為它已經在前兩年伴隨著Visual Studio 2015和Windows10釋出。但是由於之前使用VS2015開發的應用還較少,關注的人也少,相關的文章更少。所以筆者想幹脆用一篇文章,深入淺出的介紹一下Universa