日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux Makefile 中的陷阱【转】

發(fā)布時間:2023/12/9 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux Makefile 中的陷阱【转】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)自:https://blog.csdn.net/QQ1452008/article/details/52247944

版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 https://blog.csdn.net/QQ1452008/article/details/52247944

前言

每個編寫過Makefile的程序員都可能遇見過Makefile中內(nèi)含的陷阱,本博文旨在展現(xiàn)陷阱,提醒自己,也供大家一起學(xué)習(xí)。

本博文會隨所遇見的Makefile陷阱有關(guān)的問題而進行后續(xù)的更新。


陷阱一:在定義變量的語句后面空格之后使用了‘#’注釋符

結(jié)果:導(dǎo)致變量的值并不是你所賦值的,而是把值與注釋符之間的空格一起賦值給了變量,使得執(zhí)行違背自己的意愿,而不容易察覺。

實例說明如下(Makefile版本:GNU MAKE 3.81):

TmpDir = /Source #此處隨意定義了一個目錄,#為了驗證此陷阱,特意在賦值語句后空幾格并進行注釋,ifeq ($(TmpDir), /Source) Result = They are equal else Result = They are not equal endif all: @echo $(TmpDir)||||||| @echo $(Result)

?

make之后其結(jié)果為 : /Source ||||||| (注意:/Source與|之間的空格,其實是屬于TmpDir變量的) They are not equal若把 ifeq ($(TmpDir), /Source) 改為 ifeq ($(TmpDir), /Source ) 說明:/Source后面的空格需要跟定義TmpDir與注釋符之間的空格數(shù)相等如此一來,再次make,結(jié)果為:They are equal

擴展一:其實驗證的過程中也引申出了另一個陷阱,ifeq()語句中的陷阱,見陷阱二
擴展二 : 變量賦值語句存在這個陷阱,那宏定義語句呢?及類似于如下語句

CFLAGS += -DTMP=1 #注釋語句 INCFLAGS += -I$(APP_COMMON_SRC_DIR)/Include #注釋語句 main:mian.o gcc $< $(CFLAGS) $(INCFLAGS) -o $@

?

其實經(jīng)過實測表明,這樣并不會影響宏定義“TMP”在源文件中的值, 以及“INCFLAGS ”所在的路徑值。

心得: 通過以上求證,注釋符會影響到Makefile文件內(nèi)部定義使用的變量的值,而不會影響到諸如 -D , -I 后面的值。所以建議Makefile中注釋都不要寫在語句后面,而是語句的前一行,來避免類似的問題出現(xiàn)


陷阱二:ifeq語句的括號里面,不要隨意使用空格

結(jié)果:makefile會吧參數(shù)后面的空格也當(dāng)作參數(shù)的一部分來進行比較,導(dǎo)致結(jié)果違背自己的意愿。

實例說明如下(Makefile版本:GNU MAKE 3.81):

TmpDir = /Source#下方的/Source后面空了幾格 ifeq ($(TmpDir), /Source ) Result = They are equal else Result = They are not equal endif all: @echo $(Result) make之后其結(jié)果為 : They are not equal若把 ifeq ($(TmpDir), /Source ) 改為 ifeq ($(TmpDir), /Source) 如此一來,再次make,結(jié)果為:They are equal

經(jīng)過實測表明,$(TmpDir)后面空幾格沒有影響,唯獨/Source后面空格就會有影響了

心得 : 在Makefile中,最好保證參數(shù)的一致性,是否空格等,不像C語言等語言編程一樣,那么寬松。


陷阱三:在mingw環(huán)境下使用路徑時的陷阱

詳情:在正確使用并能生成.d依賴文件,理論上使得修改任一 .h 或者 .c 文件都能自動進行編譯的情況下,其結(jié)果偏偏就是在修改了.h文件而不能編譯與之相關(guān)的.c文件,即沒有檢查到有文件更新,從而沒有進行編譯。待仔細查看Makefile的內(nèi)容,也不能輕易看出端倪。其實這背后存在一個不易察覺的陷阱。

例子大概如下:

