一、 頭文件
1 “”中的頭文件,在源文件當前目錄查找
2 -I 中指定目錄 -I可以在CFLAG中指定
3 gcc的環境變量 C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJC_INCLUDE_PATH
4 編譯器預設路徑、內定目錄:
/usr/include
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g -3
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include
但是假如裝gcc的時候,有給定的prefix的話,那么就是
/usr/include
prefix/include
prefix/xxx-xxx-xxx-gnulibc/include
prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include
此外還可用pkg-config 程序,用來在編譯腳本中向編譯器傳遞頭文件包含路徑或庫文件路徑。 Linux下那么多庫,在./configure時時怎么判斷它們存不存在的,難道是靠遞歸搜索?pkg-config這個命令和/*/lib/pkgconfig下的一些.pc文件才是主角。每個.pc文件定義了庫的名字、路徑、編譯選項等,比如glib-2.0.pc文件:
prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib
includedir=${prefix}/include
glib_genmarshal=glib-genmarshal
gobject_query=gobject-query
glib_mkenums=glib-mkenums
Name: Glib
Description: C Utilitiy Library
Version: 2.14.4
Libs: -L${libdir} -lglib-2.0
Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include
--cflags 參數可以給出在編譯時所需要的選項,而 --libs 參數可以給出連接時的選項
configure到某個庫的時候,pkg-config命令會首先去環境變量PKG_CONFIG_PATH定義好的路徑下搜索庫名字對應的.pc文件(庫名加.pc),找到了就行了,等會兒make的時候就可以通過正則表達式取出libs和cflags的值來使用。
如configure文件中有:
pkg_XLIB_CFLAGS='$PKG_CONFIG --cflags "x11" 2>/dev/null'(還是`***`)(結果是-I的形式)
(x11表示libx11庫),這些參數配置結束后寫入Makefile。
配置 pkgconfig
PKG_CONFIG_PATH 的缺省設置是 /lib/pkgconfig, /usr/lib/pkgconfig 和 /usr/local/lib/pkgconfig. 這些設置都是硬編碼的,所以不用另外設置它們。
二、 庫文件
? 編譯的時候動態庫的搜索路徑:
1 gcc會去找-L 指定的路徑和 -l指定的庫(指定庫的路徑)
2 由'-rpath-link'選項指定的搜索路徑 在LDFLAGS中gcc 的參數"-Wl,-rpath-link,-Wl"指定。 '-rpath-link'比‘-L’多一功能,指定的目錄還可用于搜索依賴庫。
3 由'-rpath'指定的搜索路徑. '-rpath'跟'-rpath_link'的不同之處在于,由'-rpath'指定的路徑被包含在可執行文件中,并在運行時使用, 而'-rpath-link'選項僅僅在連接時起作用.'-rpath'比'-rpath-link'多一功能,指定路徑編譯進程序,當程序運行時,首先從這些目錄中尋找庫。
4 再找內定目錄 /lib、 /usr/lib、 /usr/local/lib 這是當初compile gcc時寫在程序內的
'-rpath'跟'-rpath_link'用來指定依賴庫的路徑
? 對于交叉編譯,鏈接時庫搜索路徑及優先順序如下:
1 -rpath-link 指定
2 -rpath 指定
3 –L 指定
4 連接器的默認鏈接目錄,通常在交叉編譯器目錄下。
? 如何指定-rpath-link :在configure之前設置LDFLAGS,如
export LDFLAGS = " -Wl,-rpath-link -Wl,目錄/lib"(-Wl表示用于連接器)
在configure文件中也有:
pkg_XLIB_CFLAGS='$PKG_CONFIG --libs "x11" 2>/dev/null'(還是`***`)
? 運行時動態庫的搜索路徑
1?進程啟動時加載
首先 ?LD_PRELOAD
1、 -rpath指定目錄(在編譯目標代碼時指定程序的動態庫搜索路徑"-Wl,-rpath,"指定)
2、 通過環境變量LD_LIBRARY_PATH指定動態庫搜索路徑(當通過該環境變量指定多個動態庫搜索路徑時,路徑之間用冒號":"分隔)
3、 /etc/ld.so.cache中指定的動態庫搜索路徑, 由ldconfig讀取配置文件/etc/ld.so.conf 生成。
4、 默認的動態庫搜索路徑/lib
5、 默認的動態庫搜索路徑/usr/lib
2? 運行時加載 dlopen()
第一個參數:指定共享庫的名稱,將會在下面位置查找指定的共享庫。
-/開頭,絕對路徑,名字必須完全匹配。
-環境變量LD_LIBRARY_PATH列出的用分號間隔的所有目錄。
-文件/etc/ld.so.cache中找到的庫的列表,用ldconfig維護。
-目錄usr/lib。
-目錄/lib。
-當前目錄。
第二個參數:指定如何打開共享庫。
其中flag有:RTLD_LAZY RTLD_NOW RTLD_GLOBAL,其含義分別為:
RTLD_LAZY:在dlopen返回前,對于動態庫中存在的未定義的變量(如外部變量extern,也可以是函數)不執行解析,就是不解析這個變量的地址。
RTLD_NOW:與上面不同,他需要在dlopen返回前,解析出每個未定義變量的地址,如果解析不出來,在dlopen會返回NULL,錯誤為:
: undefined symbol: xxxx.......
RTLD_GLOBAL:它的含義是使得庫中的解析的定義變量在隨后的隨后其它的鏈接庫中變得可以使用。