一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

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

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

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

【RT-Thread學(xué)習(xí)筆記】Makefile的FORCE

嵌入式物聯(lián)網(wǎng)開發(fā) ? 來源:嵌入式物聯(lián)網(wǎng)開發(fā) ? 作者:嵌入式物聯(lián)網(wǎng)開發(fā) ? 2022-07-30 13:55 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

?

相信大家在使用Linux環(huán)境編程的時(shí)候,一定接觸過Makefile這個(gè)玩意。Makefile在搭建自定義的編譯環(huán)境,尤其是自動(dòng)化編譯、多功能一鍵編譯等功能上,還是發(fā)揮了很大的作用。如果接觸過Linux內(nèi)核編譯的童鞋,一定會看到編譯內(nèi)核中的各級Makefile中,有很多地方都會有 FORCE 這樣的字段出現(xiàn),那么這個(gè) FORCE 究竟是何方神圣呢?本文將給你答案,通過閱讀本文,你講了解到以下內(nèi)容:

  • Makefile的基本規(guī)則
  • FORCE 在Makefile的含義
  • FORCE在實(shí)際工程中的應(yīng)用

Makefile的基本規(guī)則


Makefile的基本形式如下所示:

TARGET :DEPENDENCES
    CMD

# TARGET:生成的目標(biāo),可以是一個(gè)文件,也可以是一個(gè)虛擬符號(非真實(shí)文件)
# DEPENDENCES: 生成目標(biāo)的所有依賴,它是一個(gè)集合,可以只有一個(gè)文件,或者很多文件;也可以是虛擬符號
# CMD:把所有依賴生成目標(biāo)的執(zhí)行命令,其中CMD前面是一個(gè)TAB鍵,而不能是空格
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

Makefile的基本規(guī)則,歸納起來就是一句話:【當(dāng)一個(gè)TARGET (欲生成的目標(biāo))比它的任何一個(gè)DEPENDENCES(依賴的文件)舊時(shí),這個(gè)TARGET就要重新生成】。

這句話讀起來很簡單,就是Makefile在執(zhí)行編譯的時(shí)候,會先去判斷TARGET和其依賴文件的時(shí)間,如果TARGET的時(shí)間比較舊,意味著依賴文件有更新了,所以TARGET要重新生成;反之,如果TARGET的時(shí)間比較新,意味著在TARGET生成后,依賴文件是沒有改變過的,自然就不用重新去生成TARGET。


FORCE 在Makefile的含義


有了上一小節(jié)中介紹的Makefile基本概念后,我們來進(jìn)一步分析下Makefile中的FORCE,以下是FORCE在Makefile中出現(xiàn)的最簡化版本:

file = test.txt

all: generate-a-file

generate-a-file: $(file) 

$(file):
	@echo "Force to generate a test file for every make ..."
	rm -rf $(file) && echo `date "+%Y-%m-%d %H:%M:%S"` > $(file)

FORCE:
.PHONY: FORCE
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

這個(gè)Makefile不是用于真正的編譯工程,而是提供一個(gè)很簡單的功能,生成一個(gè)test.txt,并且這個(gè)test.txt的內(nèi)容是記錄每次編譯的時(shí)間。但是使用這個(gè)makefile執(zhí)行make時(shí),發(fā)現(xiàn)只有第一次make的時(shí)候,才會生成test.txt,而其他時(shí)候只要test.txt還存在都不會重新生成,如下所示:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?編輯

很明顯,它沒有達(dá)到我們期望的“每次編譯都重新生成test.txt”。這個(gè)時(shí)候 FORCE就發(fā)揮作用了,我們在 test.txt目標(biāo)的后面添加 FORCE作為它的依賴試試看,即如下所示:

file = test.txt

all: generate-a-file

generate-a-file: $(file) 

$(file): FORCE  #FORCE表示每次這段都要執(zhí)行
	@echo "Force to generate a test file for every make ..."
	rm -rf $(file) && echo `date "+%Y-%m-%d %H:%M:%S"` > $(file)

FORCE:
.PHONY: FORCE
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

執(zhí)行輸出如下所示: 我們可以看到,這達(dá)到了我們的目的,每次test.txt都是重新生成了,它記錄了每次make的時(shí)間。

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?編輯

