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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Makefile之自动生成依赖(8)

發布時間:2025/3/15 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Makefile之自动生成依赖(8) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Makefile自動生成頭文件依賴是很常用的功能,本文的目的是想盡量詳細說明其中的原理和過程。

Makefile模板

首先給出一個本人在小項目中常用的Makefile模板,支持自動生成頭文件依賴。

CC = gcc CFLAGS = -Wall -O INCLUDEFLAGS = LDFLAGS = OBJS = seq.o TARGETS = test_seq .PHONY:all all : $(TARGETS)test_seq:test_seq.o $(OBJS)$(CC) -o $@ $^ $(LDFLAGS)%.o:%.c$(CC) -o $@ -c $< $(CFLAGS) $(INCLUDEFLAGS)%.d:%.c@set -e; rm -f $@; $(CC) -MM $< $(INCLUDEFLAGS) > $@.$$$$; \sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \rm -f $@.$$$$-include $(OBJS:.o=.d).PHONY:clean clean:rm -f $(TARGETS) *.o *.d *.d.*

基礎知識

在進行下一步之前,首先需要了解make的執行步驟:

  • 讀入Makefile
  • 讀入被include的其它Makefile
  • 初始化Makefile中的變量
  • 推導隱晦規則,并分析所有規則
  • 為所有目標創建依賴關系鏈
  • 根據依賴關系,決定哪些目標需要重新生成
  • 執行生成命令
  • 如何動態生成依賴關系?

    從上面make的執行過程中可看出,要動態生成依賴關系,只能利用第2步讀入其它Makefile的機制。那么,我們是否可以先把生成的依賴關系保存到文件,然后再把該文件的內容包含進來?
    答案是Yes! 只要利用include的機制。

    include關鍵字是用于讀入其它Makefile文件。當該文件不存在時,make會尋找是否有生成它的規則,如果有,則執行其生成命令,然后再嘗試讀入。在include前加減號"-"可以上make忽略其產生的錯誤,并不輸出任何錯誤信息。

    即是說,我們需要提供生成規則文件的規則。例如,我們可以這樣動態生成頭文件依賴關系:

    seq.d : seq.c@echo “seq.o seq.d : seq.c seq.h" > $@-include seq.d

    當make執行時,Makefile中的內容將是這樣子(指內存上的數據):

    seq.d : seq.c@echo “seq.o seq.d : seq.c seq.h" > $@seq.o seq.d : seq.c seq.h

    特別注意的是,由于對seq.c和seq.h的修改需要更新seq.d的內容(因為依賴關系可能已變化),因此seq.d也要在依賴關系的目標列表中。

    自動生成頭文件依賴

    基于上面的例子,現在可以開始討論如何自動生成頭文件依賴。

    自動生成依賴關系

    大多數c/c++編譯器提供了-M選項,可自動尋找源文件依賴的頭文件,并生成依賴規則。對于gcc,需要使用-MM選項,否則它會把系統依賴的頭文件也包含進來。例如執行下面一個命令:

    gcc -MM seq.c

    將輸出:

    seq.o : seq.c seq.h

    但我們需要結果是seq.d也要包含在目標列表中,所以還需要對它進行文本處理。因此,上面的例子可改為:

    seq.d : seq.c@set -e; \gcc -MM $< > $@.$$$$; \sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \rm -f $@.$$$$-include seq.d

    生成規則中的執行命令解釋

    第一個命令@set -e。@關鍵字告訴make不輸出該行命令;set -e的作用是,當后面的命令的返回值非0時,立即退出。

    那么為什么要把幾個命令寫在”同一行“(是對于make來說,因為\的作用就是連接行),并用分號隔開每個命令?因為在Makefile這樣做才能使上一個命令作用于下一個命令。這里是想要set -e作用于后面的命令。

    第二個命令gcc -MM $< > $@.$$$$, 作用是根據源文件生成依賴關系,并保存到臨時文件中。內建變量$<的值為第一個依賴文件(那seq.c),$$$$為字符串"$$",由于makefile中所有的$字符都是特殊字符(即使在單引號之中!),要得到普通字符$,需要用$$來轉義; 而$$是shell的特殊變量,它的值為當前進程號;使用進程號為后綴的名稱創建臨時文件,是shell編程常用做法,這樣可保證文件唯一性。

    第三個命令作用是將目標文件加入依賴關系的目錄列表中,并保存到目標文件。關于正則表達式部分就不說了,唯一要注意的是內建變量$*,$*的值為第一個依賴文件去掉后綴的名稱(這里即是seq)。

    第四個命令是將該臨時文件刪除。

    如果把內建變量都替換成其值后,實際內容是這樣子:

    seq.d : seq.c@set -e; \gcc -MM seq.c > seq.d.$$$$; \sed 's,\(seq\)\.o[ :]*,\1.o seq.d : ,g' < seq.d.$$$$ > seq.d; \rm -f seq.d.$$$$-include seq.d

    Makefile的模式匹配

    最后,再把Makefile的模式匹配應用上,就完成自動生成頭文件依賴功能了:

    %.d : %.c@set -e; \gcc -MM $@ > $@.$$$$; \sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \rm -f $@.$$$$-include seq.d

    總結

    以上是生活随笔為你收集整理的Makefile之自动生成依赖(8)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。