漸進式專案建置器是一種物件,它以建置器本身定義的方式來操作專案內的 資源。 漸進式專案建置器通常用於應用資源轉換來產生另一種資源或加工品。
外掛程式提供漸進式專案建置器資料給平台,以便實作 private 資源轉換。 例如,平台 SDK 提供的 Java 開發工具(JDT)外掛程式定義一個漸進 式專案建置器,該建置器可於 Java 專案中新增或修改檔案的任何時候,將 Java 原 始檔編譯成類別檔,以及重新編譯受變更影響的其他任何檔案。
平台定義兩種建置類型:
漸進式建置隨資源變更差量起始。此差量反映建置器上次建立專案後所有資源變更的 網路效應。 此差量類似資源變更事件內使用的差量。
建置器最能經由範例來瞭解。Java 開發工具(JDT)提供一個 Java 編譯器(它由 Java 漸進式專案建置器驅動)來重新編譯受變更影響的檔案。 當觸發完整建置時,會編譯專案中所有 .java 檔。任何發現的編譯 問題都會新增為受影響 .java 檔上的問題標示元。當觸發漸進式建置時,建置器會選擇性地重新編譯資源差量中描述的新增、變更或其他受影響的 .java 檔,並在必要時更新問題標示元。任何不再適合的 .class 檔 或標示元都會被除去。
漸進式建置對於具有數以百計或千計資源的專案有顯著的效能優點,大部份資源在將 來任何給定的時間上不會改變。
漸進式建置的技術盤查是正確判定哪些需要重新建置。例如,Java 建置器維護的內 部狀態,包括像報告編譯問題清單及相依關係圖形等事件。此資訊在漸進式建 置期間用來識別為回應 Java 資源變更而需要重新編譯的類別。
雖然建置的基礎結構是在平台中定義,但實際工作是在外掛程式中完成。 實作複雜漸進式建置器的型樣超出本討論範圍,因為實作方式與特定建置器設計有關。
下列其中一種方法可明確地呼叫建置器:
事實上,工作台使用者藉由選取資源導覽器功能表中的對應指令來觸發建置。
自動建置期間,平台也可隱含地呼叫漸進式專案建置器。 若啟用,則每當工作區有變更便會執行自動建置。
org.eclipse.core.resources.builders 延伸點用來提供漸進式專案建置器資料給平台。下列標記顯示假設的外掛程 式 com.example.builders 如何提供漸進式專案建置器資料。
<extension id="mybuilder" name="My Sample Builder" point="org.eclipse.core.resources.builders"> <builder <run class="com.example.builders.BuilderExample"> <parameter name="optimize" value="true" /> <parameter name="comment" value="Builder comment" /> </run> </builder> </extension>
延伸點中識別的類別必須延伸平台類別 IncrementalProjectBuilder。
public class BuilderExample extends IncrementalProjectBuilder { IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { // 在此處新增建置邏輯 return null; } protected void startupOnInitialize() { // 在此處新增建置器 init 邏輯 } }
以 build() 方法起始的建置處理程序,它包括所要求建置種類 FULL_BUILD、INCREMENTAL_BUILD 或 AUTO_BUILD 的相關資 訊。如果所要求的是漸進式建置,便會提供資源差量來說明上次建置後專案資源的變 更。 下列片段進一步修正 build() 方法。
protected IProject[] build(int kind, Map args, IProgressMonitor monitor throws CoreException { if (kind == IncrementalProjectBuilder.FULL_BUILD) { fullBuild(monitor); } else { IResourceDelta delta = getDelta(getProject()); if (delta == null) { fullBuild(monitor); } else { incrementalBuild(delta, monitor); } } return null; }
有時在建置專案 "X"、建置器需要其他某個專案 "Y" 變更 的相關資訊時會發生這個修正。(例如,如果 X 中的 Java 類別實作 Y 中提 供的介面。)當建置 X 時,呼叫 getDelta(Y) 可取得 Y 的差量。 為確保平台可提供這種差量,X 的建置器必須宣告 X 和 Y 之間的相依關係 ,方法是從上一個 build() 呼叫傳回含有 Y 的陣列。如果建置器沒 有相依關係,則僅傳回空值。有關進一步資訊,請參閱 IncrementalProjectBuilder。
處理完整建置要求所需的邏輯對外掛程式而言是特定的。可能包括造訪專案中每個資 源(如果建置是針對專案觸發),甚或查驗其他專案間是否有相依關係。下 列片段建議如何實作完整建置。
protected void fullBuild(final IProgressMonitor monitor) throws CoreException {try { getProject().accept(new MyBuildVisitor()); } catch (CoreException e) { } }
建置訪客針對特定資源執行建置(然後回答 True 來繼續造訪所有子項資源)。
class MyBuildVisitor implements IResourceVisitor { public boolean visit(IResource res) { //建置指定的資源。 //傳回 True 以繼續造訪子項。 return true; } }
繼續執行造訪處理程序,直到訪遍整個資源樹狀結構為止。
當執行漸進式建置時,您使用資源變更差量代替整個專案。
protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException { // 由訪客完成此工作。 delta.accept(new MyBuildDeltaVisitor()); }
請注意:以漸進式建置而言,建置訪客使用資源差量樹狀結構代替整個資源樹狀結構。
繼續執行造訪處理程序,直到訪遍整個資源差量樹狀結構為止。 變更的特定本質類似說明於實作資源變 更接聽器中的本質。其中一個重要的差異是,對於漸進式專案建置器而言,您是根據特定專案而非整個工作區來使用資源差量。
欲使建置器適用指定的專案,它必須併入專案的建置規格中。 專案的建置規格是建置專案時依序執行的指令清單。每一個指令命名單一漸進式專案 建置器。
下列片段新增建置器為現行建置器清單中第一個建置器。
IProjectDescription desc = project.getDescription();ICommand[] commands = desc.getBuildSpec();boolean found = false; for (int i = 0; i < commands.length; ++i) { if (commands[i].getBuilderName().equals(BUILDER_ID)) { found = true; break; } } if (!found) { //新增建置器到專案中 ICommand command = desc.newCommand(); command.setBuilderName(BUILDER_ID); ICommand[] newCommands = new ICommand[commands.length + 1]; // 在其他建置器之前新增它。 System.arraycopy(commands, 0, newCommands, 1, commands.length); newCommands[0] = command; desc.setBuildSpec(newCommands); project.setDescription(desc, null); }
配置專案的建置器只做一次,通常是在專案建立完成時。