LiteOS_Lab Makefile分析

      網友投稿 960 2025-03-31

      什么是Makefile


      Makefile是一個名為GNU-Make軟件所需要的腳本文件,該腳本文件可以指導Make軟件控制arm-gcc等工具鏈去編譯工程文件最終得到可執行文件,幾乎所有的Linux發行版都內置了GNU-Make軟件,VScode等多種IED也內置了Make程序。

      你見到的xxx.mk文件或者Makefile都統稱為Makefile腳本文件。

      Makefile腳本文件的語法學習可以參考:

      https://www.gnu.org/software/make/manual/make.html (GNU make官方文檔)

      https://seisman.github.io/how-to-write-makefile/overview.html?(跟我一起寫Makefile 陳皓)

      Makefile的規則

      Makefile的規則如下,這里的[TAB]指鍵盤上的TAB按鍵,不是空格,如果在命令前輸入了空格則會造成錯誤,并且在Makefile中TAB鍵不能隨意使用:

      目標 : 依賴

      [TAB]命令

      例如:

      Hello :

      @echo “Hello”

      這時執行make命令就會輸出一條語句”Hello”,Hello是目標,依賴為空,為了生成目標,需要執行echo “Hello”語句,從而導致輸出Hello。

      例如:假設我們有一個Hello.c C語言源文件,需要將其編譯不鏈接為Hello.o文件,最后在進行連接,Makefile內容如下:

      Hello.out : Hello.o

      gcc -o Hello.out Hello.o

      Hello.o : Hello.c

      gcc -c -o Hello.o Hello.c

      這時執行make命令,make解釋器發現目標為“Hello.out”,但是生成Hello.out需要Hello.o,發現目錄下找不到“Hello.o”,就向下查找是否有生成Hello.o的規則,找到了,發現”Hello.o”依賴于”Hello.c”,在目錄下也找到了Hello.c,就執行語句“gcc -c -o Hello.o Hello.c”生成”Hello.o”,只要編譯過程不出錯,即可得到”Hello.o”,這時可以執行“gcc -o Hello.out Hello.o“生成”Hello.out”

      LiteOS_Lab Makefile分析

      從哪里開始分析?

      這里可以用分析一個C語言或Java語言程序來類比,一般都是根據程序是執行流來進行分析,也就是先找到main函數,因為main函數是程序的執行入口,Makefile也有執行入口,在執行make命令時,make解釋器默認搜索當前目錄下名為“Makefile”的文件,找到后,執行生成第一個目標的命令及生成其依賴所需的命令。

      這里選擇在SDK/Targets目錄中STM32L431_BearPi工程中的GCC目錄下的Makefile開始分析。

      第1行到第140行都是設置一些變量和導入一些makefile文件(其中也沒有任何規則,都是進行一些變量的設置),第143行是第一條規則

      當我們執行make或make all時,就開始生成all目標,其依賴于BUILD_DIR(GCC/build)目錄中的TARGET(Huawei_LiteOS).elf文件,BUILD_DIR和TARGET為兩個變量,一開始就被賦值,如下圖所示,實際使用時$(變量)會被替換為變量的值,例如$(TARGET).elf最終會被替換為Huawei_LiteOS.elf。

      可是Huawei_LiteOS.elf還不存在,make只好繼續向下查找是否有生成Huawei_LiteOS.elf的規則,好在第147行的目標為Huawei_LiteOS.elf,這就是生成Huawei_LiteOS.elf的規則,該規則依賴為$(OBJ_DIRS) $(C_OBJ) $(S_OBJ)分別對應三個目錄,這三個目錄都不存在,所以make只好繼續向下查找,它發現第152行正好為目標是該目錄的規則,就創建了該目錄,解決了$(OBJ_DIRS)這個依賴,接著該處理$(C_OBJ)這個依賴

      Make向下查找依賴發現位于第156行出現生成這個以來的規則,這里的$(C_OBJ):$(BUILD_DIR)/%.o:%.c對應makefile中的靜態模式,我這里簡單的說一下,大家如果想深入了解可以自行百度。

      靜態模型的格式如下:

      目標列表: 與目標列表相匹配的模型: 與依賴相匹配的模型

      [TAB]命令

      來看一個例子,

      目標列表中有foo.o、bar.o和test.s三個值,首先將匹配%.o的模型找出來,test.s不匹配就被遺棄了,將匹配的foo.o和bar.o替換為foo.c和bar.c,最終這一條規則等于執行了下列這兩條規則,為什么要這樣做呢?你可以試想以下,假設目標列表中有幾千個文件,這樣做的話是不是就可以少寫很多規則:

      回到LiteOS_Lab的Makefile上來,156行將C_OBJ變量中的符合build/xxx.o格式的文件作為xxx.c格式的依賴,C_OBJ變量的賦值如下圖所示:

      $(patsubst PATTERN, REPLACEMENT, TEXT)函數的作用是模式替換,將TEXT中以空格隔開的每個單詞(文件名),符合PATTERN格式的替換為REPLACEMENT格式,例如第124行,將所有的C_SOURCE變量中的文件名,凡是只要在SDK/ iot_link目錄下的都替換為.o后綴,SDK/ iotlink目錄中有一個符合該模型的文件,link_main.c,在執行該規則對應的命令時,目標文件為link_main.o,第125和126行同上。

      這里以link_main.c為例向大家講解指令,經過模式替換后規則如下:

      link_main.o: link_main.c

      $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(@:%.o=%.lst) $

      這里的CC是指arm-none-eabi-gcc,CFLAGS是指各類編譯參數,例如-MMD -MP -Wno-missing-braces,$(@:%.o=%.lst)函數的作用是將$@目標符合%.o模型的值替換為%. lst,這里就將link_main.o替換link_main. lst,$<是指第一個依賴,$@是指目標,組合的命令后如下:

      arm-none-eabi-gcc -c -MMD -MP -Wno-missing-braces -Wa,-a,-ad,-alms=link_main. lst link_main.c? -o link_main.o。一句話來說就是將所有的.c源文件編譯不鏈接生成.o文件和.lst文件,等待后續進一步操作。

      第160和161行的操作類似于上面的操作,將所有的匯編文件都編譯不鏈接生成.o文件等待后續進一步操作。

      第147到149行規則所需的依賴全部都生成好了,可以開始執行該規則的命令,將所有依賴通過LDFLAGS變量中的值鏈接生成Huawei_LiteOS.elf文件并列出程序文件中各段的大小。

      LDFLAGS變量中通過MCU變量定義了內核相關參數,例如ARM架構的版本以及是否支持硬件浮點數運算等參數,如下圖所示,如果你需要將工程移植到不是STM32L431系類的MCU上,就需要修改MCU變量的值。

      LDFLAGS變量中通過LDSCRIPT變量讀取os.ld鏈接腳本來控制程序該如何鏈接,每個段應該存放在程序中的何處,在os.ld鏈接腳本中還指明了MCU的RAM和FLASH大小及起始位置,我們在進行移植時也需要修改。

      Huawei_LiteOS.elf文件是第143至145行規則的依賴,將該elf文件轉換為Huawei_LiteOS.hex和Huawei_LiteOS.bin文件,即可燒錄。

      現在大家應該明白make控制下的整個程序編譯過程了吧,以及Makefile文件起到的作用,我們再來看看前面的include導入的文件,如下圖所示:

      首先導入了.config文件,這由Kconfig軟件讀取用戶通過圖形化配置的各項參數信息生成的,其中包含了對SDK中各組件參數的配置信息,如下圖所示:

      以AT組件為例,CONFIG_AT_ENABLE=y代表使能AT組件;CONFIG_AT_DEVNAME="atdev"將AT組件用到的串口以"atdev"注冊到driver層中;CONFIG_AT_OOBTABLEN=6 OOB表的長度配置為6個,這時用于接收異步數據的結構體,意味著我們最多能配置6個特定字符串,當這時字符串出現時調用相應處理函數進行處理;CONFIG_AT_RECVMAXLEN=1024將AT框架中的接收緩存區大小配置為1024字節,如果你的MCU資源受限可以減少這里的大小;CONFIG_AT_TASKPRIOR=10將AT任務的優先級配置為10,注意:這里只有第35行這條語句會影響Make的編譯,其余語句是為了記錄用戶做了哪些配置和生成iot_config.h所用。

      .config文件中所有的組件配置都和上面分析的一致,如果組件沒有被使能如下圖所示:

      相信大家看到這里又有新的疑問了,這些配置是如何影響到程序的編譯呢?回到前面的第70行include $(SDK_DIR)/iot_link/iot.mk,來看看這個SDK/iot_link目錄下的iot.mk文件中有什么你就有答案了,如下圖所示:

      該Makefile將每個組件所屬文件夾下的Makefile也導入進來了,我們還是以AT框架為例,第31行,導入at目錄下的at.mk文件,該Makefile內容如下圖所示:

      看到了吧,第7行與前面的CONFIG_AT_ENABLE=y變量相對應,ifeq ($(CONFIG_AT_ENABLE),y)語句的意思是如果CONFIG_AT_ENABLE變量的值為y,則將ifeq到endif之間的語句全部執行。

      第8至9行將at目錄下所有.c文件添加到C_SOURCES變量中,注意這里用的是+=是追加上去。

      第11至12行將at目錄下所有.h文件所在路徑(注意是路徑,通過-I參數指定頭文件所在的路徑,這樣編譯器才能找到頭文件,否則會因為找不到頭文件導致編譯失敗)添加到C_INCLUDES變量中,注意這里用的是+=是追加上去。

      第14至14行將-D CONFIG_AT_ENABLE=1文本追加到C_DEFS變量中。

      這三個變量大家都很眼熟吧,這就是工程目錄/GCC目錄中Makefile中的那三個變量,如下圖所示:

      這樣AT組件中的所有源文件和頭文件就參與了編譯。

      回到第三個include,include $(MAKEFILE_DIR)/project.mk,這是用于包含(引入)工程目錄/GCC目錄下的project.mk,該Makefile部分內容如下圖所示:

      主要用于包含Hal庫中的文件以及用戶自己添加進去的文件,這也是移植時需要進行修改的文件之一,大家可以仿照我前面分析的方法自己分析一下。最終所有被添加進入的.c源文件會被追加到C_SOURCES變量中,所有.h頭文件所在的路徑會被追加到C_INCLUDES變量中。

      總結

      以上就是LiteOS_Lab中Makefile運行的機制了,大家可以自己跟著文章全部分析分析一邊以加深影響,SDK中所有的Makefile文件都不需要也不能進行修改,只需要修改工程中的三個Makefile,.config(這個不用手動修改,可以通過圖形化配置進行修改),Makefile(根據目標MCU修改MCU相關的參數即可,也就是MCU這個變量的值),project.mk(根據目標MCU修改、添加或刪除庫文件以及用戶文件以及最后的C_DEFS變量即可)。

      輕量級操作系統 LiteOS Linux Makefile

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何恢復Office 2010中未保存的版本文檔
      下一篇:東旭光電耐摔玻璃通過國際知名終端認證和批量使用
      相關文章
      中文亚洲成a人片在线观看| 国产成人精品日本亚洲专一区| 亚洲人成电影网站免费| 亚洲国产高清美女在线观看| 久久精品国产精品亚洲毛片| 久久亚洲精品成人av无码网站| 亚洲爆乳精品无码一区二区三区 | 亚洲国产精品久久人人爱| 亚洲久本草在线中文字幕| 亚洲AV电影院在线观看| 亚洲AV无码久久精品色欲| 亚洲AV无码成人精品区在线观看| 久久91亚洲人成电影网站| 最新国产AV无码专区亚洲| 亚洲一区AV无码少妇电影☆| 丁香五月亚洲综合深深爱| 亚洲日韩乱码中文无码蜜桃臀网站| 国产亚洲人成A在线V网站| 亚洲中文字幕在线观看| 亚洲精品国产品国语在线| 亚洲av无码不卡| 亚洲成人在线电影| 亚洲高清视频在线播放| 亚洲精品国产情侣av在线| 亚洲人6666成人观看| 亚洲AV无码一区二区三区牛牛| 亚洲天堂2017无码中文| 亚洲日本在线电影| 亚洲AV无码一区二区三区网址| 国产亚洲蜜芽精品久久| 亚洲人AV永久一区二区三区久久| 4338×亚洲全国最大色成网站| 久久亚洲中文字幕精品一区| 国产亚洲无线码一区二区| 久久青青草原亚洲av无码app| 亚洲精品中文字幕乱码| 中文有码亚洲制服av片| 色天使色婷婷在线影院亚洲| 亚洲一级片内射网站在线观看| 亚洲色自偷自拍另类小说| 亚洲阿v天堂在线|