Linux編譯鏈接環境變量

Linux編譯鏈接環境變量

靜態庫鏈接時搜索路徑順序:

1.ld會去找GCC命令中的參數-L

2.再找gcc的環境變量LIBRARY_PATH

3.再找內定目錄 /lib /usr/lib /usr/local/lib 這是當初compile gcc時寫在程序內的

動態鏈接時、執行時搜索路徑順序:

1.編譯目標代碼時指定的動態庫搜索路徑;

2.環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑;

3.配置文件/etc/ld.so.conf中指定的動態庫搜索路徑;

4.默認的動態庫搜索路徑/lib;

5.默認的動態庫搜索路徑/usr/lib。

有關環境變量:

LIBRARY_PATH環境變量:指定程序靜態鏈接庫文件搜索路徑
LD_LIBRARY_PATH環境變量:指定程序動態鏈接庫文件搜索路徑
鏈接過程
 建立靜態庫方法(包括靜態內部庫和動態外部庫)
gcc -c fun.c
ar cqs libfun.a fun.o
 編譯中使用靜態庫方法
gcc call.c -static -L. -lfun -o fun_static_call
 建立動態庫(包括動態內部庫和動態外部庫)
gcc fun.c -fPIC -shared -o libfun.so
 編譯中使用動態庫方法
gcc call.c -L. -lfun -o fun_dyn_call
編譯器會先在path文件夾下搜索libxxx.so文件,
如果沒有找到,繼續搜索libxxx.a(靜態庫)。

 

執行過程

無論是使用動態庫還是外部庫鏈接時都是使用的ld連接器;

使用動態庫的程序執行時使用動態加載器。在Linux 下,加載器是/lib/ld-Linux.so.X(X是版本號)。然後加載器搜索、加載程序所要使用的動態鏈接庫。搜索順序見上。

 

******************************

八   環境變量
8.1   查看環境變量
$ env        顯示所有的環境變量設置
$ echo $ENV_VARIABLE   顯示指定環境變量的設置
例:
$ echo $PATH
/bin:/etc:/usr/bin:/tcb/bin

8.2   設定環境變量
$ ENV_VARIABLE=XXX;export ENV_VARIABLE
例:
$ PATH=$PATH:$INFORMIXDIR/bin;export PATH  將環境變量PATH設定爲原PATH值+$INFORMIXDIR/bin

8.3   取消環境變量設置
$ unset $ENV_VARIABLE
例:
$ set GZJ=gzj;export GZJ    設置環境變量GZJ
$ echo $GZJ
gzj         顯示環境變量值
$ unset $GZJ      取消環境變量GZJ的設置
$ echo $GZJ
         已取消




一   makefile規則
makefile是一個make的規則描述腳本文件,包括四種類型行:目標行、命令行、宏定義行和make僞指令行(如“include”)。makefile文件中註釋以“#”開頭。當一行寫不下時,可以用續行符“\”轉入下一行。
1.1   目標行
目標行告訴make建立什麼。它由一個目標名錶後面跟冒號“:”,再跟一個依賴性表組成。
例:
example: depfile deptarget
該目標行指出目標example與depfile和deptarget有依賴關係,如果depfile或deptarget有修改,則重新生成目標。
example1 example2 example3: deptarget1 deptarget2 depfile
該目標行指出目標名錶中的example1、example2、example3這三個各自獨立的目標是用相同的依賴列表和規則生成的。
clean:
空的依賴列表說明目標clean沒有其他依賴關係。

目標行後續的以Tab 開始的行是指出目標的生成規則,該Tab字符不能以空格代替。例如:
example.o:example.c example.h
cc –c example.c
該例子指出目標example.o依賴於example.c和example.h。如果example.c或example.h其中之一改變了,就需要執行命令cc –c example.c重新生成目標example.o。
可以用文件名模式匹配來自動爲目標生成依賴表,如:
prog: *.c

以下是一個簡單的makefile的例子:

