Makefile中自動生成頭文件依賴


為什么需要自動生成頭文件依賴?

  編譯單個源文件時,需要獲取文件中包含的頭文件的信息,但是一般的Makefile不會在規則中明確寫明文件依賴的頭文件,所以單獨修改頭文件后,不會導致包含頭文件的源文件重新編譯。如果每次手動的添加頭文件依賴,又會非常的繁瑣,所以需要一種自動生成依賴的方法。

 

編譯器中神奇的選項

  • 使用$(CC)中的-M命令就可以完美的解決問題,因為-M選項可以將源文件依賴的所有頭文件,自動解析出來。
  • 例子:在當前路徑下,編輯test.c和test.h文件,test.c如下所示,test.h為空
#include <stdio.h>
#include "test.h"

int main()
{
	return 0;
}
  • 運行命令:gcc -M test.c,輸出如下:
test.o: test.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/sys/cdefs.h \
 /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
 /usr/include/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h \
 /usr/include/bits/types.h /usr/include/bits/typesizes.h \
 /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h \
 /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h test.h  
  • 運行命令:gcc -MM test.c,輸出如下:
test.o: test.c test.h  
  • 結論:gcc -MM 命令可以自動生成源文件對頭文件的依賴關系,且剔除掉庫里面的頭文件

 

解決方法

%.d: %.c
    @set -e; \
    rm -f $@; \
    $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
    sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
    rm -f $@.$$$$
  • set -e : 后續命令只要執行失敗,直接結束全部流程,返回
  • rm -f $@ : 刪除上一次編譯的殘留文件
  • $(CC) -MM $(CPPFLAGS) $< > $@.$$$$ : 將生成的依賴關系輸出到指定的目錄中,其中$$$$表示一個隨機數,防止文件名重復
  • sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@ : ;利用sed命令,將xxx.d添加到規則中的目標里面,形成多目標,如:將 main.o : main.o mian.h 變成main.o main.d : main.o mian.h。目的:頭文件更新后,d文件也需要同步更新
  • rm -f $@.$$$$ : 刪除中間文件

 

提示:上述方法中隱含了,目標相同的多條規則會自動進行合並的機制,所以規則的目標一定要相同,才能使得原來的編譯規則(%.c:%.o)中添加對頭文件的依賴。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM