色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

【Makefile】C文件包含的頭文件修改,但不重新編譯?

嵌入式物聯網開發 ? 來源:嵌入式物聯網開發 ? 作者:嵌入式物聯網開發 ? 2022-09-08 08:53 ? 次閱讀

在上一篇 《【Linux + Makefile】十分鐘教你學會Makefile的FORCE》文章的最后,筆者就FORCE的用法在一個示例工程中使用,提出了一個問題:為何build_info.h每次都是新生成的(有修改過),而main.c又是有include “build-info.h”,但main.c卻不是每次都重新編譯呢?這個到底是不是違反了Makefile的基本規則呢?本文將給你答案,通過閱讀本文,你將了解到以下內容:

  • 如何保證在C文件中包含的頭文件修改了的時候,C文件每次都會被重新編譯?

為了更好地展示上訴描述的問題,我們將之前的示例工程稍微復雜化一點點:

整個工程有3個.c文件,a.c/b.c/main.c,其中main.c會調用a.c/b.c中的兩個接口,同時main.c會include頭文件build_info.h;這個build_info.h每次編譯都會重新生成,按照我們之前的寫法,我們Makefile可能就是這樣:

SHELL           = /bin/bash #指定shell使用/bin/bash,否則echo -e可能會出問題
ECHO            = echo
BIN             = test
BUILG_INFO_H    = build_info.h
SRC-C-y         += a.c
SRC-C-y         += b.c
SRC-C-y         += main.c
SRC-O           = $(patsubst %.c, $(O)%.o, $(SRC-C-y))

all: gen_build_info $(BIN)

clean: 
    rm -rf $(SRC-O) $(BIN) $(BUILG_INFO_H)

$(BIN) : $(SRC-O)
    gcc -o $(O)"$@" $(SRC-O)
	
%.o : %.c
    gcc -c "$<" -o "$@"
	
gen_build_info: $(BUILG_INFO_H)

$(BUILG_INFO_H): FORCE     #強制生成build_info.h
    @$(RM) $@
    @$(ECHO) '  GEN     $@'
    @$(ECHO) -e   " #ifndef __BUILD_INFO_H__\n"\
				"#define __BUILD_INFO_H__\n"\
				"#define APP_TIME        	\"`date "+%Y-%m-%d %H:%M:%S"`\"\n"\
				"#endif"  > $@

FORCE:
.PHONY: FORCE
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

執行make,我們會發現,跟我們的預期不一樣:它雖然會每次都生成build_info.h,但是main.c包含了build_info.h卻不會每次都重新編譯。這個問題發生的原因,我們來分析下:

在我們的Makefile規則中,main.o只依賴于main.c (Makefile 第18-19行),而在第二次執行make的時候,main.c顯然并沒有被修改,所以main.o不會重新生成,自然可執行文件就不會重新生成。這里的問題根源在于,main.c它是依賴于build_info.h的,而這個依賴關系并沒有體現在Makefile中,所以整個編譯流程達不到我們的預期想法。我們嘗試下,將main.c的依賴頭文件也寫入到Makefile中,怎么實現呢?

恰好,GCC給了我們強大的支持,它有個非常有用的選項 -MD -MF,它可以在生成一個.o的同時也生成它的依賴文件列表,修改后的Makefile如下所示:

SHELL           = /bin/bash #指定shell使用/bin/bash,否則echo -e可能會出問題
ECHO            = echo
BIN             = test
BUILG_INFO_H    = build_info.h
SRC-C-y         += a.c
SRC-C-y         += b.c
SRC-C-y         += main.c
SRC-O           = $(patsubst %.c, $(O)%.o, $(SRC-C-y))
SRC-C-DEPS      = $(patsubst %.c, $(O).%.o.d, $(SRC-C-y))  ## 由 a.c ==> .a.o.d

all: gen_build_info $(BIN)

clean: 
    rm -rf $(SRC-O) $(BIN) $(BUILG_INFO_H) $(SRC-C-DEPS)

$(BIN) : $(SRC-O)
    gcc -o $(O)"$@" $(SRC-O)
	