圖 1 最簡單的makefile例
make使用makefile文件時,從第一個目標開始掃描。上例中的第一個目標爲all,所以目標clean不會自動被執行,可以通過命令make clean來生成目標。

1.2   命令行
命令行用來定義生成目標的動作。
在目標行中分號“;”後面的文件都認爲是一個命令,或者一行以Tab製表符開始的也是命令。
如在上面的makefile例中,第三行以Tab字符開始的cc命令即是一個命令行,說明要生成hello應執行的命令。也可以寫成:hello:hello.o;cc –c hello –L…
一般情況下,命令行的命令會在標準輸出中回顯出來,如對上面的makefile執行make時,標準輸出如下:
        cc -c hello.c
        cc -o hello -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello.o
        cc -c hello1.c
        cc -o hello1 -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello1.o
如果不希望命令本身回顯,可在命令前加@字符,如在上例中不希望回顯cc –c hello.c和cc –c hello1.c,可修改makefile文件如下:



圖 2 抑制回顯的makefile例
對該makefile文件執行make時,標準輸出如下:
        cc -o hello -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello.o
        cc -o hello1 -L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11 hello1.o
可以看出,命令行前有@字符的不回顯。

1.3   宏定義行
在makefile中,可以使用宏定義減少用戶的輸入,例如上例中對hello和hello1的編譯選項均爲“-L/usr/X11R6/lib -L/usr/lib -lXm -lXt -lX11”,此時可以用宏來代替,如:
圖 3 使用宏定義的makefile例
宏定義的基本語法是:
name=value
在定義宏時,次序不重要。宏不需要在使用前定義。如果一個宏定義多次,則使用最後一次的定義值。
可以使用“$”字符和“()”或“{}”來引用宏,例如:
cc –o hello.o $(CCFLAGS) hello.o
也可以將一個宏賦值給另一個宏,但這樣的定義不能循環嵌套,如:
A=value1
B=value2
C=$(A) $(B)等價於C=value1 value2

1.4   僞指令
makefile大部分由宏定義行、命令行和目標行組成。第四種類型是make僞指令行。make僞指令沒有標準化,不同的make可能支持不同的僞指令集,使得makefile有一定的不兼容性。如果要考慮移植性問題,則要避免使用make僞指令。但有一些僞指令,如include,由於使用比較多,很多不同make都提供該僞指令。
1.4.1   僞指令include
該僞指令類似C語言中的#include,它允許一次編寫常用的定義幷包括它。include僞指令必須在一行中,第一個元素必須是include,並且跟一個要包含的文件名,如:
include default.mk

1.4.2   僞指令“#”
“#”字符也是make的僞指令,它指出“#”後面的文件是註釋,如:
PROGNAME=test  # define macro
#don't modify this

二   後綴規則
2.1   雙後綴規則
在前面的makefile例中有許多重複內容,例如,生成hello和hello1的命令類似,生成hello.o和hello1.o的命令也類似,除了編譯或鏈接的文件不一樣外,其它均相同,這時,我們就可以使用後綴規則。首先看一個雙後綴的例子:
圖 4 使用雙後綴規則的makefile例
後綴規則使用特殊的目標名“.SUFFIXES”。
第一行中.SUFFIXES的依賴表爲空,用來清除原有的後綴規則,因爲.SUFFIXES可以在makefile中多次使用,每一次都將新的後綴規則加入以前的後綴規則中。
第二行中指定後綴規則爲“.c .o”,即表示將所有的.c文件轉換爲.o文件。
第三行指定將.c文件轉換成.o文件的方法。$(CC)爲make的預定義宏,其默認值爲cc,$<爲特殊的宏,代替當前的源文件,即所有要編譯的.c文件。
第六行指定目標hello和hello1的生成方法。$@爲特殊的宏,代替當前的目標名,即hello和hello1,[email protected]即爲hello.o和hello1.o。