這個(gè)就是要?dú)w功于 FORCE 的功勞了。我們來分析下,為何加了 FORCE 就能實(shí)現(xiàn)這樣的功能。

我們可以注意到FORCE這個(gè)目標(biāo),它的DEPENDENCES是空的,CMD部分也是空的;這個(gè)比較特殊了,在Makefile里,像這樣依賴為空、執(zhí)行命令也為空的TARGET,則需要每次都重新生成,而這個(gè)TARGET不一定是一個(gè)文件,可以是任意的符號,而 FORCE 只是我們最常用的符號,理論上它可以換成任意符號,比如NO-FORCE、SOMETHING等等。


FORCE在實(shí)際工程中的應(yīng)用


上一小節(jié),我們講到可以用Makefile配合shell命令來自動(dòng)生成一些文件,自然我們很容易想到,在我們實(shí)際的編譯工程中,往往需要?jiǎng)討B(tài)生成一些配置項(xiàng),然后嵌入到代碼中,比如編譯版本號、編譯時(shí)間等。

假設(shè)我們有以下一個(gè)main.c:

#include 
#include "build_info.h"  #這個(gè)頭文件需要每次編譯時(shí)自動(dòng)生成

int main(int argc, const char *argv[])
{
    printf("%s >>> APP_TIME=%s\n", __func__, APP_TIME);
    return 0;
}
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

示例代碼很簡單,就是再main函數(shù)中打印一個(gè) build_info.h中的一個(gè)宏定義APP_TIME,這個(gè)build_info.h要求每次編譯的時(shí)候都重新生成。我們給出的Makefile示例如下:

##拷貝時(shí),注意tab鍵
SHELL           = /bin/bash #指定shell使用/bin/bash,否則echo -e可能會出問題
ECHO            = echo
BIN             = test
BUILG_INFO_H    = build_info.h
SRC-C-y         = main.c
SRC-O           = $(patsubst %.c, $(O)%.o, $(SRC-C-y))

all: gen_build_info $(BIN)

