11

考虑从源构建 jar 并包含所有非 java 资源的最小 build.xml 片段:

<property name="src.dir" value="src" />

<target name="build">
    <javac destdir="bin">
        <src path="${src.dir}" />
    </javac>
    <copy includeemptydirs="false" todir="bin">
        <fileset dir="${src.dir}">
            <exclude name="**/*.java" />
        </fileset>
    </copy>
    <jar destfile="dist/foo.jar" basedir="bin"/>
</target>

现在想象一下,我需要支持一个源目录列表:

<property name="src.dirs" value="src;src-gen" />

我怎样才能修改上面的脚本来实现它? javac会很高兴地获取目录列表,但为了复制,我需要将字符串转换为带有排除项的文件集列表或找到其他方式。

4

4 回答 4

11

通常,您只需将它们一起列出:

<javac destdir="bin">
    <src path="${src.dir}"/>
    <src path="${src2.dir}"/>
    <src path="${src3.dir}"/>
</javac>

你可以试试这个<sourcepath/>属性。我从未使用过它,但我相信您可以使用它来定义各种源文件的路径,并使用它:

<path id="source.path">
    <pathelement path="${src.dir}"/>
    <pathelement path="${src2.dir}"/>
    <pathelement path="${src4.dir}"/>
</path>

<javac destdir="bin">
    srcpathref="source.path"/>

第一个会起作用,但不能 100% 确定第二个。

于 2013-07-12T16:08:55.303 回答
4

简单的解决方案是只指定多个文件集,就像 javac 任务支持多个“src”属性一样:

   <target name="build" depends="init" description="Create the package">
      <javac destdir="${classes.dir}" includeantruntime="false">
         <src path="src/main1/java"/>
         <src path="src/main2/java"/>
      </javac>

      <copy todir="${classes.dir}" includeemptydirs="false">
         <fileset dir="src/main1" excludes="**/*.java"/>
         <fileset dir="src/main2" excludes="**/*.java"/>
         <flattenmapper/>
      </copy>
   </target>

这当然假设源代码位置的数量是固定的,这不是不合理的期望。

如果你想使用列表属性来驱动它,你必须在你的构建中嵌入一个脚本来处理这个列表(我不能支持 ant-contrib):

<project name="demo" default="build">

   <property name="src.dirs"    value="src/main1,src/main2"/>
   <property name="build.dir"   location="build"/>
   <property name="classes.dir" location="${build.dir}/classes"/>

    <target name="bootstrap">
        <mkdir dir="${user.home}/.ant/lib"/>
        <get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.6/groovy-all-2.1.6.jar"/>
    </target>

   <target name="init">
      <mkdir dir="${classes.dir}"/>
   </target>

   <target name="build" depends="init" description="Create the package">
      <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>

      <groovy>
         def srcDirs = properties["src.dirs"].split(",")

         ant.javac(destdir:properties["classes.dir"], includeantruntime:false) {
            srcDirs.each {
               src(path:"${it}/java")
            }
         }

         ant.copy(todir:properties["classes.dir"], includeemptydirs:false) {
            srcDirs.each {
               fileset(dir:it, excludes:"**/*.java")
            }
            flattenmapper()
         }
      </groovy>
   </target>

   <target name="clean" description="Cleanup build dirs">
      <delete dir="${build.dir}"/>
   </target>

</project>

笔记:

  • 比较“构建”目标。您会注意到 groovy 解决方案以相同的方式调用 ANT。这就是为什么我真的很喜欢 groovy 与 ANT 的集成。
  • 示例还包括一个“引导”目标,用于从Maven Central下载 groovy jar 依赖项。您也可以使用 ivy 来管理构建的依赖项。
于 2013-07-13T09:38:24.273 回答
4

我不确定使用内置 Ant 任务的方法,但您可以使用ant-contrib<for>任务

<path id="src.path">
  <pathelement location="src" />
  <pathelement location="src-gen" />
</path>

<target name="build">
    <javac destdir="bin">
        <src refid="src.path" />
    </javac>
    <for param="dir">
        <path refid="src.path" />
        <sequential>
            <copy includeemptydirs="false" todir="bin">
                <fileset dir="@{dir}">
                    <exclude name="**/*.java" />
                </fileset>
            </copy>
        </sequential>
    </for>
    <jar destfile="dist/foo.jar" basedir="bin"/>
</target>
于 2013-07-12T16:16:25.633 回答
0

一个没有 ant-contrib 任务或嵌入式脚本的简单解决方案:

<property name="src.dirs" value="src,src-gen" />

<path id="src.path">
    <multirootfileset type="dir" basedirs="${src.dirs}"/>
</path>

<target name="build">
    <javac destdir="bin">
        <src refid="src.path"/>
    </javac>
    <copy todir="bin">
        <multirootfileset type="file" basedirs="${src.dirs}">
            <exclude name="**/*.java"/>
        </multirootfileset>
    </copy>
    <jar destfile="dist/foo.jar" basedir="bin"/>
</target>

多根文件集来救援!;-) 需要 Ant 1.9.4 或更高版本。

于 2018-11-30T13:08:51.090 回答