makefile學習筆記

#。對於一般多字符變量的引用必須使用括號了標記,否則make將把變量名的首字母作爲作爲變量而不是整個字符串(“$PATH”在Makefile中實際上是“$(P)ATH”)。
# 這一點和shell中變量的引用方式不同。shell中變量的引用可以是“${xx}”或者“$xx”格式。但在Makefile中多字符變量名的引用只能是“$(xx)”或者“${xx}”格式。


name1 := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
include inc.mk

#並且下面的定義也相當於 foo = $(P)ATH。如果$P變量沒有定義,則爲ATH。
foo = $PATH

ch = $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH))))
pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))
name2 := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
all:
        @echo $$(foo)         #相當於在命令行執行 @echo $(f00)
        @echo $(foo)          #相當於             @echo ATH
       
#value函數功能:不對變量“VARIBLE”進行任何展開操作,直接返回變量“VARIBALE”的值。
#。這裏“VARIABLE”是一個變量名,一般不包含“$”(除非計算的變量名)。
# 如果 不是一個變量名(或者在文件中沒有找到定義),則value函數返回值爲空
ppp=foo
       @echo $(value $(ppp))       #效果和@echo $(value foo)一樣
        @echo $(value foo)    #相當於             @echo $PATH
        @echo $(value $PATH)  #這裏並不會取到path的環境變量的值,相當於$P爲空,$PATH展開爲ATH,而ATH不是變量名。所以value函數的返回值爲空。所以相當於執行@echo
       
       
       
#美元符號“$”在Makefile中有特殊的含義,所有在命令或者文件名中使用“$”時需要用兩個美元符號“$$”來表示。
        @echo $$PATH          #顯示出PATH環境變量的值,相當於在命令行執行: @echo $PATH

        @echo pt = $(pathsearch)
        @echo t = $(ch)
        @echo name1 = $(name1)
        @echo name2 = $(name2)
       
       
       
# 一類是在這些依賴文件被更新後,需要更新規則的目標;另一類是更新這些依賴的,可不需要更新規則的目標。
#我們把第二類稱爲:“order-only”依賴。書寫規則時,“order-only”依賴使用管道符號“|”開始,作爲目標的一個依賴文件。
#規則依賴列表中管道符號“|”左邊的是常規依賴,管道符號右邊的就是“order-only”依賴。這樣的規則書寫格式如下:
#TARGETS : NORMAL-PREREQUISITES | ORDER-ONLY-PREREQUISITES       


#Makefile中統配符可以出現在以下兩種場合:
#1. 可以用在規則的目標、依賴中,make在讀取Makefile時會自動對其進行匹配處理(通配符展開);
#2. 可出現在規則的命令中,通配符的通配處理是在shell在執行此命令時完成的。
#除這兩種情況之外的其它上下文中,不能直接使用通配符。而是需要通過函數“wildcard”(可參考8.3 文件名處理函數一節)來實現。

 

# 當規則中依賴文件列表中存在一個“-lNAME”形式的文件時。make將根據“NAME”首先搜索當前系統可提供的共享庫,如果當前系統不能提供這個共享庫,
# 則搜索它的靜態庫(當然你可以在命令行中使用連接選項來指定程序採用動態連接還是靜態連接,這裏我們不討論)。來看一下詳細的過程。
# 1. make在執行規則時會在當前目錄下搜索一個名字爲“libNAME.so”的文件;
# 2. 如果當前工作目錄下不存在這樣一個文件,則make會繼續搜索使用“VPATH”或者“vpath”指定的搜索目錄。
# 3. 還是不存在,make將搜索系統庫文件存在的默認目錄,順序是:“/lib”、“/usr/lib”和“PREFIX/lib”(在Linux系統中爲“/usr/local/lib”,其他的系統可能不同)。
# 如果“libNAME.so”通過以上的途徑最後還是沒有找到的話,那麼make將會按照以上的搜索順序查找名字爲“libNAME.a”的文件。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
# 假設你的系統中存在“/usr/lib/libcurses.a”(不存在“/usr    

 

