Linux下Makefile学习笔记
makefile 可以用于編譯和執行多個C/C++源文件和頭文件。
(1) #include "file.h" 和 #include <file.h> 的區別
#include "file.h" 會先在當前目錄下查找file.h,然后才在系統頭文件目錄中進行查找;
#include <file.h>會先查找系統頭文件目錄,默認是不會在當前目錄下查找的。
(2) 關于在頭文件中使用#ifndef 和 #define?
頭文件的主要作用在于多個代碼文件全局變量(函數)的重用、防止定義的沖突,對各個被調用函數給出一個描述,其本身不需要包含程序的邏輯實現代碼,它只起描述性作用,用戶程序只需要按照頭文件中的接口聲明來調用相關函數或變量,鏈接器會從庫中尋找相應的實際定義代碼。
#ifndef是屬于宏定義的一種,但確切地說它應該是預處理功能(宏定義,文件包含和條件編譯)中的第三種--條件編譯。而#define則就是屬于宏定義。
定義:
#ifndef x //先測試x是否被宏定義過 #define x 程序段1 //如果x沒有被宏定義過,定義x,并編譯程序段 1 #else 程序段2 //如果x已經定義過了則編譯程序段2的語句,“忽視”程序段 1。 #endif //終止if作用: #ifndef 起到的效果是防止一個源文件兩次包含同一個頭文件,而不是防止兩個源文件包含同一個頭文件。網上很多資料對這一細節的描述都是錯誤的。事實上,防止同一頭文件被兩個不同的源文件包含這種要求本身就是不合理的,頭文件存在的價值就是被不同的源文件包含。假如你有一個C源文件,它包含了多個頭文件,比如頭文件A和頭文件B,而頭文件B又包含了頭文件A,則最終的效果是,該源文件包含了兩次頭文件A。如果你在頭文件A里定義了結構體或者類類型(這是最常見的情況),那么問題來了,編譯時會報大量的重復定義錯誤。
(3)?CFLAGS, CXXFLAGS, LDFLAGS, LIBS
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將會設置這個選項,鏈接時會有這個參數,編譯出來的可執行程序的庫文件搜索路徑就得到擴展了。
?
轉載于:https://www.cnblogs.com/alliance/p/6944519.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Linux下Makefile学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: robotframework 配置过程中
- 下一篇: linux 其他常用命令