在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 來(lái)源:嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 作者:嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 2022-09-08 08:53 ? 次閱讀

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

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

為了更好地展示上訴描述的問(wèn)題,我們將之前的示例工程稍微復(fù)雜化一點(diǎn)點(diǎn):

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

SHELL           = /bin/bash #指定shell使用/bin/bash,否則echo -e可能會(huì)出問(wèn)題
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     #強(qiáng)制生成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

執(zhí)行make,我們會(huì)發(fā)現(xiàn),跟我們的預(yù)期不一樣:它雖然會(huì)每次都生成build_info.h,但是main.c包含了build_info.h卻不會(huì)每次都重新編譯。這個(gè)問(wèn)題發(fā)生的原因,我們來(lái)分析下:

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

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

SHELL           = /bin/bash #指定shell使用/bin/bash,否則echo -e可能會(huì)出問(wèn)題
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的時(shí)候,同時(shí)生成它的依賴列表,放在文件.xxx.o.d中
	gcc -c "$<" -o "$@" -MD -MF "$(dir $@).$(notdir $@).d" -MT "$@"
	
gen_build_info: $(BUILG_INFO_H)

$(BUILG_INFO_H): FORCE     #強(qiáng)制生成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末尾強(qiáng)制包含這些依賴文件
-include $(SRC-C-DEPS)

測(cè)試結(jié)果如下所示:

再次執(zhí)行make,多試幾次,一樣的結(jié)果。

由上可知,經(jīng)過(guò)改造后的Makefile是實(shí)現(xiàn)了我們的需求,每次build_info.h重新生成,導(dǎo)致main.c包含了build_info.h也會(huì)重新編譯,而a.c和b.c沒(méi)有被修改,所以在未執(zhí)行make clean的情況下,a.c和b.c是不會(huì)被重新編譯的,每次都是僅僅main.c被再次編譯,從而重新生成新的test可執(zhí)行文件。這樣就是已經(jīng)達(dá)到了【當(dāng)C文件包含的頭文件修改了的時(shí)候,C文件必須重新編譯】的目的。


以上就是關(guān)于Makefile的高階用法,基本滿足了我們?nèi)粘9こ虒?shí)踐的需求。如果你對(duì)該Makefile有疑問(wèn),歡迎在評(píng)論席提出你的疑問(wèn),博主很樂(lè)意為你解答。


延伸閱讀:

【Linux + Makefile】十分鐘教你學(xué)會(huì)Makefile的FORCE

