2

アリの助けが必要です。どうすれば ant を と同じように動作させることができmake -j <n>ますか? 私はJavaを構築しているのではなく、独自言語用の外部コンパイラを呼び出していることに注意してください。

タスク<parallel>(および の類似の属性<for>) はありますが、それらは依存関係をサポートしていないようです。または、これらに依存関係を適用する方法が見つかりませんでした。

ただし、次のようにフォーマットされたプロパティ ファイルで依存関係を利用できます。

fileA=fileB fileC 
fileB=fileC

fileA/B/C は、ターゲット ファイルのベース名です。

現在、ビルドするファイルは約 850 個あります。を使用して、<for>このリスト (依存関係を解決することによって適切に並べ替えられたリスト) をウォークスルーして、コンパイラを呼び出します。を使用するように既にアドバイスされていましたが<sequential>、これは依存関係をブロックに変換することを意味し、そのブロック<sequential>はちょっと悪いです。

ループが依存関係を尊重するよう<for ... parallel="yes">にする方法についてのアイデア、またはこれを解決する方法についての他のアイデアはありますか?

4

1 に答える 1

0

これを実行できるネイティブ Ant はないと思いますが、この例は、Groovy のGParsでサポートされている「データフロー同時実行」モデルの完全に理想的な使用例であるため、スクリプト タスクで何かを実行できます。

<project name="gpars-test">
  <path id="groovy.path">
    <pathelement location="groovy-all-1.8.8.jar" />
    <pathelement location="gpars-0.12.jar" />
  </path>

  <!-- Target to build one file - expects a property "filetobuild"
       containing the name of the file to build -->
  <target name="buildOneFile">
    <echo>Imagine I just built ${filetobuild}...</echo>
  </target>

  <target name="main">
    <script language="groovy" classpathref="groovy.path"><![CDATA[
      import static groovyx.gpars.dataflow.Dataflow.task
      import groovyx.gpars.dataflow.Dataflows

      // load dependencies
      def deps = new Properties()
      new File(basedir, 'dependencies.properties').withInputStream {
        deps.load(it)
      }

      def df = new Dataflows()
      // spawn one "task" per file to be compiled
      deps.each { file, dependencies ->
        task {
          if(dependencies) {
            // wait for dependencies - reading df.something will suspend
            // this task until another task has written the same variable
            dependencies.split(/ /).each { dep ->
              def dummy = df."${dep}"
            }
          }

          // now we know all our dependencies are done, call out to build
          // this one.    
          def compiler = project.createTask('antcall')
          compiler.target = "buildOneFile"
          def prop = compiler.createParam()
          prop.name = "filetobuild"
          prop.value = file
          try {
              compiler.perform()
          } catch(Exception e) {
              // do something
          } finally {
              // we're done - this will release any other tasks that are blocked
              // depending on us
              df."${file}" = "done"
          }
        }
      }

      // now wait for all tasks to complete
      deps.each { file, dependencies ->
        def dummy = df."${file}"
      }
      println "finished"
    ]]></script>
  </target>
</project>

これは、ビルドするすべてのファイルが依存関係ファイルにリストされていることを前提としていることに注意してください。これには、依存関係のないものも含まれます。

fileA=fileB fileC 
fileB=fileC
fileC=

def df = new Dataflows()非依存ファイル名がプロパティにリストされていない場合は、それらをそこに配置するためにさらにいじる必要があります-次の行に沿って何かを追加する必要がある直前に

deps.values().collect().each { depString ->
  depString.split(/ /).each {
    // if we find a fileX that something depends on but which does not
    // itself appear in the deps map, assume it has no dependencies
    if(!deps.containsKey(it)) {
      deps.setProperty(it, "")
    }
  }
}
于 2012-11-29T13:47:52.617 に答える