TARGET = Temp # abspath 函數(shù):獲取其參數(shù)中的文件或者目錄的絕對路徑 APP_BASE = $(abspath ../..) DEV_BLD_DIR = $(APP_BASE)/$(TARGET)/Build TEMP = $(APPSRC:.c=.o) APPOBJS_TMP = $(TEMP:.S=.o) # addprefix 函數(shù):把 APPOBJS_TMP 中的文件一一添加前綴 $(DEV_BLD_DIR)/ APPOBJS := $(addprefix $(DEV_BLD_DIR)/,$(APPOBJS_TMP)) APPDEPS_TMP = $(APPOBJS_TMP:.o=.d) APPDEPS := $(addprefix $(DEV_BLD_DIR)/,$(APPDEPS_TMP)) all: Tmp.bin -include $(APPDEPS) ...... #省略了若干內(nèi)容 ...... # subst 函數(shù):把$@中的 Source 替換成 Build # 該編譯的命令,在編譯源文件的同時,也生成了.d 依賴文件 $(DEV_BLD_DIR)/%.o: %.c $(info Compiling $< ...) $(CC) -c -o $(subst Source,Build,$@) $(CFLAGS) $(INCFLAGS) $< -MD -MF $(DEV_BLD_DIR)/$*.d -MP

?

請點擊進入 .d依賴文件 相關(guān)內(nèi)容介紹

其實從結(jié)果上便能大致推測是.d依賴文件部分出現(xiàn)了問題,因為改寫任一文件都要能重新編譯,本身就是.d依賴文件所要賦予的功能。

陷阱:目標(biāo)路徑的問題,即同一文件目標(biāo)的引用時要保持路徑一致。mingw環(huán)境下,windows路徑(e.g. c:\agc.o) 和 mingw路徑(/c/agc.o)都能夠識別,對于make而言, c:\abc.o 和 /c/abc.o 是兩個不同的目標(biāo)。若要是不知道這一知識要點,很難發(fā)現(xiàn) .d 文件開頭 c:\ 和 /c/ 的區(qū)別。(個人疑點:同一環(huán)境,不同工程,有些生成的.d依賴文件中.o目標(biāo)路徑和make中引用的路徑是一樣的,目前也不知是什么原因,總之這個陷阱還是存在的。)

實例陷阱說明:

#以下行將導(dǎo)入所有的.d依賴文件的內(nèi)容,即以 /c/...開頭的內(nèi)容 -include $(APPDEPS) #而以下目標(biāo)依賴關(guān)系中,指明目標(biāo)的路徑則是以 c:\...開頭的路徑 $(DEV_BLD_DIR)/%.o: %.c #其結(jié)果就是導(dǎo)致了因路徑表示的不同,而認為不是同一目標(biāo)的情況出現(xiàn) #使得make不能找到.o目標(biāo)文件依賴的所有依賴源文件,其中包括.h頭文件 #自然而然,也就不能因為.h文件的更新,而重新編譯對應(yīng)的.c文件來生成.o文件

?

解決方法:
既然知道了陷阱所在,就可以利用如下命令來解決該問題:

#通過增加sed命令,把生成的.d依賴文件中的.o目標(biāo)路徑改寫就可以了。 $(DEV_BLD_DIR)/%.o: %.c$(info Compiling $< ...) $(CC) -c -o $(subst Source,Build,$@) $(CFLAGS) $(INCFLAGS) $< -MD -MF $(DEV_BLD_DIR)/$*.d.tmp -MP sed 's,.*\.o[ :]*,$@:,g' < $(DEV_BLD_DIR)/$*.d.tmp > $(DEV_BLD_DIR)/$*.d;\ rm -f $(DEV_BLD_DIR)/$*.d.tmp @echo

?

心得:以后出現(xiàn)類似該情況,即表面上 makefile 中沒有什么問題,但在使用了依賴文件,并修改.h 文件后,不重新編譯的情況,這個時候要考慮路徑問題。不同路徑的表示方法,所表示的目標(biāo)文件在make中會認為不是同一文件。

--------------------- 本文來自 Jerry_yl_ 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/QQ1452008/article/details/52247944?utm_source=copy?

轉(zhuǎn)載于:https://www.cnblogs.com/sky-heaven/p/9735196.html

總結(jié)

以上是生活随笔為你收集整理的Linux Makefile 中的陷阱【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。