2015-01-15 38 views
1

我想創建一個特定文件的依賴關係列表。例如:是否有可能爲C++文件生成依賴關係列表?

//a.cpp 
#include "b.h" 
#include <cstdio> 
int main(){printf("%d\n",fn());} 

//b.h 
int fn(); 

//b.cpp 
#include "b.h" 
#include "c.h" 
int fn(){return fn2();} 

//c.h 
inf fn2(); 

//c.cpp 
#include "c.h" 
int fn2(){return 5;} 

對於那些文件一個取決於b取決於Ç。所以通緝程序的結果應該是:

a: a.o b.o c.o 

是的,它是用於makefile。由於某些原因,我不希望列表中包含目錄中的所有.o文件,因此%.o將不起作用。此外,我所知道的g++ -MMD選項,它幾乎作品我想要的 - 但它僅列出直接依賴關係,在這種情況下:

a.o: a.cpp b.h 

(擴展名是不是一個問題,我可以後置信稍後處理它們)

有沒有簡單的方法來生成這樣的列表?

+0

我想你可以按任何順序列出'o'文件嗎? –

+1

'-MD'做你想要的嗎? '-MMD'不包含系統頭文件。 – Wintermute

+0

@MooingDuck是的,我可以。但我不想手動輸入它們,而-MMD選項不會給出*遞歸*依賴關係,只是直接的。 – akrasuski1

回答

4

似乎你還在說this ...要了解的第一件事是,對象文件其他目標文件依賴。依賴關係列出哪些文件是構建某些東西所必需的。要創建一個目標文件,你需要一些源文件和它正在使用的頭文件。這是正好標誌給你的信息變化的-MD標誌。

如果您想確定構建可執行文件需要哪些目標文件,您需要不同的東西:您需要在目標文件之間創建一個依賴關係圖,然後創建一個從具有入口點的節點開始的圖搜索(即,main()函數)。要做到這一點的工具是nm,它打印對象文件的對象文件的符號信息和tsort,但它只是提供了一個拓撲順序而不是連接的組件。但是,您可以使用相同的信息tsort用於完成其工作。

nm程序只是傾倒出對象文件中定義或引用的所有符號。您將使用具有大寫字母的所有符號來指示對象文件(即節點)提供此符號(如果它不同於'U')或需要該符號(即字符爲'U'),則該對象文件即節點。符號的確切含義(例如'T'代表「文本」,即程序代碼)除'U'之外無關緊要,意思是「未定義」,其他所有內容都是定義(因爲'W'可能會引起一些爭議,因爲這些是「弱」符號,並且多個翻譯單元可能具有它們)。如果一個節點具有未定義的符號而另一個具有已定義的符號,則可以連接兩個節點。

構建圖形之後,您將使用定義爲​​的節點作爲開始節點並搜索可到達圖形。所有到達的目標文件(節點)都需要構建相應的程序。這是算法描述。實際實現可能不同,實際上更簡單:

  1. 使用tsort將目標文件轉換爲適當的相關性順序。如果有周期,請將其移除。
  2. 從包含main()的目標文件開始,並將其記錄爲依賴項。
  3. 記錄所有已定義和未定義的符號。
  4. 刪除每個未定義的符號,其中有一個定義的符號。
  5. 如果沒有未定義的符號:完成。
  6. 打開下一個目標文件。如果不再有錯誤(您有一個循環,並且需要重新處理涉及該循環的雙連通組件上的所有對象文件)
  7. 查看是否存在未定義符號的任何已定義符號如果不是,轉到6.
  8. 記錄目標文件作爲依賴。
  9. 轉到3.

比連接我不知道任何工具的這樣做。又,原因是改變任何目標文件都可以改變依賴關係,你需要重新評估每個程序的依賴關係。順便提一句,這是一個鏈接器。

也許你會得到更好的幫助,如果你說明你的實際目標是什麼,而不是問預想的解決方案的方面。

+0

所以,基本上寫一個鏈接器:) –

+0

是的,這是上一個問題的下一部分。我接受了你的答案,但現在我注意到它與原始答案類似的缺陷 - 有關詳細信息,請參閱其他問題。目標與以前相同 - 創建一個通用makefile,唯一要更改的是具有main函數的文件的名稱,當且僅當需要時才編譯它。 我知道的唯一方法是以某種方式生成創建exec所需的對象文件列表。 現在,我想我可能會誤解這個過程中的冗長操作:鏈接,編譯還是兩者兼而有之。 – akrasuski1

+0

如果鏈接比編譯目標文件簡單快捷,那麼我從一開始就錯了,原來的解決方案是可以接受的。 – akrasuski1

相關問題