5

Antで構築しているクライアントとサーバーがあります。クライアントは、ビルドする前に最初にビルドされるサーバーに依存します。クライアントにバンドルされているサーバーearファイルを除いて、必要なすべてのライブラリがあります。

3つのantファイル、、、を作成build.xmlbuild-client.xmlましbuild-server.xmlた。(ファイル名のいずれかをクリックすると、それらが表示されます)ファイルbuild-client.xmlとは、それらからターゲットを実行できるようにbuild-server.xml含まれています。build.xml

私が抱えている問題は、basedir変数がビルドファイルからビルドファイルに変わることです。したがって、basedir変数build-client.xmlからターゲットを実行すると、は相対的です。build.xmlbuild.xml

Antスクリプト内でbasedir変数を複数回変更するにはどうすればよいですか?

また、これらのビルドファイルを見ると、私がやろうとしていることを実行するためのより良い方法がわかりますか?今のところ、最終的なバンドルイヤーを作成するには、クライアント戦争とサーバーイヤーの両方を同じ場所に配置する必要があると考えています。これらのスクリプトは不必要に複雑に見えるため、これに関する私の考えには欠陥がある可能性があります。

4

3 に答える 3

5

タスクのantドキュメントには、<import>これを実現する方法に関する情報が記載されています。

インポートされたファイルに対するファイルの解決

importing.xmlというメインのビルドファイルが、ファイルシステム上の任意の場所にあるビルドファイルimported.xmlをインポートし、imported.xmlがimported.propertiesから一連のプロパティを読み取るとします。

<!-- importing.xml -->
<project name="importing" basedir="." default="...">
  <import file="${path_to_imported}/imported.xml"/>
</project>

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

ただし、このスニペットは、imported.xmlのofがAntによって無視されるbasedirため、importing.xmlのofに対してimported.propertiesを解決します。basedirimported.propertiesを使用する正しい方法は次のとおりです。

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

上で説明したよう${ant.file.imported}に、importedというプロジェクトを定義するビルドスクリプトのパスを格納し(つまり、imported.xmlへのパスを格納します)、<dirname>そのディレクトリを取得します。この手法により、imported.xmlをスタンドアロンファイルとして使用することもできます(他のプロジェクトにインポートする必要はありません)。

${basedir}基本的に、プロジェクトタグで変数や属性を実際に使用することはできませんbasedir="./../GrahamsProjClient"が、代わりに次のように作成できます。

<!-- build-client.xml -->
<project name="GPClient" default="dist" >

  <dirname property="client.root.dir" file="${ant.file.GPClient}"/>
  <property name="real.basedir" value="${client.root.dir}/../GrahamsProjClient"/>

  <!-- Then from then on, replace ${basedir} with ${real.basedir} -->
  ...
</project>

build-server.xmlについても同じことができます。注意すべきことは、プロジェクト名がの${ant.file.[project name]}file属性に含まれていることだけです<dirname />

于 2012-10-10T00:58:32.053 に答える
3

私の通常のルールは、依存関係のチェックを壊すため、通常のビルドプロセスでは使用し<ant>ないことです。<subant>開発者にbuild.xmlを7つの別々のビルドファイルに分割してもらいまし<ant>た。他のビルドファイルで何かを行うためにタスクが絶えず呼び出されていたため、彼は同じターゲットを最大14回実行していました。そして、なぜ彼は自分のビルドにそれほど時間がかかるのか疑問に思いました。7つのビルドファイルをつなぎ合わせて1つに戻し、ビルドを2分未満に短縮するというパラメーターをbuild.xml使用します。depends<target>

ただし、この場合にあるのは、実際には2つの別個のプロジェクトであり、1つbuild.xmlはこれら2つの別個のプロジェクトを呼び出すために使用しています。この場合、とを使用する方が。よりも優れて<ant><subant>ます<import>

  • これらの呼び出しはに干渉しません${basedir}
  • これらの呼び出しにより、これらの個別のファイルに含めるプロパティとリソースを指定できます。(考えられる答えはnoneです)。
  • 同じ名前を共有する複数のターゲットに問題はありません。クライアントビルドのコンパイルターゲットは、サーバービルドのターゲットと重複しません_compile_

Subantはより強力ですが、実装が難しいです。Subantを使用すると、build.xmlファイルを検索することができます。ほとんどの場合、使用<ant>は簡単で、必要なことを実行できます。


私が本当にお勧めするのは、依存関係の問題を処理するためにIvyを使用することです。Ivyは、クライアントのサーバー依存関係を処理できるだけでなく、すべてのサードパーティのjar依存関係も処理できます。プロジェクトにjarファイルを保存する必要はもうありません。jarファイルをプロジェクトに保存すると、実際のバージョンと履歴に関する情報が失われます。プロジェクトにが表示commons-io.jarされ、それがどのバージョンであったか、またはそれが公式の `commons-io.jarであるか、開発者の1人が何らかの時点でそれを変更したかどうかさえわかりません。

問題は、Ivyの実装に少し手間がかかることです。NexusArtifactoryArchivaなどのIvyリポジトリマネージャを使用する必要があります。(実際、これらはMavenリポジトリーマネージャーですが、Ivyはそれらと非常にうまく連携します。)

ivy.jar次に、をプロジェクトにインポートし、ファイルがMavenIvyリポジトリサーバーivysettings.xmlを指すようにする必要があります。

バージョン管理システムとしてSubversionを使用する場合は、次の操作を実行できます。

  • ivy.jarを含むIvyプロジェクトと、すべてをセットアップするXMLファイルを作成します。私はあなたが見ることができるGithubに1つ持っています。XMLファイルはと呼ばれivy.tasks.xmlます。
  • 次に、プロジェクトで、を使用svn:externalsしてこのプロジェクトをインポートします。
  • あなたのbuild.xml中で、あなたは2つのことをする必要があります:
    • <project>エンティティにIvy名前空間を追加します。
    • タスクを使用し<import>て、すべてがセットアップされたIvyXMLファイルをインポートします。

利点は、Ivyプロジェクトを変更すると、Ivyと対話するすべてのプロジェクトが自動的に変更されることです。たとえば、IvyサーバーのURLを変更した場合、またはIvyキャッシュディレクトリを再定義する必要がある場合です。

ivy.xmlこれを行うと、依存関係を定義するファイルを作成し、必要なサードパーティのjarを使用<ivy:cachepath>および取得するだけです。<ivy:retrieve>これには、クライアントが必要とするサーバーjarが含まれます。

于 2012-10-10T02:39:11.640 に答える
0

antで気付いたのは、変数を思い通りに変更できないことです。

解決策は、実行したいターゲットごとにコマンドラインからantを実行することでした。そのため、次のようなコマンドラインステートメントを実行する代わりに

ant target1 target2

また

<target name="target1">
   <antcall target="target2">
</target>

代わりに、コマンドラインから順番にターゲット呼び出しを実行する必要がありました ant target1 ant target2

そこで、これらのant呼び出しをpythonスクリプト内に配置することを選択しました。これos.system("");は、コマンドラインステートメントが引用符内にある単純な呼び出しです。bashもこれを行うことができます

これらの変数が同じ名前である場合、これはantが各ターゲットに適切な変数を使用する唯一の方法です。

于 2012-10-09T22:00:54.990 に答える