# 但是如果在當前工作目錄下存在文件“clean”,情況就不一樣了,同樣我們輸入“make clean”,由於這個規則沒有任何依賴文件,
# 所以目標被認爲是最新的而不去執行規則所定義的命令,因此命令“rm”將不會被執行。這並不是我們的初衷。爲了解決這個問題,
# 我們需要將目標“clean”聲明爲僞目標。將一個目標聲明爲僞目標的方法是將它作爲特殊目標.PHONY”的依賴。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          

# make存在一個內嵌隱含變量“RM”,它被定義爲:“RM = rm –f”。

#空目標文件只是用來記錄上一次執行此規則命令的時間。在這樣的規則中,命令部分都會使用“touch”在完成所有命令之後來更新目標文件的時間戳,記錄此規則命令的最後執行時間。
#make時通過命令行將此目標作爲終極目標,當前目錄下如果不存在這個文件,“touch”會在第一次執行時創建一個空的文件(命名爲空目標文件名)。

 

#。此規則所定義的命令將會被執行,如果是多行命令,那麼每一行命令將在一個獨立的子shell進程中被執行.
#通常系統中可能存在多個不同的shell。但在make處理Makefile過程時,如果沒有明確指定,那麼對所有規則中命令行的解析使用“/bin/sh”來完成。   
#變量引用置換“$(sources : .c=.d)”的功能是根據變量“source”指定的.c文件自動產生對應的.d文件   


#在Makefile中書寫在同一行中的多個命令屬於一個完整的shell命令行,書寫在獨立行的一條命令是一個獨立的shell命令行。
#因此:在一個規則的命令中,命令行“cd”改變目錄不會對其後的命令的執行產生影響。就是說其後的命令執行的工作目錄不會是之前使用“cd”進入的那個目錄。
#如果要實現這個目的,就不能把“cd”和其後的命令放在兩行來書寫。而應該把這兩條命令寫在一行上,用分號分隔。這樣它們纔是一個完整的shell命令行。

#。make的環境變量“SHELL”沒有使用系統環境變量的定義。因爲系統環境變量“SHELL”指定那個程序被用來作爲用戶和系統交互的接口程序,
# 它對於不存在直接交互過程的make顯然不合適。在make的環境變量中“SHELL”會被重新賦值;


#爲了忽略一些無關命令執行失敗的情況,我們可以在命令之前加一個減號“-”(在[Tab]字符之後),來告訴make忽略此命令的執行失敗。
# 命令中的“-”號會在shell解析並執行此命令之前被去掉,shell所解釋的只是純粹的命令,“-”字符是由make來處理的。

# 通過對編譯器指定參數-I<PATH>來指定頭文件所在目錄,可以用 #include <>來引用。例如:gcc -I./include hello.c,將從當前目錄下的include目錄下去尋找頭文件。
# 同理,程序中調用的庫函數在編譯時也需要指定路徑,同時指定庫。使用-L<PATH>參數指定庫文件的目錄,-l<FILE>指定包含的庫文件。例如,要使用libXXX.so庫,參數爲-lXXX。
#  一般一個庫編譯完成後有庫文件和頭文件。如果要使用這個庫,可以將庫文件目錄和頭文件目錄分別用-I和-L參數指定,也可以將他們拷貝到編譯器的include和lib目錄下。


#在make的遞歸調用中,需要了解一下變量“CURDIR”,此變量代表make的工作目錄。當使用“-C”選項進入一個子目錄後,此變量將被重新賦值。
#在使用make的遞歸調用時,在Makefile規則的命令行中應該使用變量“MAKE”來代替直接使用“make”。

 

ldd:顯示可執行文件或者庫文件依賴的庫文件。
objdump:顯示elf可執行文件的內部信息。
    -h:顯示
    -t:顯示符號信息
    -T:顯示動態符號信息。(例如引用動態鏈接庫中的函數名稱)
    -r:顯示重定位入口信息。
    -R:顯示動態重定位入口信息。(例如:動態鏈接庫中的變量或者函數地址)
    -s:顯示所有section內容。
    -S:反彙編代碼段。
objcopy:copy elf文件內容
    -R:刪除某個section
    -j:僅僅複製指定的section
   
# 放在/lib和/usr/lib和/usr/local/lib裏的庫直接用-l參數就能鏈接了,   

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