我正在研究SpiderMonkey項目,這是一個大量的.h和.cpp文件的大型項目。儘管我知道我只更改了一個文件或兩個文件,但每次我對項目進行更改時,都必須運行make
命令並再次編譯整個項目以獲取可執行文件./js
。避免編譯開銷
所以,我的問題是,是否有任何解決方案,以避免編譯所有文件,並只編譯特定的文件,以獲得新的可執行文件./js
文件?
我正在研究SpiderMonkey項目,這是一個大量的.h和.cpp文件的大型項目。儘管我知道我只更改了一個文件或兩個文件,但每次我對項目進行更改時,都必須運行make
命令並再次編譯整個項目以獲取可執行文件./js
。避免編譯開銷
所以,我的問題是,是否有任何解決方案,以避免編譯所有文件,並只編譯特定的文件,以獲得新的可執行文件./js
文件?
make
實用程序的含義爲目標和依賴關係。 目標只有在依賴關係被更改時纔會被重建,否則它被認爲是最新的(有點簡單的解釋)。下面的Makefile會導致目標只能重建,如果有任何目標文件被更改,且僅當源/頭改變目標文件將被重建:
all: target
target: obj1.o obj2.o
$(CC) -o [email protected] $^
obj1.o: obj1.c obj1.h
$(CC) -o [email protected] -c $<
obj2.o: obj2.c obj2.h
$(CC) -o [email protected] -c $<
說了這麼多,你應該檢查項目的Makefile和檢查如果依賴性被正確定義。複雜的構建系統(例如autotools/automake)使用$(CC)-M或-MM來構建源的依賴關係列表。
P.S.檢查你的源代碼/頭文件的日期是否正確,而不是將來 - make
通常會在該情況下發出警告,因爲它無法正確確定依賴性更改。對於在一臺計算機上編輯並在另一臺計算機上編譯的NFS文件,這可能尤其重要。
您可以嘗試只更改cpp文件,而不是h,因爲cpp文件在項目中包含一次。 也可以使用#pragma once指令,一些編譯器加速編譯。然而你可以在你的公司使用IncrediBuild工具。它在有IncrediBuild的所有計算機上分發編譯。
'#pragma once'實際上加快了任何事情,這是自90年代以來一直沒有的城市神話。 – DevSolar
的make
整個想法是重新建立只需要重建項目,按文件的修改日期,並提供給make
依賴信息來判斷的那些部分。
如果你的項目需要很長的重新編譯,有三件事情,可能是罪魁禍首:
可供make
相依性信息是不是最優的,即make
重新編譯不需要重新編譯,因爲文件它認爲沒有依賴關係。這將是所討論的Makefile
的缺陷,即差的Makefile
設計。
有很多依賴關係。實現文件包括很多頭文件,頭文件包括對方等等等等 - 最後你需要做一些小的修改,需要大量的翻譯單元來重新編譯(通常在編輯頭文件時)。這將成爲該項目的一個架構缺陷,只能通過重構來修復。
該項目假定使用預編譯頭。這通常會導致一個非常大的頭文件(或包含大量其他頭文件),然後以預處理的形式存儲。包括這個預處理頭是一個非常便宜的操作,但如果你的設置實際上並不是做這種預處理(但包括原始單片頭),編譯時間可能會飛漲。這將是您的設置不足之處;檢查可用的文檔和您的設置。
哪一個是負責您具體的問題?我說不出來,真的。 (我不知道Spidermonkey的第一件事。)
鑑於SpiderMonkey的一個已建立的項目,大概有一些優秀的開發人員正在研究它,可能makefile基本上是健全的,相對較少的僞造依賴項。如果這不是真的,你可能想查詢SpiderMonkey社區,詢問爲什麼修改某個特定文件觸發重建某個其他文件,或者在代碼級別上查看依賴文件使用的內容(可能通過選擇性地刪除#include
看看什麼時候休息)。
儘管如此,您可能正在修改具有許多真正依賴性的文件,例如許多不同翻譯單元包含(直接或間接)包含的頭文件。如果是這樣的話,那麼在沒有重構代碼的情況下,你可以做的事情相對較少。這些技術可能有助於包括外聯函數定義,前向聲明標題(標準的<iosfwd>
),pImpl習慣用法,使用虛擬接口,並且不會完全模板化(因爲定義需要被客戶端代碼工作)。
你能提供一個具體的例子嗎?沒有人,只能提供模糊的答案,例如「也許你正在修改許多其他文件依賴的文件。」 – cdleary