[英]Retrieve used header and source file names by parsing Makefile
我想從還包含未使用目標的Makefile中提取所有*.cc
和*.h
文件名。 此處的示例Makefile: https : //gist.github.com/berceanu/7554a9c4371b807e425259c7e99b5de9
我試過運行make -Bnd
並查看已修剪的文件,但我不知道這是否會丟失任何內容。
make -Bnd | grep "Pruning file" | sort | uniq
預期結果:在上述Makefile上make run
的make run
使用的所有*.h
和*.cc
文件的列表。
我建議使用--dry-run --print-data-base
而不是-Bnd
來轉儲目標,目標依賴項,規則,變量等的完整數據庫。
您嘗試從Makefile
提取此信息的方法可能是錯誤的方法。 make
不知道實際使用了哪些頭文件。 make
只知道它的頭文件你已經明確地告訴了make
有關的依賴關系,這是不是很可靠。 Makefile
的信息可能有兩種錯誤。 它可能包含未使用的目標(如您所注意到的)或未使用的頭文件。 它可能會錯過實際上包含但在Makefile
未提及的頭文件。 更糟糕的是,如果頭文件的實際包含取決於宏,如#ifdef XYZ_FEATURE #include "additionalHeaderFile.h" #endif
,該怎么#ifdef XYZ_FEATURE #include "additionalHeaderFile.h" #endif
?
至少有三種方法可以生成所需的列表,即在編譯過程中實際使用的.cc
和.h
文件的列表:
Makefile
) make -n --print-data-base
strace -f make
Makefile
,這非常可靠)將CPPFLAGS:=-MMD
添加到Makefile
,運行make clean
,然后make
,然后使用cat *.d
來獲取列表用於構建run
的所有.cc
和.h
文件。 您甚至可以在不更改Makefile
情況下執行此操作: make clean; make CPPFLAGS:=-MMD && cat *.d | sed -e 's/\\\\//g' -e 's/:/ /g' -e 's/ \\+/\\n/g' | sort -u
make clean; make CPPFLAGS:=-MMD && cat *.d | sed -e 's/\\\\//g' -e 's/:/ /g' -e 's/ \\+/\\n/g' | sort -u
make clean; make CPPFLAGS:=-MMD && cat *.d | sed -e 's/\\\\//g' -e 's/:/ /g' -e 's/ \\+/\\n/g' | sort -u
。 同樣,您在要點中共享的Makefile
也存在很多問題。
all
1 2 3 。 那不需要是二進制文件的名稱,它只是一個.PHONY
目標。 OBJS
或OBJECTS
,而不是OBJ
。 OBJ
這個名稱具有誤導性,因為它是單數形式。 rm
使用$(RM)
表示-f
,因此在文件不存在的情況下也不會造成麻煩。 (作為一個副作用, Makefile
將變得更加可移植,因為並非所有平台都使用rm
刪除文件。) clean
不是文件,因此應該是.PHONY
目標。 clean
的配方應使用::
而不是:
,以便將來在Makefile
較大並拆分為多個文件時,每個文件都可以擁有自己的clean
目標,而不會出現問題。 :=
而不是=
定義。 C++
使用已經定義的CXX
。 C++
/ CXX
,而要使用LDFLAGS
,因為您正在鏈接。 Makefile
中的顯式依賴關系Makefile
維護。 每次添加,刪除或更改項目頭文件的#include
語句時,都必須更新Makefile
,這很容易忘記,而且很痛苦,尤其是當#include
語句位於頭文件中時。 即使進行了盡職調查,這也是無形的合並沖突。 相反,在有明確的相關性Makefile
,你應該使用CPPFLAGS+=-MMD
在你開始Makefile
和追加-include $(wildcard *.d)
在你結束Makefile
,並添加*.d
到文件列表刪除clean
。 然后,您可以從Makefile
刪除所有依賴關系規則(鏈接規則除外)。 run
不是一個好主意。 看到您的Makefile
具有run
目標的用戶可能希望它運行實際程序,而不是鏈接它。 您的實際Makefile
應該如下所示,將二進制文件從run
重命名為program
:
LDFLAGS:=-Wno-deprecated -lm
CPPFLAGS+=-MMD
BINARY:=program
OBJECTS:= \
$(BINARY).o \
binomh.o \
# More objects here
.PHONY: all
all: $(BINARY)
$(BINARY): $(OBJECTS)
.PHONY: clean
clean::
$(RM) \
$(BINARY) \
*.[adios] \
-include $(wildcard *.d)
該Makefile
將與您的Makefile
做“相同”的事情,但是幾乎不需要維護 。 不需要更新依賴項,因為它們是從C預處理器生成的依賴項文件中自動獲取的。 如果將-save-temps
添加到CFLAGS
, CXXFLAGS
或CPPFLAGS
任何一個, *.[adios]
還將刪除創建的文件。
已知此類Makefile
可用於GCC,clang,AOCC(AMD優化C編譯器)和armcc。 它可能也適用於許多其他編譯器和預處理器,尤其是當它們基於或嘗試與GCC或clang / LLVM兼容時。
順便說一句,如果您有興趣,除了經驗之外,還非常有信心地知道這對您有用:我已將您的Makefile
並添加了以下幾行以重現您的源代碼結構。 頭文件只是空文件。 C ++源文件將是從Makefile
的依賴項獲取的#include
語句的列表。
%.cc:
grep '^$*\.o.*:' $(MAKEFILE_LIST) | sed -e 's/.*://' -e 's/.*$*\.cc//' -e 's/ \([^ ]\+\)/#include "\1"\n/g' >$@
%.h:
touch $@
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.