Makefile學習筆記(2)-編譯選項CFLAGS,LDFLAGS,LIBS:-c,-D,-o,-g,-L,-I,-Wall,-mcpu等

原文鏈接:https://blog.csdn.net/xinyuan510214/article/details/50457433/

轉載:https://blog.csdn.net/xinyuan510214/article/details/50457433/

https://blog.csdn.net/cym_anhui/article/details/80639877


CFLAGS 表示用於 C 編譯器的選項,
CXXFLAGS 表示用於 C++ 編譯器的選項。
這兩個變量實際上涵蓋了編譯和彙編兩個步驟。

CFLAGS: 指定頭文件(.h文件)的路徑,如:CFLAGS=-I/usr/include -I/path/include。同樣地,安裝一個包時會在安裝路徑下建立一個include目錄,當安裝過程中出現問題時,試着把以前安裝的包的include目錄加入到該變量中來。

LDFLAGS:gcc 等編譯器會用到的一些優化參數,也可以在裏面指定庫文件的位置。用法:LDFLAGS=-L/usr/lib -L/path/to/your/lib。每安裝一個包都幾乎一定的會在安裝目錄裏建立一個lib目錄。如果明明安裝了某個包,而安裝另一個包時,它愣是說找不到,可以抒那個包的lib路徑加入的LDFALGS中試一下。

LIBS:告訴鏈接器要鏈接哪些庫文件,如LIBS = -lpthread -liconv

簡單地說,LDFLAGS是告訴鏈接器從哪裏尋找庫文件,而LIBS是告訴鏈接器要鏈接哪些庫文件。不過使用時鏈接階段這兩個參數都會加上,所以你即使將這兩個的值互換,也沒有問題。

有時候LDFLAGS指定-L雖然能讓鏈接器找到庫進行鏈接,但是運行時鏈接器卻找不到這個庫,如果要讓軟件運行時庫文件的路徑也得到擴展,那麼我們需要增加這兩個庫給"-Wl,R":

LDFLAGS = -L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib

如果在執行./configure以前設置環境變量export LDFLAGS="-L/var/xxx/lib -L/opt/mysql/lib -Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib" ,注意設置環境變量等號兩邊不可以有空格,而且要加上引號(shell的用法)。那麼執行configure以後,Makefile將會設置這個選項,鏈接時會有這個參數,編譯出來的可執行程序的庫文件搜索路徑就得到擴展了。

 gcc編譯器 CFLAGS 標誌參數說明

CFLAGS = -g -O2  -Wall -Werror -Wno-unused
 
編譯出現警告性錯誤unused-but-set-variable,變量定義但沒有使用,解決方法:
 增加CFLAGS 或CPPFLAGS參數如下:
  CPPFLAGS=" -Werror -Wno-unused-but-set-variable" || exit 1
 
                                      

      
 

· “-I dir”

正如上表中所述,“-I dir”選項可以在頭文件的搜索路徑列表中添加dir目錄。由於Linux中頭文件都默認放到了“/usr/include/”目錄下,因此,當用戶希望添加放置在其他位置的頭文件時,就可以通過“-I dir”選項來指定,這樣,Gcc就會到相應的位置查找對應的目錄。

比如在“/root/workplace/Gcc”下有兩個文件:

#include

int main()

{

     printf(“Hello!!\n”);

     return 0;

}

#include

這樣,就可在Gcc命令行中加入“-I”選項:

[root@localhost Gcc] Gcc hello1.c –I /root/workplace/Gcc/ -o hello1

這樣,Gcc就能夠執行出正確結果。

小知識

在include語句中,“<>”表示在標準路徑中搜索頭文件,““””表示在本目錄中搜索。故在上例中,可把hello1.c的“#include”改爲“#include “my.h””,就不需要加上“-I”選項了。

· “-L dir”

選項“-L dir”的功能與“-I dir”類似,能夠在庫文件的搜索路徑列表中添加dir目錄。例如有程序hello_sq.c需要用到目錄“/root/workplace/Gcc/lib”下的一個動態庫libsunq.so,則只需鍵入如下命令即可:

[root@localhost Gcc] Gcc hello_sq.c –L /root/workplace/Gcc/lib –lsunq –o hello_sq

需要注意的是,“-I dir”和“-L dir”都只是指定了路徑,而沒有指定文件,因此不能在路徑中包含文件名。

