2013-12-09 116 views
1

我工作的是一個組,其中我們的測試存儲桶有數百個.c源程序。 .c程序相當小,並且都包含相同的10個.h頭文件。這些.h文件相當大。編譯和鏈接許多.c源程序使用的.h頭文件

每次我們得到一個新的庫文件來鏈接我們的測試程序來測試時,我們運行一個腳本來重新編譯並運行我們的測試桶。問題在於編譯需要相當長的時間,特別是如果環境是虛擬的。

有沒有辦法編譯.h頭文件一次,放入一個單獨的目標文件,並有許多.c源文件鏈接到所述目標文件?我認爲這會加快編譯時間。我願意更改/刪除.c源程序中的所有#include。

任何有關加快編譯時間的建議都非常感謝。

另外,我應該說一個腳本執行makefile PER .c源碼測試程序! makefile不會被告知編譯當前目錄中的所有程序。每個測試程序都被編譯成自己的可執行文件。

+2

頭文件未編譯。它們包含在.c文件中,然後編譯。在大多數情況下,頭文件只包含允許.c文件引用函數,結構體,數據類型等的聲明,而不用在.c文件中定義它們。 –

+0

@master_latch不幸的是,創建頭文件的程序員實際上編寫了數千行的實現代碼。他們並未將其用於申報目的。 .h文件中的代碼是所有.c文件測試程序中使用的共享代碼....所以,聽起來像「預編譯頭文件」可能是一個解決方案。或者可能創建一個包含.h頭文件的虛擬.c文件,然後創建一個對象,然後將所有.c文件鏈接到該文件? – slowmo

+0

哦,我明白了。我沒有意識到預編譯頭文件是一件事 - 但現在我想到了,我記得在MSVS中將它看作是一個選項。很高興有人能夠回答你的問題! –

回答

1

您已經提出了進一步的建議以加快編譯速度。

單程可以使用ccache。基本上,ccache保存目前已編譯的目標文件的緩存,並在識別出再次編譯同一個源文件時返回它們(而不是一遍又一遍地重新編譯)。

使用它應儘可能

  1. 簡單安裝ccache
  2. 前綴您的gcc用的ccache
+0

感謝您的支持!你以前用過這個程序嗎?如果測試程序中的源代碼相同,並且我們鏈接到的庫文件不同,是否需要重新編譯?有時我們沒有任何源代碼更改,需要針對不同的庫文件進行測試。 – slowmo

+0

基本上,如果代碼中有任何更改(.c或.h),它只會重新編譯。如果您僅將.o與不同的.so鏈接在一起,它會重複使用與緩存中相同的.o。 –

1

/立方厘米/克++命令重寫你頭。剝離所有定義並留在標題中。剝離所有實施並放入新的.c。編譯爲庫。鏈接解決方案。在運行時系統上分發庫。

+0

我希望我能。迴歸桶的創造者不會允許這樣做,因爲從花費的時間中獲得的收益並不合理。你的建議絕對是正確的做法。謝謝! – slowmo

+0

@ user3080362哇,這個收穫肯定是值得的。事實證明,創造者不希望你證明他們的做法是錯誤的...... :)我的建議,無論如何做。當你輕鬆地重新使用代碼時,他們將不得不埋頭並感到羞恥。另外,關於頭文件,它們應該不是實現的,因爲頭文件僅用於內容聲明。執行太多會導致濫用和懶惰。 – Xephon

0

如果我理解正確,庫的典型工作方式是使用目標文件(Linux系統上的.so)中的預編譯代碼,同時提供用於項目的頭文件(.h)。

發生什麼是編譯時,#include <library.h>指令發現該標題並將其內容粘貼到正在編譯的源文件中。然後,一旦源文件被編譯,它就會鏈接到預編譯的目標文件。這樣,該庫可以包含在大量的項目中,而不需要每次都從源代碼進行編譯。鏈接到一個庫時唯一必須重新編譯的部分是頭部中相對少量的代碼,這實際上使源代碼可以訪問庫函數和變量。

所有這一切意味着要大幅加快編譯速度,最好的方法是從10個.h文件中取出所有函數,而只在函數頭中留下函數原型。一旦將所有函數都放在單獨的.c源文件中,就可以將它們編譯成目標文件(通常爲-c標誌)。然後,無論何時您需要針對通常使用的10個頭文件編譯新程序,您都可以包含精簡版頭文件,並鏈接到預編譯對象。由於只需編譯.c文件中的新代碼,而不是頭文件中的所有代碼,該過程應該快得多。