上例介紹的是雙後綴規則,即它包含兩個後綴,如.c.o,用來把一個C源文件編譯爲目標文件。雙後綴規則描述如何由第一個後綴類型的文件生成第二個後綴類型的文件,例如:.c.o規則描述如何由.c文件生成.o文件。

2.2   單後綴規則
單後綴規則描述了怎樣由指定後綴的文件生成由它基名爲名字的文件。例如使用單後綴規則.c,可以由hello.c和hello1.c生成hello和hello1文件。例如將前面的makefile改爲:
圖 5 使用單後綴規則的makefile例
由於.c後綴規則爲make標準後綴規則,make爲其指定了相應的命令行,所以在makefile中可以不用再指定其目標生成的具體命令行。

下表是make提供的標準後綴規則。
表 1 make標準後綴規則
後綴規則 命令行
.c $(LINK.c) –o $@ $< $(LDLIBS)
.c.ln $(LINK.c) $(POUTPUT OPTPUT OPTION) –i $<
.c.o $(COMPILE.c) $(OUTPUT OPTION) $<
.c.a $(COMPILE.c) –o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%

三   特殊目標
在後綴規則中使用了特殊目標.SUFFIXES,用來指定新增的後綴規則。make還提供了幾個特殊目標來設置make的行爲,下面爲一些特殊的目標:
 .IGNORE
make在執行命令行時,如果返回的是錯誤碼,make的缺省動作是停止並退出。增加該目標後,make將忽略命令行返回的錯誤碼,並繼續執行後續的操作。

 .SILENT
前面已經介紹過,make在執行命令行時會回顯命令行內容,在命令行前增加“@”字符將抑制該命令行的回顯。
如果增加該目標,所有的命令行不再回顯,相當於在每個命令行前均增加了“@”字符。

 .PRECIOUS
當收到一個信號或從shell命令返回非零的錯誤碼時,make刪除它所有已建立的文件。但有些文件即使出了錯誤,用戶也不想讓make刪除,這些文件可以作爲.PRECIOUS目標的參數。它可以在一個makefile中出現多次,每一次都累積文件列表。

 .SUFFIXES
它爲makefile指定新的後綴規則,新的後綴規則作爲.SUFFIXES的依賴表給出。.SUFFIXES可以在一個makefile中多次使用,每一次都將新的後綴規則加入以前的後綴規則中,如果.SUFFIXES的依賴表爲空,則設置後綴規則表爲空。

四   特殊的宏
爲簡單使用規則,make提供了幾個特殊的宏:
 $@
整個當前目標名的值可以由宏“$@”來代替。

 $<
當前的源文件由“$<”來代替。例如,在前面的例子中用到了$(CC) –c $<,其中的“$<”是所有要編譯的.c文件。宏“$<”僅在後綴規則或.DEFAULT中有效。

 $*
當前目標的基名由宏“$*”來代替。例如目標的名字是hello.o,則基名就是除去了後綴.o的hello。

以上介紹的特殊宏使用了make自身的規則,用戶不可以改變。下表介紹了C中預定義的宏。
用途 宏 默認值
庫文檔彙編命令 AR ar
ARFLAGS rv
AS as
ASFLAGS 
COMPILE.s $(AS) $(ASFLAGS) $(TARGET ARCH)
C編譯器命令 CC cc
CFLAGS 
CPPFLAGS 
COMPILE.c $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET ARCH) –c
LINK.c $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET ARCH)
鏈接編輯器命令 LD ld
LDFLAGS 
rm命令 RM rm
後綴列表 SUFFIXES .o .c .c~ .s .s~ .S .S~ .ln .f .f~ .F .F~ .l .mod .mod~ .sym
.def .def~ .p .p~ .r .r~ .y .y~ .h .h~ .sh .sh~ .cps .cps~

五   makefile的應用
當調用make時,它在當前目錄下搜索文件名是“makefile”或“Makefile”的文件,並執行。
如果不想使用上述缺省文件,可以使用命令行中的“-f”來指定文件,如將編寫的makefile命名爲mklib,則指定爲“make –f mklib”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章