考虑最小的build.xml片段,它从源构建jar并包含所有非java资源:
<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
会愉快地获取目录列表,但是对于副本,我需要将字符串转换为带有排除项的文件集列表,或者找到其他方法。
答案 0 :(得分:8)
通常,您只需将它们全部列在一起:
<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%肯定第二个。
答案 1 :(得分: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>
这当然假设源代码位置的数量是固定的,这是不合理的。
如果你想使用list属性来驱动它,你必须在你的构建中嵌入一个脚本来处理这个列表(我不能认可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>
注意:
答案 2 :(得分:3)
我不确定使用内置Ant任务的方法,但您可以使用ant-contrib <for>
task
<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>
答案 3 :(得分: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>
multirootfileset 来解救! ;-)需要蚂蚁1.9.4或更高版本。