現在我們知道了動態與靜態函數庫,也知道了當前的Linux大多是將函數庫做成動態函數庫,下面來討論增加函數庫讀取效能的方法。我們知道,記憶體的訪問速度是硬碟的好幾倍,所以,如果將常用的動態函數庫載入到記憶體中(快取,cache),當軟體套件要採用動態函數庫時,就不需要重新從硬碟裡讀出,這樣就可以提高動態函數庫的讀取速度。這個時候需要ldconfig與 /etc/ld.so.conf的協助。
將動態函數庫載入到快取(cache)中的過程如下:
1. 首先,要在 /etc/ld.so.conf中寫下“想要讀入快取中的動態函數庫所在的目錄”,注意,是目錄而不是檔案。
2. 利用ldconfig執行檔案將 /etc/ld.so.conf的資料讀入快取中。
3. 同時在 /etc/ld.so.cache檔案中記錄資料。
事實上,ldconfig還可以用來判斷動態函數庫的串連資訊。趕緊使用Fedora Core 4來測試吧。假設要將MySQL函數庫加入到快取中:
[root@linux ~]# ldconfig [-f conf] [ -C cache] [-p]
參數:
-f conf : conf指的是某個檔案名稱,也就是說,使用conf作為libarary
函數庫的取得路徑,而不以 /etc/ld.so.conf為預設值
-C cache : cache指的是某個檔案名稱,也就是說,使用cache作為快取暫存
函數庫資訊,而不以 /etc/ld.so.cache為預設值
-p : 列出當前所擁有的所有函數庫資料內容(在 /etc/ld.so.cache中的資料)。
範例:
範例一:假設MySQL資料庫函數庫在 /usr/lib/mysql中,如何讀入快取?
[root@linux ~]# vi /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/lib/mysql <==這一行是新增的。
[root@linux ~]# ldconfig
# 畫面上不會顯示任何資訊,正常。
[root@linux ~]# ldconfig -p
928 libs found in cache `/etc/ld.so.cache'
libz.so.1 (libc6) => /usr/lib/libz.so.1
libz.so (libc6) => /usr/lib/libz.so
......中間省略......
通過上面的操作,我們可以將MySQL的相關函數庫讀入快取中,這樣可以加快函數庫讀取的速度。有時您可能會自行加入某些Tarball安裝的動態函數庫,當您想讓這些動態函數庫的相關串連可以讀入到快取中時,可以將動態函數庫所在的目錄名稱寫入 /etc/ld.so.conf中,然後執行ldconfig。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
首先說下/etc/ld.so.conf:
這個檔案記錄了編譯時間使用的動態連結程式庫的路徑。
預設情況下,編譯器只會使用/lib和/usr/lib這兩個目錄下的庫檔案
如果你安裝了某些庫,比如在安裝gtk+-2.4.13時它會需要glib-2.0 >= 2.4.0,辛苦的安裝好glib後
沒有指定 --prefix=/usr 這樣glib庫就裝到了/usr/local下,而又沒有在/etc/ld.so.conf中添加/usr/local/lib
這個搜尋路徑,所以編譯gtk+-2.4.13就會出錯了
對於這種情況有兩種方法解決:
一:在編譯glib-2.4.x時,指定安裝到/usr下,這樣庫檔案就會放在/usr/lib中,gtk就不會找不到需要的庫檔案了
對於安裝庫檔案來說,這是個好辦法,這樣也不用設定PKG_CONFIG_PATH了 (稍後說明)
二:將/usr/local/lib加入到/etc/ld.so.conf中,這樣安裝gtk時就會去搜尋/usr/local/lib,同樣可以找到需要的庫
將/usr/local/lib加入到/etc/ld.so.conf也是必須的,這樣以後安裝東東到local下,就不會出現這樣的問題了。
將自己可能存放庫檔案的路徑都加入到/etc/ld.so.conf中是明智的選擇 ^_^
添加方法也極其簡單,將庫檔案的絕對路徑直接寫進去就OK了,一行一個。例如:
/usr/X11R6/lib
/usr/local/lib
/opt/lib
再來看看ldconfig是個什麼東東吧 :
它是一個程式,通常它位於/sbin下,是root使用者使用的東東。具體作用及用法可以man ldconfig查到
簡單的說,它的作用就是將/etc/ld.so.conf列出的路徑下的庫檔案 緩衝到/etc/ld.so.cache 以供使用
因此當安裝完一些庫檔案,(例如剛安裝好glib),或者修改ld.so.conf增加新的庫路徑後,需要運行一下/sbin/ldconfig
使所有的庫檔案都被緩衝到ld.so.cache中,如果沒做,即使庫檔案明明就在/usr/lib下的,也是不會被使用的,結果
編譯過程中抱錯,缺少xxx庫,去查看發現明明就在那放著,搞的想大罵computer蠢豬一個。 ^_^
我曾經編譯KDE時就犯過這個錯誤,(它需要每編譯好一個東東,都要運行一遍),所以
切記改動庫檔案後一定要運行一下ldconfig,在任何目錄下運行都可以。
再來說說 PKG_CONFIG_PATH這個變數吧:
經常在論壇上看到有人問"為什麼我已經安裝了glib-2.4.x,但是編譯gtk+-2.4.x 還是提示glib版本太低阿?
為什麼我安裝了glib-2.4.x,還是提示找不到阿?。。。。。。"都是這個變數搞的鬼。
先來看一個編譯過程中出現的錯誤 (編譯gtk+-2.4.13):
checking for pkg-config... /usr/bin/pkg-config
checking for glib-2.0 >= 2.4.0 atk >= 1.0.1 pango >= 1.4.0... Package glib-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `glib-2.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'glib-2.0' found
configure: error: Library requirements (glib-2.0 >= 2.4.0 atk >= 1.0.1 pango >= 1.4.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.
[root@NEWLFS gtk+-2.4.13]#
很明顯,上面這段說明,沒有找到glib-2.4.x,並且提示應該將glib-2.0.pc加入到PKG_CONFIG_PATH下。
究竟這個pkg-config PKG_CONFIG_PATH glib-2.0.pc 是做什麼的呢? let me tell you ^_^
先說說它是哪冒出來的,當安裝了pkgconfig-x.x.x這個包後,就多出了pkg-config,它就是需要PKG_CONFIG_PATH的東東
pkgconfig-x.x.x又是做什麼的? 來看一段說明:
The pkgconfig package contains tools for passing the include path and/or library paths to build tools during the make file execution.
pkg-config is a function that returns meta information for the specified library.
The default setting for PKG_CONFIG_PATH is /usr/lib/pkgconfig because of the prefix we use to install pkgconfig. You may add to PKG_CONFIG_PATH by exporting additional paths on your system where pkgconfig files are installed. Note that PKG_CONFIG_PATH is only needed when compiling packages, not during run-time.
我想看過這段說明後,你已經大概瞭解了它是做什麼的吧。
其實pkg-config就是向configure程式提供系統資訊的程式,比如軟體的版本啦,庫的版本啦,庫的路徑啦,等等
這些資訊只是在編譯其間使用。你可以 ls /usr/lib/pkgconfig 下,會看到許多的*.pc,用文字編輯器開啟
會發現類似下面的資訊:
prefix=/usr
exec_prefix=$
libdir=$/lib
includedir=$/include
glib_genmarshal=glib-genmarshal
gobject_query=gobject-query
glib_mkenums=glib-mkenums
Name: GLib
Description: C Utility Library
Version: 2.4.7
Libs: -L$ -lglib-2.0
Cflags: -I$/glib-2.0 -I$/glib-2.0/include
明白了吧,configure就是靠這些資訊判斷你的軟體版本是否符合要求。並且得到這些東東所在的位置,要不去哪裡找呀。
不用我說你也知道為什麼會出現上面那些問題了吧。
解決的辦法很簡單,設定正確的PKG_CONFIG_PATH,假如將glib-2.x.x裝到了/usr/local/下,那麼glib-2.0.pc就會在
/usr/local/lib/pkgconfig下,將這個路徑添加到PKG_CONFIG_PATH下就可以啦。並且確保configure找到的是正確的
glib-2.0.pc,就是將其他的lib/pkgconfig目錄glib-2.0.pc幹掉就是啦。(如果有的話 ^-^)
設定好後可以加入到~/.bashrc中,例如:
PKG_CONFIG_PATH=/opt/kde-3.3.0/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/pkgconfig:
/usr/X11R6/lib/pkgconfig
[root@NEWLFS ~]#echo $PKG_CONFIG_PATH
/opt/kde-3.3.0/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/pkgconfig:/usr/X11R6/lib/pkgconfig
從上面可以看出,安裝庫檔案時,指定安裝到/usr,是很有好處的,無論是/etc/ld.so.conf還是PKG_CONFIG_PATH
預設都會去搜尋/usr/lib的,可以省下許多麻煩,不過從源碼包管理上來說,都裝在/usr下
管理是個問題,不如裝在/usr/local下方便管理
其實只要設定好ld.so.conf,PKG_CONFIG_PATH路徑後,就OK啦 ^_^
附:ldconfig man(8)
Name
/sbin/ldconfig - configure dynamic linker run time bindings
Synopsis
/sbin/ldconfig [ -nNvXV ] [ -f conf ] [ -C cache ] [ -r root ] directory ...
/sbin/ldconfig -l [ -v ] library ...
/sbin/ldconfig -p
Description
ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/lib and /usr/lib). The cache is used by the run-time linker, ld.so or ld-linux.so. ldconfig checks the header and filenames of the libraries it encounters when determining which versions should have their links updated.
ldconfig will attempt to deduce the type of ELF libs (ie. libc5 or libc6/glibc) based on what C libs, if any, the library was linked against. Therefore, when making dynamic libraries, it is wise to explicitly link against libc (use -lc).
Some existing libs do not contain enough information to allow the deduction of their type. Therefore, the /etc/ld.so.conf file format allows the specification of an expected type. This is only used for those ELF libs which we can not work out. The format is "dirname=TYPE", where TYPE can be libc4, libc5, or libc6. (This syntax also works on the command line.) Spaces are not allowed. Also see the -p option. ldconfig should normally be run by the superuser as it may require write permission on some root owned directories and files.
Options
-v
Verbose mode. Print current version number, the name of each directory as it is scanned, and any links that are created. Overrides quiet mode.
-n
Only process directories specified on the command line. Don't process the trusted directories (/lib and /usr/lib) nor those specified in /etc/ld.so.conf. Implies -N.
-N
Don't rebuild the cache. Unless -X is also specified, links are still updated.
-X
Don't update links. Unless -N is also specified, the cache is still rebuilt.
-f conf
Use conf instead of /etc/ld.so.conf.
-C cache
Use cache instead of /etc/ld.so.cache.
-r root
Change to and use root as the root directory.
-l
Library mode. Manually link individual libraries. Intended for use by experts only.
-p
Print the lists of directories and candidate libraries stored in the current cache.
Files
/lib/ld.so
run-time linker/loader
/etc/ld.so.conf
File containing a list of colon, space, tab, newline, or comma-separated directories in which to search for libraries.
/etc/ld.so.cache