?審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11345

    瀏覽量

    210398
  • Makefile
    +關(guān)注

    關(guān)注

    1

    文章

    125

    瀏覽量

    19219
  • C文件
    +關(guān)注

    關(guān)注

    0

    文章

    12

    瀏覽量

    2870
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C語(yǔ)言中的頭文件能不能重復(fù)包含

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

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

    在維護(hù)公司項(xiàng)目的時(shí)候,打開(kāi)工程下一個(gè)C文件在里面添加了一些代碼,然后點(diǎn)擊重新編譯后發(fā)現(xiàn)它的二進(jìn)制O文件沒(méi)有同步更新,而其他C
    發(fā)表于 09-04 10:35

    linux驅(qū)動(dòng)程序的編譯方法有哪兩種

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

    可重復(fù)頭文件的固定結(jié)構(gòu)

    年輕人,你可曾記得,在修習(xí)C語(yǔ)言的時(shí)候,見(jiàn)過(guò)這樣的字句:在創(chuàng)建頭文件的時(shí)候,一定要加入保護(hù)宏。
    的頭像 發(fā)表于 08-29 10:23 ?404次閱讀
    可重復(fù)<b class='flag-5'>頭文件</b>的固定結(jié)構(gòu)

    如何修改buildroot和debian文件系統(tǒng)

    本文檔主要介紹在沒(méi)有編譯環(huán)境的情況下,如何修改buildroot和debian文件系統(tǒng)方法,如在buildroot文件系統(tǒng)中添加文件
    的頭像 發(fā)表于 07-22 17:46 ?545次閱讀
    如何<b class='flag-5'>修改</b>buildroot和debian<b class='flag-5'>文件</b>系統(tǒng)

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

    虛擬機(jī)編譯太麻煩,想把SDK 1.0移植到安信可的eclipse編譯環(huán)境,出現(xiàn)如下錯(cuò)誤,是否需修改makefile文件?如何
    發(fā)表于 07-12 11:08

    文件工程的編譯

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

    IDF-V4.3環(huán)境下包含了庫(kù)的頭文件會(huì)編譯報(bào)錯(cuò),為什么?

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

    components包含頭文件錯(cuò)誤是怎么回事?

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

    快來(lái)用Makefile管理工程,提高工作效率!

    一、makefile簡(jiǎn)介Makefile是一種特別設(shè)計(jì)用來(lái)幫助項(xiàng)目的構(gòu)建管理的文件。它定義了編譯器和IDE工程管理系統(tǒng)自動(dòng)執(zhí)行的命令集合,主要用于自動(dòng)化
    的頭像 發(fā)表于 05-18 08:10 ?392次閱讀
    快來(lái)用<b class='flag-5'>Makefile</b>管理工程,提高工作效率!

    請(qǐng)問(wèn)頭文件能不能定義變量呢?

    最近在編譯一個(gè)工程的時(shí)候,突然遇到了變量重復(fù)定義的問(wèn)題,根據(jù)提示打開(kāi)這幾個(gè) C 文件,并沒(méi)有發(fā)現(xiàn)定義變量的地方。后來(lái)再找一找,原來(lái)變量定義在了頭文件里面。
    的頭像 發(fā)表于 04-28 09:33 ?1269次閱讀

    HighTec Tricore編譯速度優(yōu)化策略探討

    HighTec在編譯時(shí)默認(rèn)是根據(jù)工程源文件文件架構(gòu)首先生成makefile文件,然后執(zhí)行“make ma
    的頭像 發(fā)表于 04-10 12:44 ?2362次閱讀
    HighTec Tricore<b class='flag-5'>編譯</b>速度優(yōu)化策略探討

    已經(jīng)將文件的路徑添加了,頭文件包含了,為什么編譯會(huì)提示未定義符號(hào)錯(cuò)誤?

    我準(zhǔn)備添加TFT顯示屏的驅(qū)動(dòng),已經(jīng)將文件的路徑添加了,頭文件包含了,但在編譯時(shí)卻提示未定義符號(hào)錯(cuò)誤。
    發(fā)表于 03-07 07:36

    rt-thread studio執(zhí)行清空項(xiàng)目的時(shí)候發(fā)現(xiàn)系統(tǒng)找不到指定的文件怎么解決?

    在基于rt-thread studio開(kāi)發(fā)時(shí),出于嘗試添加了一些組件,后來(lái)又刪掉了一些不需要的組件,重新編譯的時(shí)候拋出錯(cuò)誤,錯(cuò)誤指出刪掉的組件的相關(guān).o文件還是存在,執(zhí)行清空項(xiàng)目的時(shí)候發(fā)現(xiàn)系統(tǒng)找不到
    發(fā)表于 03-05 06:18

    C語(yǔ)言中的頭文件

    #include 指令會(huì)指示 C 預(yù)處理器瀏覽指定的文件作為輸入。預(yù)處理器的輸出包含了已經(jīng)生成的輸出,被引用文件生成的輸出以及 #include 指令之后的文本輸出。
    發(fā)表于 02-23 14:06 ?522次閱讀
    主站蜘蛛池模板: 一级黄色毛片播放 | 色噜噜狠狠成人影院 | 久久视频精品36线视频在线观看 | 高清成年美女黄网站色大 | 免费国内精品久久久久影院 | 一区二区三区在线看 | 国产成人啪精品午夜在线观看 | 男人午夜影院 | 美女啪啪91 | 午夜精品视频在线观看 | 激情视频综合网 | 女人69xxx| 欧美一级特黄aaaaaaa在线观看 | 亚洲狠狠网站色噜噜 | 高清一区二区三区免费 | 91九色porny蝌蚪| 国产精品美乳在线观看 | 六月婷婷综合 | 99国产精品久久久久久久成人热 | 美女黄页免费 | 青草悠悠视频在线观看 | 国产成在线观看免费视频 | 夜夜春夜夜夜夜猛噜噜噜噜噜 | 国产成人综合亚洲怡春院 | 泰剧天堂 | 伊人精品成人久久综合欧美 | 亚洲影视网 | 校园春色亚洲欧美 | 日韩欧美一区二区三区不卡视频 | 97久久伊人精品影院 | 天天干天天噜 | 美女污污网站 | 操欧洲美女| 日韩免费一区 | 一级做a爰片久久毛片免费 一级做a爰片久久毛片免费看 | 亚洲youjizz| 午夜视频观看 | 四虎在线最新地址公告 | 国产真实乱偷人视频 | 免费视频在线播放 | 美国一级大黄香蕉片 |