自動生成依賴關係

2021-08-16 00:04:35 字數 1718 閱讀 6189

值得思考的問題:目標檔案.o是否只依賴於原始檔.c?編譯器是如何編譯原始檔和標頭檔案的?

解答:預處理器將標頭檔案的**直接插入原始檔,編譯器只通過預處理器的原始檔產生目標檔案。如果規則中以原始檔為依賴,命令可能無法執行。因為在修改**的時候有可能只改動了標頭檔案,原始檔沒有被修改。如果規則中只是以原始檔為依賴目標,makefile裡面某條規則的依賴並不比目標更新,因此命令不同執行,但其實目標所間接依賴的標頭檔案已經被修改,對應的命令應該被執行。這是編譯行為帶來的缺陷。

解決的方法之一:將所有的標頭檔案作為依賴出現於每個目標對應的規則中,這樣標頭檔案被改變之後可以執行規則中的命令。但是,這種方法有缺陷嗎?上面「所有的」三個字被加粗,這裡的解決方案並不好,雖然可以解決問題。因為當任意乙個標頭檔案改動,任何原始檔都將被重新編譯(編譯低效),當專案中標頭檔案數量巨大時,makefile將很難維護

於是有了下面瘋狂的想法:

(1)通過命令自動生成對頭檔案的依賴;

(2)將生成的依賴自動包含進makefile中;

(3)當頭檔案改動後,自動確認需要重新編譯的檔案。

(1)linux命令sed;

(2)編譯器依賴生成選項gcc -mm(gcc -m);

示例**:

test:

echo

"test=>abc+abc=abc" | sed 's:abc:xyz:g'

echo

"main.o : main.c func.h" | sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g'

echo

"/a/b/c/d/main.o : main.c func.h" | sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g'

echo

"/a/b/c/d/main.o : main.c func.h" | sed 's,\(.*\)\.o[ :]*,x/y/z/\1.o : ,g'

echo

"/a/b/c/d/main.o :::: main.c func.h" | sed 's,\(.*\)\.o[ :]*,x/y/z/\1.o : ,g'

# add prefix before .o

gcc -mm -e main.c | sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g'

gcc -m -e main.c | sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g'

(3)小技巧:如果乙個目標是有多個依賴的,那這多個依賴不需要一次性寫出來,可以根據需要拆分成多個。

例子:拆分目標的依賴(將目標的完成依賴拆分為多個部分依賴)

.phony : a b c

test : a b c

@echo "$^"

等價於

.phony : a b c

test : a b

test : b c

test :

@echo "$^"

有了原材料,如何將sed和gcc -mm用於makefile,並自動生成依賴關係?

直接開門見山:需要用到makefile裡的include。

參考:makefile中include的暗黑操作

12 自動生成依賴關係(中)

下面的 有沒有問題?phony all all mkdir test cd test mkdir subtest結果 在當前目錄中生成了 test 和 subtest兩個資料夾,和我們預期的不一樣 makefile 中命令的執行機制 示例改進 phony all all set e mkdir te...

Makefile自動生成標頭檔案依賴

makefile自動生成標頭檔案依賴是很常用的功能,本文的目的是想盡量詳細說明其中的原理和過程。首先給出乙個本人在小專案中常用的makefile模板,支援自動生成標頭檔案依賴。cc gcc cflags wall o includeflags ldflags objs seq.o targets t...

Makefile之自動生成依賴(8)

makefile自動生成標頭檔案依賴是很常用的功能,本文的目的是想盡量詳細說明其中的原理和過程。首先給出乙個本人在小專案中常用的makefile模板,支援自動生成標頭檔案依賴。cc gcc cflags wall o includeflags ldflags objs seq.o targets t...