%.o : %.c
#	生成xxx.o的時候,同時生成它的依賴列表,放在文件.xxx.o.d中
	gcc -c "$<" -o "$@" -MD -MF "$(dir $@).$(notdir $@).d" -MT "$@"
	
gen_build_info: $(BUILG_INFO_H)

$(BUILG_INFO_H): FORCE     #強制生成build_info.h
    @$(RM) $@
    @$(ECHO) '  GEN     $@'
    @$(ECHO) -e   " #ifndef __BUILD_INFO_H__\n"\
				"#define __BUILD_INFO_H__\n"\
				"#define APP_TIME        	\"`date "+%Y-%m-%d %H:%M:%S"`\"\n"\
				"#endif"  > $@

FORCE:
.PHONY: FORCE

# 在Makefile末尾強制包含這些依賴文件
-include $(SRC-C-DEPS)

測試結果如下所示:

再次執行make,多試幾次,一樣的結果。

由上可知,經過改造后的Makefile是實現了我們的需求,每次build_info.h重新生成,導致main.c包含了build_info.h也會重新編譯,而a.c和b.c沒有被修改,所以在未執行make clean的情況下,a.c和b.c是不會被重新編譯的,每次都是僅僅main.c被再次編譯,從而重新生成新的test可執行文件。這樣就是已經達到了【當C文件包含的頭文件修改了的時候,C文件必須重新編譯】的目的。


以上就是關于Makefile的高階用法,基本滿足了我們日常工程實踐的需求。如果你對該Makefile有疑問,歡迎在評論席提出你的疑問,博主很樂意為你解答。


延伸閱讀:

【Linux + Makefile】十分鐘教你學會Makefile的FORCE

?審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11373

    瀏覽量

    211294
  • Makefile
    +關注

    關注

    1

    文章

    125

    瀏覽量

    19279
  • C文件
    +關注

    關注

    0

    文章

    12

    瀏覽量

    2916
