2011-09-07 29 views
5

我正在嘗試使用Ant和MSBuild自動化我的項目(包括java和.net)的構建過程。我已經閱讀了他們,並知道如何在Ant和MSBuild中編寫構建腳本。但是我想知道,一般來說編寫構建腳本是否有任何指導原則或最佳實踐?以下是我找到的兩個,但我希望聽到其他開發人員的更多信息。在Ant或MSBuild中編寫構建腳本的任何最佳實踐

  • 在編寫構建腳本,僅僅依賴於位於 源控制和工作文件夾數量有限, 簽出源代碼的項目。不要編寫依賴於源代碼管理中未保留的項目的構建腳本,它們是 。
  • 如果一個項目包含一組子系統,並且每個子系統都有其自己的構建腳本,則該項目的構建文件應該只調用 子系統的構建腳本。此外,這些文件應該導入包含目標,如編譯,測試,封裝等

我見過this post以及共同構建文件,但它是對寫作任務的方式詳細。如上所述,我需要更高層次的指導方針。

下面是我從答案中收集的準則:

  1. 運行間隔建立一個乾淨的環境。這意味着每個構建腳本需要一個clean目標。
  2. 構建腳本通常應包括compile,packagetest目標。
  3. 如果某個產品有不同的開發線(例如dev,release),則它們都應該具有相同的構建腳本。但是,不同的 參數應該傳遞給這些腳本。
  4. 在開發線上執行的構建通常包含編譯, 打包,部署和安裝步驟。但在版本 上構建的產品線包括進一步的步驟,例如標記產品和生成更改日誌/發行說明的 。
  5. 構建腳本也應該保存在源代碼管理中。
  6. 儘量保持所有的構建腳本構建信息,並不 持續集成服務器(竹,TeamCity的,等等)上
  7. 如果您的構建使用參數可能會在未來發生變化(例如 網絡地址複製編譯結果),請不要將其硬編碼爲您的構建腳本中的 。相反,使用構建參數可以很容易地控制它更多 。

回答

4

如果您正在構建VisualStudio應用程序,則最好使用msbuild而不是Ant。 msbuild命令將使用開發人員創建的解決方案文件進行構建,並基本上模擬他們所做的構建。

如果你真的想自動化所有的東西,看看Jenkins。它有一個插件,可以執行msbuild,並且每次有人進行更改時都會自動觸發構建。我使用msbuild和Jenkins的組合。我使用msbuild進行構建,然後使用Ant收集並壓縮所有構建的構件。然後,人們可以直接從Jenkins下載構建的工件。

現在,您的Java應用程序必須使用Ant。我使用以下指導原則

  • 每個構建腳本需要一個clean目標。該目標刪除在構建過程中添加的所有文件,並將工作目錄返回到clean之前的狀態。
  • 我按照使用對象的名字時,Maven的是什麼呢,所以我的目標是像乾淨名字的東西編譯
  • 還遵循Maven指南,我所有的構建文件都放在target目錄中。這樣,我的乾淨的命令可以簡單地做一個<delete dir="${target.dir}/>並清理一切,很好,閃閃發光。
  • 如果我有子項目,每個子項目都有自己的build.xml文件。我的主文件build.xml只是調用所有子項目的文件build.xml
  • 使用Ivy。它很容易設置和易於使用。您不再有將源文件存儲在您的源代碼庫中的問題,或者失去了您所依賴的什麼版本的jar文件。
  • 哎呀,如果可以的話,請使用Maven並完成它。不幸的是,大多數較老的項目比它的價值更難以達到。
  • 使用Jenkins作爲連續構建服務器進行構建。而且,離開部門的所有構建(UAT,QA和保護構建)必須是Jenkins構建。
  • 鼓勵開發人員編寫單元測試。實際上,Jenkins可以執行單元測試並在其構建頁面上顯示其結果。
  • 使用其他的東西,如checkstyle,PMD,CPD,Findbugs和其他代碼驗證產品。當然,詹金斯可以運行其中的每一個,並顯示漂亮的圖表,這些圖表可以用來向您的經理顯示您的工作有多難。
+0

謝謝大衛。您的意見非常有價值。 – hsalimi

1

在MSBuild中,目標應儘可能指定輸入和輸出(以啓用依賴性計算)。如有必要,請使用Returns屬性指定一個返回不同於用於依賴性計算的項目的目標。

給定目標的輸入和輸出項目應使用項目轉換(對於簡單的基於路徑的轉換)或另一個目標(對於更復雜的轉換)來生成。

對於MSBuild 4.x之前版本,對於您在。中定義的目標。目標文件,可以考慮使用以下模式,使消費者正在定義的問題之前注入自己的目標:

<PropertyGroup> 
    <MyTargetDependsOn> 
    Target1; 
    Target2; 
    SomeOtherTarget 
    </MyTargetDependsOn> 
</PropertyGroup> 
<Target 
    Name="MyTarget" 
    DependsOnTargets="$(MyTargetDependsOn)"> 

</Target> 

這使得消費者在指定的目標之前,注入自己的目標,簡單地通過修改MyTargetsDependsOn的價值屬性:

<PropertyGroup> 
    <MyTargetDependsOn> 
    $(MyTargetDependsOn); 
    YetAnotherTarget 
    </MyTargetDependsOn> 
</PropertyGroup> 
<Target 
    Name="YetAnotherTarget"> 

</Target> 

在MSBuild 4.x中,您可以簡單地使用BeforeTargets和AfterTargets屬性。

+0

重要的是,如果可能的話,任務不應返回其輸出項目列表。相反,他們的輸出應該在目標水平上計算,並傳遞給任務(而不是由任務產生)。 – tintoy

+0

非常感謝,但我正在尋求更高層次的指導方針,而不是詳細的指南。 – hsalimi

4

剛上第二個小點評論你上面提到的:

如果一個項目包含一系列的子系統,每個子系統都有 自己的編譯腳本,該項目的生成文件應該只需調用 構建子系統的腳本。

每個子系統應該有它自己的構建文件,但該文件應該導入一個公共構建文件。共同構建文件將包含目標,如編譯,測試,封裝等

http://ant.apache.org/manual/Tasks/import.html

子系統建立文件然後很簡單,不包含重複,只包含特定於該子系統的信息(如compile.classpath)。

+0

非常感謝凱文。這是絕對正確的。 – hsalimi