$(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

make執(zhí)行輸出測試如下:

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?編輯

從輸出的測試,我們可以看出,make的每次執(zhí)行都觸發(fā)了生成build_info.h,但是運(yùn)行編譯出來的test可執(zhí)行程序,我們發(fā)現(xiàn)并不是每次生成的build_info.h的內(nèi)容都傳遞到了test里面;也就是當(dāng)build_info.h改變的時(shí)候,test沒有被重新編譯。這里先留下點(diǎn)疑問,為何會產(chǎn)生這樣的問題。博主將會在后續(xù)的文章中解決這個(gè)問題。


不管怎么樣,經(jīng)過對上文的學(xué)習(xí),我們至少掌握了 FORCE的基本用法,而在實(shí)際項(xiàng)目工程中,我們也見證了它的威力;那么,你學(xué)會了嗎?如果還有疑問,歡迎在評論席提出你的問題和看法,博主定會盡力解決你的困惑。

版權(quán)申明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請注明出處!【Linux + Makefile】十分鐘教你學(xué)會Makefile的FORCE_架構(gòu)師李肯-CSDN博客

原創(chuàng)作者:recan

電子郵箱:recan.szu@foxmail.com


延伸閱讀:

【Linux + Makefile】Makefile的高階用法:解決C文件包含的頭文件修改了,但C文件不重新編譯的問題

?審核編輯:湯梓紅

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

    關(guān)注

    87

    文章

    11511

    瀏覽量

    213874
  • Makefile
    +關(guān)注

    關(guān)注

    1

    文章

    125

    瀏覽量

    19738
  • RT-Thread
    +關(guān)注

    關(guān)注

    32

    文章

    1412

    瀏覽量

    41974
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    RT-Thread學(xué)習(xí)筆記】使用scons命令生成靜態(tài)庫

    RT-Thread學(xué)習(xí)筆記】如何使用scons 命令中buildlib的生成靜態(tài)庫?
    的頭像 發(fā)表于 07-27 09:13 ?7117次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】使用scons命令生成靜態(tài)庫

    RT-Thread學(xué)習(xí)筆記】RISC-V匯編基礎(chǔ)三大塊知識

    RT-Thread學(xué)習(xí)筆記】RISC-V匯編基礎(chǔ)的三大塊知識
    的頭像 發(fā)表于 07-30 11:01 ?3246次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】RISC-V匯編基礎(chǔ)三大塊知識

    RT-Thread Nano入門學(xué)習(xí)筆記

    RT-Thread Nano入門學(xué)習(xí)筆記
    發(fā)表于 11-26 12:36 ?20次下載
    <b class='flag-5'>RT-Thread</b> Nano入門<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>

    RT-Thread 應(yīng)用筆記 - RTC Alarm 組件的使用

    RT-Thread 應(yīng)用筆記 - 不正確使用LOG也會引發(fā)hard faultRT-Thread 應(yīng)用筆記 - RTC Alarm 組件的使用RT-
    發(fā)表于 01-25 18:18 ?10次下載
    <b class='flag-5'>RT-Thread</b> 應(yīng)用<b class='flag-5'>筆記</b> - RTC Alarm 組件的使用

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 理解defunct僵尸線程

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:19 ?9次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 理解defunct僵尸線程

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 設(shè)備模型rt_device的理解

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:19 ?8次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 設(shè)備模型<b class='flag-5'>rt</b>_device的理解

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對象鏈表結(jié)構(gòu)深入理解

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:23 ?6次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 內(nèi)核對象鏈表結(jié)構(gòu)深入理解

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對象初始化鏈表組織方式

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:24 ?3次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 內(nèi)核對象初始化鏈表組織方式

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對象操作API

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:26 ?7次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 內(nèi)核對象操作API

    RT-Thread學(xué)習(xí)筆記 --(6)RT-Thread線程間通信學(xué)習(xí)過程總結(jié)

    前兩篇文章總結(jié)了RT-Thread多線程以及多線程同步的學(xué)習(xí)過程,關(guān)于前兩篇學(xué)習(xí)總結(jié),可以查看之前的文章。
    發(fā)表于 01-25 18:50 ?7次下載
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> --(6)<b class='flag-5'>RT-Thread</b>線程間通信<b class='flag-5'>學(xué)習(xí)</b>過程總結(jié)

    RT-Thread學(xué)習(xí)筆記分享

    我是從2020年11月初開始學(xué)習(xí)RT-Thread實(shí)時(shí)操作系統(tǒng)的,在學(xué)習(xí)RT-Thread之前,我接觸過uCOS和FreeRTOS,但這兩個(gè)在單片機(jī)上應(yīng)用的實(shí)時(shí)操作系統(tǒng),我都沒有仔細(xì)并
    的頭像 發(fā)表于 01-27 18:52 ?2617次閱讀

    RT-Thread學(xué)習(xí)筆記 RT-Thread的架構(gòu)概述

    RT-Thread 簡介 作為一名 RTOS 的初學(xué)者,也許你對 RT-Thread 還比較陌生。然而,隨著你的深入接觸,你會逐漸發(fā)現(xiàn) RT-Thread 的魅力和它相較于其他同類型 RTOS
    的頭像 發(fā)表于 07-09 11:27 ?5037次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> <b class='flag-5'>RT-Thread</b>的架構(gòu)概述

    RT-Thread學(xué)習(xí)筆記】如何抓取終端的網(wǎng)絡(luò)報(bào)文

    RT-Thread學(xué)習(xí)筆記】如何抓取終端的網(wǎng)絡(luò)報(bào)文?
    的頭像 發(fā)表于 07-30 13:57 ?3456次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】如何抓取終端的網(wǎng)絡(luò)報(bào)文

    RT-Thread學(xué)習(xí)筆記】用memwatch排除內(nèi)存泄露

    RT-Thread學(xué)習(xí)筆記】使用memwatch排除內(nèi)存泄露
    的頭像 發(fā)表于 07-30 14:01 ?2956次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】用memwatch排除內(nèi)存泄露

    基于RT-Thread Studio學(xué)習(xí)

    前期準(zhǔn)備:從官網(wǎng)下載 RT-Thread Studio,弄個(gè)賬號登陸,開啟rt-thread學(xué)習(xí)之旅。
    的頭像 發(fā)表于 05-15 11:00 ?5275次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio<b class='flag-5'>學(xué)習(xí)</b>