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> | |||