2009-05-24 78 views
8

我們的團隊多年來一直使用Delphi 6,然後在2006年前切換到Delphi 2006。在這兩個版本中,我們遇到以下問題:通常編譯器會抱怨一個被推測爲遞歸使用的單元。這個單位是一個40k LOC單位,是一個項目的核心,擁有近100萬LOC(包括第三方)。不正確的循環參考錯誤

錯誤消息是不正確的:該項目的完整版本始終工作。不幸的是,這個錯誤信息並不能告訴我們所在的循環引用的位置,只是該單元的名稱。有時甚至會發生有效的錯誤消息被列出2-4次,直到該循環引用問題被「找到」。很明顯,編譯器在這裏以一個圓圈運行。由於該項目的大小,很難手動找到問題。因此,我製作了一個工具,其中證明確實沒有循環引用(該工具會創建單元的定向依賴關係圖並確定該圖中的相關性組件 - 除了我故意放置某些內容外,沒有其他功能)。

這不僅影響F9編譯,而且代碼完成/洞察力在大多數時間不工作。有時它工作時,我再次按Ctrl空間...

任何想法我們如何可以隔離甚至解決問題?請注意,將40k LOC單元拆分爲較小的單元將非常困難,因爲它包含大約15個大類,這些大類在接口部分相互依賴(我知道這很糟糕,但應該可以工作)。

更新
我們不斷地重構,但是這是一個艱難的單位重構,因爲一切都依賴於一切,幾乎。一直試圖通過接口繞過它,但我們正在談論一些具有100多種方法和屬性的類。它會更慢。

升級到D2009可能是一個可行的選擇,但現在我們堅持使用D2006(unicode和價格標籤是這裏的兩個瓶塞)。無論如何,如果問題有幫助的話,問題至少從D6開始就存在。

關於修剪使用條款,我們經常用Icarus來做這件事。但目前爲止這並沒有幫助。現在我們在接口部分下降到90個自定義單位。但是,對於真實的循環引用,問題可能出現在任何單元中。還嘗試將所有單位添加到dpr。

該項目與其他項目共享很多代碼,並且有一些IFDEF。但是,定義不是在項目選項中設置的,而是通過常用的包含文件。因此所有模塊應該看到相同的定義。而且,在完全重建之後不久,問題又重新出現,而不切換到另一個項目。

回答

0

您是否有任何其他使用相同代碼庫的項目?如果在不同的編譯器設置或IFDEF下編譯其中的一個,它可能會改變某些DCU中的某些事情,從而導致循環依賴。完整構建重建所有DCU,然後問題消失。

0

嘗試Icarus(免費)來自Peganza。如果沒有告訴你問題是什麼,請嘗試使用他們的Pascal分析儀。

2

看起來很清楚,這是由於背景編譯器和實物之間的細微差別。您可以查看(QualityCentral)該主題的已知內容。另外,由於您沒有明確說明這一點,因此如果可能的話,您應該刪除不必要的單元並將使用語句移到實現中。也許你的工具可以幫助這個。

而只是爲了確保您應該檢查單位別名和路徑設置。

4

我可能會因此而低估。在D2005中,我有一個10k的loc單元(datamodule),它停止了編譯。必須將一些數據集/代碼分離到另一個數據模塊。這10萬個單位是,並且是一團糟。你真的應該考慮重構一些代碼給其他單位。我的模塊自D2005 /分離後變得更糟,但它仍然編譯在D2007中。所以我的答案是a)重構和b)升級到D2009。

2

您認爲完整構建總是成功,但在增量構建失敗後不久出現此錯誤。假設您在IDE中遇到過這種情況,是否嘗試過使用命令行編譯器dcc32來執行增量構建?

如果你不給它提供「-Q」開關(這可能是大多數Makefiles或腳本的命令行版本),它會輸出很多信息按什麼順序編譯它的文件。您可以嘗試在IDE出現錯誤後嘗試執行增量構建,也可以在IDE旁邊打開命令行並使用Alt + Tab進行編譯,從而完全跳過IDE中的編譯。

我簡單地假設你有一種方法來構建使用dcc32,這種或那種方式 - 與我無法想象的項目大小。

+0

對,我們在所有項目(和更多)的完整構建腳本中使用dcc32。我並不期望將其用作IDE編譯的替代品;它不會幫助您瞭解代碼洞察力,以及誰知道當時需要多長時間。 但也許這是一種診斷問題的方法?理想情況下,dcc32增量會遇到同樣的問題,它的輸出會觸發一些想法... – 2009-05-25 18:53:01

+0

是的,這正是我想要建議的,也許我沒有成功通過明確說明:-(抱歉,使用dcc32應該看看哪些文件被編譯了幾次,並且在哪個文件之後它全部停止了。除非IDE編譯器和dcc32真的不一樣,但是這個我不會假設。 – mghie 2009-05-25 20:21:13

2

我們經常遇到類似的問題,並且我們從未處理過(或困擾了很長時間)以找到確切的原因。在按Ctrl-F9時,Delphi選擇編譯單元的順序似乎有問題,這與單元的實際依賴性順序不兼容。

  • 您是否嘗試在按Ctrl-F9之前刪除「MyBigFatUnit.dcu」?
  • 您是否嘗試在您的dpr/dpk文件中重新排列單位聲明,以便單位顯示正確的編譯順序? (即:如果單元B依賴於單元A,則單元A應該首先出現在dpr/dpk中)
0

我們也有這個問題,還有一個相當大的代碼庫。

我們目前正在使用D2009,但在Delphi的所有以前版本中都遇到了這個問題。

它經常發生在從源代碼控制更新後立即發生,所以我懷疑在Delphi構建過程中有一些時間戳問題。

在我們的情況下,如果按Ctrl-F9失敗,並報告了循環引用,第二按Ctrl-F9將一般工作

0

我已被告知,處理,這是在項目中打開另一個任意文件的一種方式,更改該文件並保存,然後再次嘗試運行增量編譯。令人驚訝的是,這通常起作用。

我們有一個4 MLOC項目,這不時出現,這個「解決方案」適合我。

0

我已經打過這個了,以我的經驗,這個錯誤是準合法的。這已經有一段時間了(這個錯誤與版本無關),但是我對這種情況的記憶是它涉及一個循環,其中的一部分循環在實現中。

單元A在實現中使用B.單元B在界面中使用A.如果先編譯B,則它會調用A,但由於B的調用在實現中會成功。如果你先編譯A,它會調用B,B會轉向並在接口中調用A,boom。如果兩個交叉引用都在實現中,這樣的循環只是安全的。

解決方案是設計一些東西,以便在界面中使用最少的東西,並確保在這些單元中沒有任何類似的循環。只要你將你的類型定義與代碼單元分開,這很容易做到。

根據你正在做的事情而出現的錯誤是這個問題的標誌,因爲它涉及到你如何進入循環。當你做一個完整的版本時,訂單是一致的,你可以得到它100%或0%,它不是隨機的。