compiler attribute rather than the current JDK (falling back to assuming the current JDK if compiler has not been specified). git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272509 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -62,6 +62,9 @@ Changes that could break older environments: | |||
| * If the 'output' attribute of <ant> is set to a simple filename or a | |||
| relative path, the file is created relative to ${basedir}, not ${user.dir}. | |||
| * The default value for build.compiler is now javac1.x with x | |||
| depending on the JDK that is running Ant instead of classic/modern. | |||
| Fixed bugs: | |||
| ----------- | |||
| * A bug existed that prevented generated log files from being deleted as | |||
| @@ -315,31 +315,6 @@ | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Steve + any other help he can get | |||
| </font> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Base compiler command line switches on the selected | |||
| compiler, not the current JDK | |||
| </font> | |||
| </td> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| If you set compiler to javac1.1, massage your | |||
| classpath correctly and set include*runtime to false you | |||
| can invoke jdk 1.1's javac even though you are running on | |||
| a 1.3 VM. Current Ant will use -sourcepath which the | |||
| compiler cannot understand in this sitation. | |||
| </font> | |||
| </td> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Stefan, others welcome | |||
| </font> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| @@ -496,6 +471,27 @@ | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Stefan | |||
| </font> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Base compiler command line switches on the selected | |||
| compiler, not the current JDK | |||
| </font> | |||
| </td> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| | |||
| </font> | |||
| </td> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Stefan | |||
| </font> | |||
| </td> | |||
| </tr> | |||
| </table> | |||
| @@ -70,8 +70,8 @@ attribute are:</p> | |||
| its own).</li> | |||
| </ul> | |||
| </a> | |||
| <p>For JDK 1.1/1.2, <code>classic</code> is the default. | |||
| For JDK 1.3/1.4, <code>modern</code> is the default. | |||
| <p>The default is <code>javac1.x</code> with <code>x</code> depending | |||
| on the JDK version you use while you are running Ant. | |||
| If you wish to use a different compiler interface than those | |||
| supplied, you can write a class that implements the CompilerAdapter interface | |||
| (<code>package org.apache.tools.ant.taskdefs.compilers</code>). Supply the full | |||
| @@ -82,6 +82,14 @@ classname in the <code>build.compiler</code> property or the | |||
| or <code>compiler</code> attribute setting and | |||
| expects a JDK1.1 or higher to be set in <code>JAVA_HOME</code>. | |||
| </p> | |||
| <p>You can also use the <code>compiler</code> attribute to tell Ant | |||
| which JDK version it shall assume when it puts together the command | |||
| line switches - even if you set <code>fork="true"</code>. | |||
| This is useful if you want to run the compiler of JDK 1.1 while you | |||
| current JDK is 1.2+. If you use | |||
| <code>compiler="javac1.1"</code> and (for example) | |||
| <code>depend="true"</code> Ant will use the command line | |||
| switch <code>-depend</code> instead of <code>-Xdepend</code>.</p> | |||
| <p>This task will drop all entries that point to non-existent | |||
| files/directories from the classpath it passes to the compiler.</p> | |||
| <p><strong>Windows Note:</strong>When the modern compiler is used | |||
| @@ -147,9 +147,14 @@ public class Javac extends MatchingTask { | |||
| * Javac task for compilation of Java files. | |||
| */ | |||
| public Javac() { | |||
| if (JavaEnvUtils.getJavaVersion() != JavaEnvUtils.JAVA_1_1 && | |||
| JavaEnvUtils.getJavaVersion() != JavaEnvUtils.JAVA_1_2) { | |||
| facade = new FacadeTaskHelper("modern"); | |||
| if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) { | |||
| facade = new FacadeTaskHelper("javac1.1"); | |||
| } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2)) { | |||
| facade = new FacadeTaskHelper("javac1.2"); | |||
| } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_3)) { | |||
| facade = new FacadeTaskHelper("javac1.3"); | |||
| } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4)) { | |||
| facade = new FacadeTaskHelper("javac1.4"); | |||
| } else { | |||
| facade = new FacadeTaskHelper("classic"); | |||
| } | |||
| @@ -617,11 +622,16 @@ public class Javac extends MatchingTask { | |||
| * @return array of command line arguments, guaranteed to be non-null. | |||
| */ | |||
| public String[] getCurrentCompilerArgs() { | |||
| String chosen = facade.getExplicitChoice(); | |||
| // make sure facade knows about magic properties and fork setting | |||
| getCompiler(); | |||
| return facade.getArgs(); | |||
| facade.setImplementation(getCompiler()); | |||
| try { | |||
| return facade.getArgs(); | |||
| } finally { | |||
| facade.setImplementation(chosen); | |||
| } | |||
| } | |||
| /** | |||
| * Executes the task. | |||
| @@ -712,17 +722,20 @@ public class Javac extends MatchingTask { | |||
| * <p>Defaults to the build.compiler property but can be overriden | |||
| * via the compiler and fork attributes.</p> | |||
| * | |||
| * <p>If fork has been set to true, the result will be extJavac | |||
| * and not classic or java1.2 - no matter what the compiler | |||
| * attribute looks like.</p> | |||
| * | |||
| * @see #getCompilerVersion | |||
| * | |||
| * @since Ant 1.5 | |||
| */ | |||
| public String getCompiler() { | |||
| facade.setMagicValue(getProject().getProperty("build.compiler")); | |||
| String compilerImpl = facade.getImplementation(); | |||
| String compilerImpl = getCompilerVersion(); | |||
| if (fork) { | |||
| if (isJdkCompiler(compilerImpl)) { | |||
| log("Since fork is true, ignoring compiler setting.", | |||
| Project.MSG_WARN); | |||
| facade.setImplementation("extJavac"); | |||
| compilerImpl = "extJavac"; | |||
| } else { | |||
| log("Since compiler setting isn't classic or modern," | |||
| @@ -732,6 +745,24 @@ public class Javac extends MatchingTask { | |||
| return compilerImpl; | |||
| } | |||
| /** | |||
| * The implementation for this particular task. | |||
| * | |||
| * <p>Defaults to the build.compiler property but can be overriden | |||
| * via the compiler attribute.</p> | |||
| * | |||
| * <p>This method does not take the fork attribute into | |||
| * account.</p> | |||
| * | |||
| * @see #getCompiler | |||
| * | |||
| * @since Ant 1.5 | |||
| */ | |||
| public String getCompilerVersion() { | |||
| facade.setMagicValue(getProject().getProperty("build.compiler")); | |||
| return facade.getImplementation(); | |||
| } | |||
| /** | |||
| * Check that all required attributes have been set and nothing | |||
| * silly has been entered. | |||
| @@ -57,11 +57,13 @@ package org.apache.tools.ant.taskdefs.compilers; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.util.JavaEnvUtils; | |||
| /** | |||
| * Creates the necessary compiler adapter, given basic criteria. | |||
| * | |||
| * @author <a href="mailto:jayglanville@home.com">J D Glanville</a> | |||
| * @since Ant 1.3 | |||
| */ | |||
| public class CompilerAdapterFactory { | |||
| @@ -77,11 +79,12 @@ public class CompilerAdapterFactory { | |||
| * <ul><li>jikes = jikes compiler | |||
| * <li>classic, javac1.1, javac1.2 = the standard compiler from JDK | |||
| * 1.1/1.2 | |||
| * <li>modern, javac1.3 = the new compiler of JDK 1.3 | |||
| * <li>modern, javac1.3, javac1.4 = the compiler of JDK 1.3+ | |||
| * <li>jvc, microsoft = the command line compiler from Microsoft's SDK | |||
| * for Java / Visual J++ | |||
| * <li>kjc = the kopi compiler</li> | |||
| * <li>gcj = the gcj compiler from gcc</li> | |||
| * <li>sj, symantec = the Symantec Java compiler</li> | |||
| * <li><i>a fully quallified classname</i> = the name of a compiler | |||
| * adapter | |||
| * </ul> | |||
| @@ -96,8 +99,8 @@ public class CompilerAdapterFactory { | |||
| throws BuildException { | |||
| boolean isClassicCompilerSupported = true; | |||
| //as new versions of java come out, add them to this test | |||
| if (Project.getJavaVersion() == Project.JAVA_1_4) { | |||
| isClassicCompilerSupported = false; | |||
| if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4)) { | |||
| isClassicCompilerSupported = false; | |||
| } | |||
| if (compilerType.equalsIgnoreCase("jikes")) { | |||
| @@ -107,41 +110,44 @@ public class CompilerAdapterFactory { | |||
| return new JavacExternal(); | |||
| } | |||
| if (compilerType.equalsIgnoreCase("classic") || | |||
| compilerType.equalsIgnoreCase("javac1.1") || | |||
| compilerType.equalsIgnoreCase("javac1.2")) { | |||
| compilerType.equalsIgnoreCase("javac1.1") || | |||
| compilerType.equalsIgnoreCase("javac1.2")) { | |||
| if (isClassicCompilerSupported) { | |||
| return new Javac12(); | |||
| } else { | |||
| throw new BuildException("This version of java does " | |||
| + "not support the classic compiler"); | |||
| + "not support the classic " | |||
| + "compiler"); | |||
| } | |||
| } | |||
| //on java<=1.3 the modern falls back to classic if it is not found | |||
| //but on java>=1.4 we just bail out early | |||
| if (compilerType.equalsIgnoreCase("modern") || | |||
| compilerType.equalsIgnoreCase("javac1.3") || | |||
| compilerType.equalsIgnoreCase("javac1.4")) { | |||
| compilerType.equalsIgnoreCase("javac1.3") || | |||
| compilerType.equalsIgnoreCase("javac1.4")) { | |||
| // does the modern compiler exist? | |||
| if (doesModernCompilerExist()) { | |||
| return new Javac13(); | |||
| } else { | |||
| if (isClassicCompilerSupported) { | |||
| task.log("Modern compiler not found - looking for " | |||
| + "classic compiler", Project.MSG_WARN); | |||
| + "classic compiler", Project.MSG_WARN); | |||
| return new Javac12(); | |||
| } else { | |||
| throw new BuildException("Unable to find a javac " | |||
| + "compiler;\n" | |||
| + "com.sun.tools.javac.Main is not on the " | |||
| + "classpath.\n" | |||
| + "Perhaps JAVA_HOME does not point to the JDK"); | |||
| + "compiler;\n" | |||
| + "com.sun.tools.javac.Main " | |||
| + "is not on the " | |||
| + "classpath.\n" | |||
| + "Perhaps JAVA_HOME does not" | |||
| + " point to the JDK"); | |||
| } | |||
| } | |||
| } | |||
| if (compilerType.equalsIgnoreCase("jvc") || | |||
| compilerType.equalsIgnoreCase("microsoft")) { | |||
| compilerType.equalsIgnoreCase("microsoft")) { | |||
| return new Jvc(); | |||
| } | |||
| if (compilerType.equalsIgnoreCase("kjc")) { | |||
| @@ -151,7 +157,7 @@ public class CompilerAdapterFactory { | |||
| return new Gcj(); | |||
| } | |||
| if (compilerType.equalsIgnoreCase("sj") || | |||
| compilerType.equalsIgnoreCase("symantec")) { | |||
| compilerType.equalsIgnoreCase("symantec")) { | |||
| return new Sj(); | |||
| } | |||
| return resolveClassName(compilerType); | |||
| @@ -62,8 +62,8 @@ import org.apache.tools.ant.taskdefs.Execute; | |||
| import org.apache.tools.ant.taskdefs.LogStreamHandler; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.types.Commandline; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.tools.ant.util.JavaEnvUtils; | |||
| import java.io.File; | |||
| import java.io.PrintWriter; | |||
| @@ -211,12 +211,7 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| sourcepath = src; | |||
| } | |||
| // we cannot be using Java 1.0 when forking, so we only have to | |||
| // distinguish between Java 1.1, and Java 1.2 and higher, as Java 1.1 | |||
| // has its own parameter format | |||
| boolean usingJava1_1 | |||
| = Project.getJavaVersion().equals(Project.JAVA_1_1); | |||
| String memoryParameterPrefix = usingJava1_1 ? "-J-" : "-J-X"; | |||
| String memoryParameterPrefix = assumeJava11() ? "-J-" : "-J-X"; | |||
| if (memoryInitialSize != null) { | |||
| if (!attributes.isForkedJavac()) { | |||
| attributes.log("Since fork is false, ignoring " | |||
| @@ -256,7 +251,7 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| // Just add "sourcepath" to classpath ( for JDK1.1 ) | |||
| // as well as "bootclasspath" and "extdirs" | |||
| if (Project.getJavaVersion().startsWith("1.1")) { | |||
| if (assumeJava11()) { | |||
| Path cp = new Path(project); | |||
| /* | |||
| * XXX - This doesn't mix very well with build.systemclasspath, | |||
| @@ -297,10 +292,7 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| cmd.createArgument().setValue(encoding); | |||
| } | |||
| if (debug) { | |||
| if (useDebugLevel | |||
| && Project.getJavaVersion() != Project.JAVA_1_0 | |||
| && Project.getJavaVersion() != Project.JAVA_1_1) { | |||
| if (useDebugLevel && !assumeJava11()) { | |||
| String debugLevel = attributes.getDebugLevel(); | |||
| if (debugLevel != null) { | |||
| cmd.createArgument().setValue("-g:" + debugLevel); | |||
| @@ -310,8 +302,7 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| } else { | |||
| cmd.createArgument().setValue("-g"); | |||
| } | |||
| } else if (Project.getJavaVersion() != Project.JAVA_1_0 && | |||
| Project.getJavaVersion() != Project.JAVA_1_1) { | |||
| } else if (!assumeJava11()) { | |||
| cmd.createArgument().setValue("-g:none"); | |||
| } | |||
| if (optimize) { | |||
| @@ -319,9 +310,9 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| } | |||
| if (depend) { | |||
| if (Project.getJavaVersion().startsWith("1.1")) { | |||
| if (assumeJava11()) { | |||
| cmd.createArgument().setValue("-depend"); | |||
| } else if (Project.getJavaVersion().startsWith("1.2")) { | |||
| } else if (assumeJava12()) { | |||
| cmd.createArgument().setValue("-Xdepend"); | |||
| } else { | |||
| attributes.log("depend attribute is not supported by the " | |||
| @@ -474,5 +465,25 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| cmd.addArguments(getJavac().getCurrentCompilerArgs()); | |||
| } | |||
| /** | |||
| * Shall we assume JDK 1.1 command line switches? | |||
| * @since Ant 1.5 | |||
| */ | |||
| protected boolean assumeJava11() { | |||
| return "javac1.1".equals(attributes.getCompilerVersion()) || | |||
| ("classic".equals(attributes.getCompilerVersion()) | |||
| && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)); | |||
| } | |||
| /** | |||
| * Shall we assume JDK 1.2 command line switches? | |||
| * @since Ant 1.5 | |||
| */ | |||
| protected boolean assumeJava12() { | |||
| return "javac1.2".equals(attributes.getCompilerVersion()) || | |||
| ("classic".equals(attributes.getCompilerVersion()) | |||
| && JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2)); | |||
| } | |||
| } | |||
| @@ -126,6 +126,18 @@ public class JavaEnvUtils { | |||
| return javaVersion; | |||
| } | |||
| /** | |||
| * Compares the current Java version to the passed in String - | |||
| * assumes the argument is one of the constants defined in this | |||
| * class. | |||
| * @return true if the version of Java is the same as the given | |||
| * version. | |||
| * @since Ant 1.5 | |||
| */ | |||
| public static boolean isJavaVersion(String version) { | |||
| return javaVersion == version; | |||
| } | |||
| /** | |||
| * Finds an executable that is part of a JRE installation based on | |||
| * the java.home system property. | |||
| @@ -132,6 +132,13 @@ public class FacadeTaskHelper { | |||
| : defaultValue); | |||
| } | |||
| /** | |||
| * Retrieves the explicit user choice | |||
| */ | |||
| public String getExplicitChoice() { | |||
| return userChoice; | |||
| } | |||
| /** | |||
| * Command line argument. | |||
| */ | |||
| @@ -55,6 +55,11 @@ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter; | |||
| import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory; | |||
| import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter; | |||
| import org.apache.tools.ant.taskdefs.compilers.Javac12; | |||
| import org.apache.tools.ant.taskdefs.compilers.JavacExternal; | |||
| import junit.framework.TestCase; | |||
| @@ -176,12 +181,16 @@ public class JavacTest extends TestCase { | |||
| String compiler = javac.getCompiler(); | |||
| assertNotNull(compiler); | |||
| assertTrue("default value", | |||
| "modern".equals(compiler) || "classic".equals(compiler)); | |||
| "javac1.1".equals(compiler) | |||
| || "javac1.2".equals(compiler) | |||
| || "javac1.3".equals(compiler) | |||
| || "javac1.4".equals(compiler) | |||
| || "classic".equals(compiler)); | |||
| javac.setFork(true); | |||
| compiler = javac.getCompiler(); | |||
| assertNotNull(compiler); | |||
| assertEquals("extJavac", compiler); | |||
| assertNotNull(javac.getCompiler()); | |||
| assertEquals("extJavac", javac.getCompiler()); | |||
| assertEquals(compiler, javac.getCompilerVersion()); | |||
| // check build.compiler provides defaults | |||
| javac = new Javac(); | |||
| @@ -209,4 +218,17 @@ public class JavacTest extends TestCase { | |||
| assertEquals("jvc", compiler); | |||
| } | |||
| public void testCompilerAdapter() { | |||
| javac.setCompiler("javac1.1"); | |||
| javac.setDepend(true); | |||
| CompilerAdapter adapter = | |||
| CompilerAdapterFactory.getCompiler(javac.getCompiler(), javac); | |||
| assertTrue(adapter instanceof Javac12); | |||
| javac.setFork(true); | |||
| adapter = | |||
| CompilerAdapterFactory.getCompiler(javac.getCompiler(), javac); | |||
| assertTrue(adapter instanceof JavacExternal); | |||
| } | |||
| } | |||
| @@ -78,17 +78,6 @@ | |||
| <td>Steve + any other help he can get</td> | |||
| </tr> | |||
| <tr> | |||
| <td>Base compiler command line switches on the selected | |||
| compiler, not the current JDK</td> | |||
| <td>If you set compiler to javac1.1, massage your | |||
| classpath correctly and set include*runtime to false you | |||
| can invoke jdk 1.1's javac even though you are running on | |||
| a 1.3 VM. Current Ant will use -sourcepath which the | |||
| compiler cannot understand in this sitation.</td> | |||
| <td>Stefan, others welcome</td> | |||
| </tr> | |||
| <tr> | |||
| <td>Make javadoc a real directory based task</td> | |||
| <td></td> | |||
| @@ -142,7 +131,12 @@ | |||
| some cases yet (same reason as bug PR 7980)</td> | |||
| <td>Stefan</td> | |||
| </tr> | |||
| <tr> | |||
| <td>Base compiler command line switches on the selected | |||
| compiler, not the current JDK</td> | |||
| <td></td> | |||
| <td>Stefan</td> | |||
| </tr> | |||
| </table> | |||
| </subsection> | |||