另外值得詳細解釋一下的是“-l”選項,它指示Gcc去連接庫文件libsunq.so。由於在Linux下的庫文件命名時有一個規定:必須以lib三個字母開頭。因此在用-l選項指定鏈接的庫文件名時可以省去lib三個字母。也就是說Gcc在對”-lsunq”進行處理時,會自動去鏈接名爲libsunq.so的文件。

(2)告警和出錯選項

Gcc的告警和出錯選項如表3.8所示。

下面結合實例對這幾個告警和出錯選項進行簡單的講解。

如有以下程序段:

#include

void main()

{

     long long tmp = 1;

     printf(“This is a bad code!\n”);

     return 0;

}

這是一個很糟糕的程序,讀者可以考慮一下有哪些問題?

· “-ansi”

該選項強制Gcc生成標準語法所要求的告警信息,儘管這還並不能保證所有沒有警告的程序都是符合ANSI C標準的。運行結果如下所示:

[root@localhost Gcc]# Gcc –ansi warning.c –o warning

warning.c: 在函數“main”中:

warning.c:7 警告:在無返回值的函數中,“return”帶返回值

warning.c:4 警告:“main”的返回類型不是“int”

可以看出,該選項並沒有發現”long long”這個無效數據類型的錯誤。

· “-pedantic”

允許發出ANSI C標準所列的全部警告信息,同樣也保證所有沒有警告的程序都是符合ANSI C標準的。其運行結果如下所示:

[root@localhost Gcc]# Gcc –pedantic warning.c –o warning

warning.c: 在函數“main”中:

warning.c:5 警告:ISO C90不支持“long long”

warning.c:7 警告:在無返回值的函數中,“return”帶返回值

warning.c:4 警告:“main”的返回類型不是“int”

可以看出,使用該選項查看出了”long long”這個無效數據類型的錯誤。

· “-Wall”

允許發出Gcc能夠提供的所有有用的報警信息。該選項的運行結果如下所示:

[root@localhost Gcc]# Gcc –Wall warning.c –o warning

warning.c:4 警告:“main”的返回類型不是“int”

warning.c: 在函數”main”中:

warning.c:7 警告:在無返回值的函數中,”return”帶返回值

warning.c:5 警告:未使用的變量“tmp”

使用“-Wall”選項找出了未使用的變量tmp,但它並沒有找出無效數據類型的錯誤。

另外,Gcc還可以利用選項對單獨的常見錯誤分別指定警告,有關具體選項的含義感興趣的讀者可以查看Gcc手冊進行學習。

(3)優化選項

Gcc可以對代碼進行優化,它通過編譯選項“-On”來控制優化代碼的生成,其中n是一個代表優化級別的整數。對於不同版本的Gcc來講,n的取值範圍及其對應的優化效果可能並不完全相同,比較典型的範圍是從0變化到2或3。

不同的優化級別對應不同的優化處理工作。如使用優化選項“-O”主要進行線程跳轉(Thread Jump)和延遲退棧(Deferred Stack Pops)兩種優化。使用優化選項“-O2”除了完成所有“-O1”級別的優化之外,同時還要進行一些額外的調整工作,如處理器指令調度等。選項“-O3”則還包括循環展開和其他一些與處理器特性相關的優化工作。

雖然優化選項可以加速代碼的運行速度,但對於調試而言將是一個很大的挑戰。因爲代碼在經過優化之後,原先在源程序中聲明和使用的變量很可能不再使用,控制流也可能會突然跳轉到意外的地方,循環語句也有可能因爲循環展開而變得到處都有,所有這些對調試來講都將是一場噩夢。所以筆者建議在調試的時候最好不使用任何優化選項,只有當程序在最終發行的時候才考慮對其進行優化。

(4)體系結構相關選項

Gcc的體系結構相關選項如表3.9所示。

                                                    Gcc體系結構相關選項列表

 

 [-c]  代表compile,只編譯不連接

        cc foobar.c

  就會把 foobar.c 通過以上的步驟編譯出來。如果你有多個文件要編譯,只要輸入

       僅僅編譯文件,不會連接。如果你只想檢查你寫的測試程序的語法的話,這個選項非常有用。

 

[-D] 代表define

允許從編譯程序命令行定義宏符號


一共有兩種情況:一種是用-DMACRO,相當於在程序中使用#define MACRO;
另一種是用-DMACRO=A,相當於程序中的#define MACRO A.如對下面這代碼:
#ifdefine DEBUG

printf("debug message\n");

#endif

編譯時可加上-DDEBUG參數,執行程序則打印出編譯信息
 

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