1 「」中的頭文件,在源文件當前目錄查找linux
2 -I 中指定目錄 -I能夠在CFLAG中指定正則表達式
3 gcc的環境變量 C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJC_INCLUDE_PATH函數
4 編譯器預設路徑、內定目錄:編碼
/usr/includespa
/usr/local/include遞歸
/usr/lib/gcc-lib/i386-linux/2.95.2/include進程
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g -3ip
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include編譯器
可是假如裝gcc的時候,有給定的prefix的話,那麼就是it
/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
一、 -rpath指定目錄(在編譯目標代碼時指定程序的動態庫搜索路徑"-Wl,-rpath,"指定)
二、 經過環境變量LD_LIBRARY_PATH指定動態庫搜索路徑(當經過該環境變量指定多個動態庫搜索路徑時,路徑之間用冒號":"分隔)
三、 /etc/ld.so.cache中指定的動態庫搜索路徑, 由ldconfig讀取配置文件/etc/ld.so.conf 生成。
四、 默認的動態庫搜索路徑/lib
五、 默認的動態庫搜索路徑/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:它的含義是使得庫中的解析的定義變量在隨後的隨後其它的連接庫中變得可使用。