收藏 人收藏

    評論

    相關推薦

    STM32使用ISp燒錄HEX文件運行,代碼重新編譯之后的產生的新hex文件選擇全片擦除就沒辦法正常運行,為什么?

    我有一套代碼需要使用ISp燒錄HEX文件運行,代碼有一個老的HEX,無論是全片擦除還是擦除重要部分再下載都沒有問題。但是代碼重新編譯之后的產生的新hex文件,如果選擇全片擦除,就沒辦法正常運行。只有
    發表于 03-10 07:42

    C語言中的頭文件能不能重復包含

    "); return 0;} 我們先來編譯看下,好像沒有任何問題。 root@Turbo:~# gcc test.c -o test root@Turbo:~# 同一個頭文件,隨便包含
    的頭像 發表于 11-26 17:19 ?305次閱讀

    labview程序生成exe文件怎么還原

    在LabVIEW中,程序生成exe文件后,通常這個過程是不可逆的,即exe文件無法直接“還原”回原始的LabVIEW項目文件(.vi或.lvproj)。exe文件是一個
    的頭像 發表于 09-04 17:12 ?2051次閱讀

    Keil工程下改動.c文件編譯的.o文件不更新如何解決?

    在維護公司項目的時候,打開工程下一個C文件在里面添加了一些代碼,然后點擊重新編譯后發現它的二進制O文件沒有同步更新,而其他C
    發表于 09-04 10:35

    linux驅動程序的編譯方法有哪兩種

    Collection)或其他C/C++編譯器來編譯源代碼文件。這種方法較為原始,需要開發者手動指定編譯
    的頭像 發表于 08-30 14:39 ?1083次閱讀

    可重復頭文件的固定結構

    年輕人,你可曾記得,在修習C語言的時候,見過這樣的字句:在創建頭文件的時候,一定要加入保護宏。
    的頭像 發表于 08-29 10:23 ?466次閱讀
    可重復<b class='flag-5'>頭文件</b>的固定結構

    如何修改buildroot和debian文件系統

    本文檔主要介紹在沒有編譯環境的情況下,如何修改buildroot和debian文件系統方法,如在buildroot文件系統中添加文件
    的頭像 發表于 07-22 17:46 ?643次閱讀
    如何<b class='flag-5'>修改</b>buildroot和debian<b class='flag-5'>文件</b>系統

    SDK 1.0移植到eclipse失敗,如何修改makefile文件呢?

    虛擬機編譯太麻煩,想把SDK 1.0移植到安信可的eclipse編譯環境,出現如下錯誤,是否需修改makefile文件?如何
    發表于 07-12 11:08

    文件工程的編譯

    文件工程的編譯
    的頭像 發表于 06-26 13:35 ?368次閱讀
    多<b class='flag-5'>文件</b>工程的<b class='flag-5'>編譯</b>

    IDF-V4.3環境下包含了庫的頭文件編譯報錯,為什么?

    hello_world_main.c里面包含頭文化 #include "xtensa/core-macros.h",編譯則報錯:找不到頭文件; Pss:CMakeL
    發表于 06-21 08:12

    編譯components文件夾內容引入的頭文件不對怎么處理?

    最近在移植LVGL,需要自己寫RGB驅動 我把LVGL放在components文件夾中,但編譯的時候提示缺少esp_lcd下頭文件的引用 仔細找了一下發現,編譯components內容
    發表于 06-17 07:35

    components包含頭文件錯誤是怎么回事?

    我新建了一個工程,添加了一個BLE組件,現在我在BLE組件的頭文件包含了如下文件Code: Select all #include \"api/esp_gatt_common_api.h
    發表于 06-06 07:21

    快來用Makefile管理工程,提高工作效率!

    一、makefile簡介Makefile是一種特別設計用來幫助項目的構建管理的文件。它定義了編譯器和IDE工程管理系統自動執行的命令集合,主要用于自動化
    的頭像 發表于 05-18 08:10 ?449次閱讀
    快來用<b class='flag-5'>Makefile</b>管理工程,提高工作效率!

    請問頭文件能不能定義變量呢?

    最近在編譯一個工程的時候,突然遇到了變量重復定義的問題,根據提示打開這幾個 C 文件,并沒有發現定義變量的地方。后來再找一找,原來變量定義在了頭文件里面。
    的頭像 發表于 04-28 09:33 ?1347次閱讀

    HighTec Tricore編譯速度優化策略探討

    HighTec在編譯時默認是根據工程源文件文件架構首先生成makefile文件,然后執行“make ma
    的頭像 發表于 04-10 12:44 ?2568次閱讀
    HighTec Tricore<b class='flag-5'>編譯</b>速度優化策略探討
    主站蜘蛛池模板: 嫩草影院在线观看精品 | 久久三级视频 | 国产福利视频第一导航 | 91嫩草私人成人亚洲影院 | 精品久久久久久久国产潘金莲 | 一个人免费完整观看日本 | 亚洲AV人无码综合在线观看蜜桃 | 国产午夜精品美女免费大片 | 青青涩射射| 天天国产在线精品亚洲 | 一本道色综合手机久久 | 含羞草国产亚洲精品岁国产精品 | 国产综合18久久久久久软件 | 亚洲伊人久久大香线蕉综合图片 | 亚洲综合色五月久久婷婷 | 黑人特黄AA完整性大片 | black大战chinese周晓琳 | 精品极品三大极久久久久 | 欧美ⅹxxxx18性欧美 | 蜜柚视频高清在线 | 2019精品国产品在线不卡 | 成人无码精品1区2区3区免费看 | 蜜桃成熟时33D在线嘟嘟网 | 免费果冻传媒2021视频 | 麻豆国产MV视频 | 特级做A爰片毛片免费69 | 日本理论片和搜子同居的日子2 | 在线自拍综合亚洲欧美 | 欧美色图14p | 性色AV一区二区三区咪爱四虎 | 日本zljzljzlj精品 | bt天堂午夜国产精品 | 亚洲AV久久久噜噜噜噜 | 久久精品视频uu | 亚洲黄色三级视频 | 久草在线精彩免费视频 | jlzz中国jizz日本老师水多 | 国产福利秒拍weipai.ee | 日韩男明星 | 国产欧美精品国产国产专区 | 青苹果乐园在线观看电视剧 |