包含

自 Apache Ant 1.8.0 起

說明

將另一個建置檔案包含到目前的專案中。

注意此任務極度仰賴 ProjectHelper 實作,且本身並未執行任何工作。如果您已將 Ant 設定為使用非 Ant 預設的 ProjectHelper,此任務可能無法正常運作。

執行時,它會將另一個 Ant 檔案讀取到同一個專案中,並改寫包含的目標 namedepends 清單。這與 Ant 常見問答中說明的實體包含 不同,因為目標名稱會加上包含專案的 nameas 屬性為字首,且不會顯示為檔案包含在包含檔案中。

include 任務只能用作頂層任務。這表示它不能用於目標中。

還有兩個與此任務相關的功能面向,而實體包含無法做到

目標改寫

包含檔案中的任何目標都將重新命名為 prefix.name,其中 name 是原始目標的名稱,而 prefix 是包含檔案中 project 標籤的 as 屬性或 name 屬性的值。

所有包含目標的 depends 屬性都會重新改寫,以便所有目標名稱都加上字首。這使得包含的檔案自給自足。

請注意,字首會巢狀,因此如果建置檔案包含一個字首為 q 的檔案,而包含的檔案又包含另一個字首為 b 的檔案,則最後那個建置檔案的目標將加上 a.b. 字首。

<import> 也會加入字首,但前提是已指定其 as 屬性。

特殊屬性

包含的檔案會視為存在於主建置檔案中。這讓理解變得容易,但會讓它們無法參照相對於其路徑的檔案和資源。因此,對於每個包含的檔案,Ant 會新增一個包含指向包含建置檔案路徑的屬性。有了這個路徑,包含的建置檔案就能保留資源,並能相對於其位置參照這些資源。

因此,如果我包含一個名為 builddocsdocsbuild.xml 檔案,我可以透過 ant.file.builddocs 取得其路徑,類似於主建置檔案的 ant.file 屬性。

請注意,builddocs 不是檔案名稱,而是包含的 project 標籤中存在的 name 屬性。

如果包含的檔案沒有 name 屬性,則不會設定 ant.file.projectname 屬性。

如果您需要知道目前的建置檔案來源是檔案還是 URL,您可以查看屬性 ant.file.type.projectname(使用上述範例中的 ant.file.type.builddocs),其值為 fileurl

針對包含的檔案解析檔案

假設你的主建置檔案稱為 including.xml,包含一個建置檔案 included.xml,位於檔案系統中的任何位置,而 included.xmlincluded.properties 讀取一組屬性

<!-- including.xml -->
<project name="including" basedir="." default="...">
  <include file="${path_to_included}/included.xml"/>
</project>

<!-- included.xml -->
<project name="included" basedir="." default="...">
  <property file="included.properties"/>
</project>

然而,這個片段會針對 including.xmlbasedir 解析 included.properties,因為 Ant 會忽略 included.xmlbasedir。使用 included.properties 的正確方式是

<!-- included.xml -->
<project name="included" basedir="." default="...">
  <dirname property="included.basedir" file="${ant.file.included}"/>
  <property file="${included.basedir}/included.properties"/>
</project>

如上所述,ant.file.included 會儲存定義名為 included 專案的建置指令碼路徑(簡而言之,它會儲存 included.xml 的路徑),而 <dirname> 會取得其目錄。此技術也允許 included.xml 作為獨立檔案使用(不包含在其他專案中)。

上述說明僅適用於實際從檔案(而非 URL)包含的已包含檔案。對於使用相對於已包含檔案的資源從 URL 包含的檔案,你必須使用可以處理非檔案資源的任務。若要建立相對資源,你可以使用類似下列的內容

<loadproperties>
  <url baseUrl="${ant.file.included}"
       relativePath="included.properties"/>
</loadproperties>

參數

屬性 說明 必要
檔案 要包含的檔案。如果這是相對檔案名稱,檔案名稱將相對於包含檔案解析。請注意,這與大多數其他 ant 檔案屬性不同,其中相對檔案相對於 ${basedir} 解析。 是或嵌套資源集合
選用 如果 true,如果檔案不存在,請勿停止建置。 否;預設為 false
指定加在目標名稱之前的字首。 是,如果已包含檔案的 project 標籤未指定 name 屬性(否則會將其視為預設值)
prefixSeparator 指定用於字首和目標名稱之間的分隔符號。 否;預設為 .

指定為嵌套元素的參數

任何 資源 或資源集合

將包含指定的資源。

範例

<include file="../common-targets.xml"/>

包含位於父目錄中的 common-targets.xml 檔案中的目標。

<include file="${deploy-platform}.xml"/>

包含由屬性 deploy-platform 定義的專案

<include>
  <javaresource name="common/targets.xml">
    <classpath location="common.jar"/>
  </javaresource>
</include>

包含位於 jar 檔案 common.jar 內的目錄 common 內的 targets.xml 檔案中的目標。

<import> 與 <include> 有何不同?

簡短版本:如果你打算覆寫目標,請使用 import,否則請使用 include

當使用 import 時,已匯入目標最多可使用兩個名稱:沒有任何字首的「正常」名稱,以及可能帶有字首名稱(as 屬性的值或已匯入專案的 name 屬性(如果有的話))。

當使用 include 時,已包含目標只能以字首形式使用。

當使用 import 時,已匯入目標的 depends 屬性保持不變,即它使用「正常」名稱,並允許你覆寫相依性清單中的目標。

當使用 include 時,包含的目標無法被覆寫,且其 depends 屬性會被改寫,以便使用前綴名稱。這允許包含檔案的撰寫者控制作為相依性的一部分而呼叫的目標。

使用不同的前綴可以 include 同一個檔案多次;無法 import 同一個檔案多次。

範例

nested.xml 應為

<project>
  <target name="setUp">
    <property name="prop" value="in nested"/>
  </target>

  <target name="echo" depends="setUp">
    <echo>prop has the value ${prop}</echo>
  </target>
</project>

在如下的情況中使用 import

<project default="test">
  <target name="setUp">
    <property name="prop" value="in importing"/>
  </target>

  <import file="nested.xml" as="nested"/>

  <target name="test" depends="nested.echo"/>
</project>

執行建置檔案將發出

setUp:

nested.echo:
     [echo] prop has the value in importing

test:

在如下的情況中使用 include

<project default="test">
  <target name="setUp">
    <property name="prop" value="in importing"/>
  </target>

  <include file="nested.xml" as="nested"/>

  <target name="test" depends="nested.echo"/>
</project>

執行目標建置檔案將發出

nested.setUp:

nested.echo:
     [echo] prop has the value in nested

test:

且在包含的建置檔案中不會有任何名為 echo 的目標。