如何在标准Ant的javac任务中条件性指定编译器参数
问题
我编写了如下Ant目标:
<!-- 调用antcall时必须设置的属性: DestinationDir 编译类文件的输出目录。 ReleaseVer 编译目标Java版本(如8、9等),至少为8。 Debug 是否编译调试信息,可选值为'on'或'off'。 --> <target name="java-support-compile" description="编译JavaSupport源码"> <mkdir dir="${DestinationDir}"/> <condition property="ModulesSupported"> <not> <equals arg1="${ReleaseVer}" arg2="8" /> </not> </condition> <!-- 单独编译GSSUtilWrapper,因为引用sun.security.jgss.GSSUtil包时无法使用'release'选项, 且当${ReleaseVer} > 9时需添加--add-exports选项以访问java.security.jgss模块 --> <javac srcdir="${javasupport.src.dir}" source="1.${ReleaseVer}" target="1.${ReleaseVer}" debug="${Debug}" destdir="${DestinationDir}"> <include name="${GSSUtilWrapperFile}"/> <compilerarg if="${ModulesSupported}" line="--add-exports java.security.jgss/sun.security.jgss=ALL-UNNAMED" /> </javac> <javac srcdir="${javasupport.src.dir}" release="${ReleaseVer}" debug="${Debug}" destdir="${DestinationDir}"> <exclude name="${GSSUtilWrapperFile}"/> </javac> </target>
运行时出现错误:compilerarg doesn't support the "if" attribute。我需要该参数具备条件性,因为当传入ReleaseVer=8时,会报错:error: option --add-exports not allowed with target 8。
这个if属性语法来自ant-contrib文档,但它不属于核心Ant,我不想安装额外组件,请问如何在标准Ant中实现该需求?
解决方案
标准Ant里<compilerarg>不支持if属性,可通过以下两种方式实现条件性添加编译参数:
方法1:预设置条件属性(简洁推荐)
通过<condition>生成带参数的属性,再在<compilerarg>中引用该属性——当属性不存在时,参数会被自动忽略:
<!-- 调用antcall时必须设置的属性: DestinationDir 编译类文件的输出目录。 ReleaseVer 编译目标Java版本(如8、9等),至少为8。 Debug 是否编译调试信息,可选值为'on'或'off'。 --> <target name="java-support-compile" description="编译JavaSupport源码"> <mkdir dir="${DestinationDir}"/> <!-- 仅当ReleaseVer≠8时,设置GssExportArg属性 --> <condition property="GssExportArg" value="--add-exports java.security.jgss/sun.security.jgss=ALL-UNNAMED"> <not> <equals arg1="${ReleaseVer}" arg2="8" /> </not> </condition> <!-- 单独编译GSSUtilWrapper --> <javac srcdir="${javasupport.src.dir}" source="1.${ReleaseVer}" target="1.${ReleaseVer}" debug="${Debug}" destdir="${DestinationDir}"> <include name="${GSSUtilWrapperFile}"/> <!-- 属性不存在时,此参数自动跳过 --> <compilerarg line="${GssExportArg}" /> </javac> <!-- 编译剩余源码 --> <javac srcdir="${javasupport.src.dir}" release="${ReleaseVer}" debug="${Debug}" destdir="${DestinationDir}"> <exclude name="${GSSUtilWrapperFile}"/> </javac> </target>
方法2:拆分任务到条件分支(逻辑清晰)
利用Ant核心的<target>条件属性,或1.9.10+版本支持的核心<if>标签,拆分不同Java版本的编译逻辑:
方式A:使用<target>条件属性
<!-- 调用antcall时必须设置的属性: DestinationDir 编译类文件的输出目录。 ReleaseVer 编译目标Java版本(如8、9等),至少为8。 Debug 是否编译调试信息,可选值为'on'或'off'。 --> <target name="java-support-compile" description="编译JavaSupport源码"> <mkdir dir="${DestinationDir}"/> <condition property="ModulesSupported"> <not> <equals arg1="${ReleaseVer}" arg2="8" /> </not> </condition> <!-- Java 8专属编译任务 --> <target name="compile-gssutil-java8" unless="ModulesSupported"> <javac srcdir="${javasupport.src.dir}" source="1.8" target="1.8" debug="${Debug}" destdir="${DestinationDir}"> <include name="${GSSUtilWrapperFile}"/> </javac> </target> <!-- Java 9+专属编译任务 --> <target name="compile-gssutil-java9+" if="ModulesSupported"> <javac srcdir="${javasupport.src.dir}" source="1.${ReleaseVer}" target="1.${ReleaseVer}" debug="${Debug}" destdir="${DestinationDir}"> <include name="${GSSUtilWrapperFile}"/> <compilerarg line="--add-exports java.security.jgss/sun.security.jgss=ALL-UNNAMED" /> </javac> </target> <!-- 执行对应版本的编译任务 --> <antcall target="compile-gssutil-java8"/> <antcall target="compile-gssutil-java9+"/> <!-- 编译剩余源码 --> <javac srcdir="${javasupport.src.dir}" release="${ReleaseVer}" debug="${Debug}" destdir="${DestinationDir}"> <exclude name="${GSSUtilWrapperFile}"/> </javac> </target>
方式B:使用核心<if>标签(Ant 1.9.10+)
<!-- 调用antcall时必须设置的属性: DestinationDir 编译类文件的输出目录。 ReleaseVer 编译目标Java版本(如8、9等),至少为8。 Debug 是否编译调试信息,可选值为'on'或'off'。 --> <target name="java-support-compile" description="编译JavaSupport源码"> <mkdir dir="${DestinationDir}"/> <condition property="ModulesSupported"> <not> <equals arg1="${ReleaseVer}" arg2="8" /> </not> </condition> <!-- 按版本分支编译GSSUtilWrapper --> <if> <isset property="ModulesSupported"/> <then> <javac srcdir="${javasupport.src.dir}" source="1.${ReleaseVer}" target="1.${ReleaseVer}" debug="${Debug}" destdir="${DestinationDir}"> <include name="${GSSUtilWrapperFile}"/> <compilerarg line="--add-exports java.security.jgss/sun.security.jgss=ALL-UNNAMED" /> </javac> </then> <else> <javac srcdir="${javasupport.src.dir}" source="1.8" target="1.8" debug="${Debug}" destdir="${DestinationDir}"> <include name="${GSSUtilWrapperFile}"/> </javac> </else> </if> <!-- 编译剩余源码 --> <javac srcdir="${javasupport.src.dir}" release="${ReleaseVer}" debug="${Debug}" destdir="${DestinationDir}"> <exclude name="${GSSUtilWrapperFile}"/> </javac> </target>
内容的提问来源于stack exchange,提问作者Bwmat
相关产品推荐
相关产品推荐

