git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277590 13f79535-47bb-0310-9956-ffa450edef68master
@@ -144,7 +144,7 @@ Other changes: | |||||
* Added <target> nested elements to <ant> and <antcall> to allow | * Added <target> nested elements to <ant> and <antcall> to allow | ||||
specification of multiple sub-build targets, which are executed | specification of multiple sub-build targets, which are executed | ||||
with a single dependency analysis. | with a single dependency analysis. | ||||
* Refactored Target invocation into org.apache.tools.ant.Executor | * Refactored Target invocation into org.apache.tools.ant.Executor | ||||
implementations. Bugzilla Reports 21421, 29248. | implementations. Bugzilla Reports 21421, 29248. | ||||
@@ -203,7 +203,7 @@ Other changes: | |||||
* Added length task to get strings' and files' lengths. | * Added length task to get strings' and files' lengths. | ||||
* <native2ascii> now also supports Kaffe's version. | |||||
* <native2ascii> and <javah> now also support Kaffe's versions. | |||||
* Recursive token expansion in a filterset can now be disabled by | * Recursive token expansion in a filterset can now be disabled by | ||||
setting its recurse attribute to false. | setting its recurse attribute to false. | ||||
@@ -1291,6 +1291,18 @@ Other changes: | |||||
clashes of custom tasks | clashes of custom tasks | ||||
* <java> and <junit> now support <assertions>, which let you enable | |||||
and disable Java1.4 assertions on a package or class basis. These | |||||
only work when fork=true, currently. | |||||
* .NET tasks expanded with VB support <vbc> and J#, via <jsharp>, | |||||
<importtypelib> and <ilasm>. <csc> supports nested <src> types, | |||||
<defines> for (potentially conditional) definitions, <reference> | |||||
filesets for references. The executable attribute lets you switch to | |||||
mono or other implementations -<csc> has been tested with Mono on | |||||
Linux and OSX. | |||||
Changes from Ant 1.5.3 to Ant 1.5.4 | Changes from Ant 1.5.3 to Ant 1.5.4 | ||||
=================================== | =================================== | ||||
@@ -15,6 +15,16 @@ are needed to implement native methods. JNI operates differently depending on | |||||
whether <a href="http://java.sun.com/j2se/1.3/docs/tooldocs/win32/javah.html">JDK1.2</a> | whether <a href="http://java.sun.com/j2se/1.3/docs/tooldocs/win32/javah.html">JDK1.2</a> | ||||
(or later) or <a href="http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/javah.html">pre-JDK1.2</a> | (or later) or <a href="http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/javah.html">pre-JDK1.2</a> | ||||
systems are used.</p> | systems are used.</p> | ||||
<p>It is possible to use different compilers. This can be selected | |||||
with the <code>implementation</code> attribute. <a | |||||
name="implementationvalues">Here are the choices</a>:</p> | |||||
<ul> | |||||
<li>default - the default compiler (kaffeh or sun) for the platform.</li> | |||||
<li>sun (the standard compiler of the JDK)</li> | |||||
<li>kaffeh (the native standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li> | |||||
</ul> | |||||
<h3>Parameters</h3> | <h3>Parameters</h3> | ||||
<table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
<tr> | <tr> | ||||
@@ -74,8 +84,58 @@ systems are used.</p> | |||||
<td valign="top"> location of installed extensions.</td> | <td valign="top"> location of installed extensions.</td> | ||||
<td valign="top" align="center">No</td> | <td valign="top" align="center">No</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">implementation</td> | |||||
<td valign="top">The compiler implementation to use. If this | |||||
attribute is not set, the default compiler for the current VM | |||||
will be used. (See the above <a | |||||
href="#implementationvalues">list</a> of valid compilers.)</td> | |||||
<td align="center" valign="top">No</td> | |||||
</tr> | |||||
</table> | </table> | ||||
<p>Either outputFile or destdir must be supplied, but not both. </p> | <p>Either outputFile or destdir must be supplied, but not both. </p> | ||||
<h3>Parameters specified as nested elements</h3> | |||||
<h4>arg</h4> | |||||
<p>You can specify additional command line arguments for the compiler | |||||
with nested <code><arg></code> elements. These elements are | |||||
specified like <a href="../using.html#arg">Command-line Arguments</a> | |||||
but have an additional attribute that can be used to enable arguments | |||||
only if a given compiler implementation will be used.</p> | |||||
<table border="1" cellpadding="2" cellspacing="0"> | |||||
<tr> | |||||
<td width="12%" valign="top"><b>Attribute</b></td> | |||||
<td width="78%" valign="top"><b>Description</b></td> | |||||
<td width="10%" valign="top"><b>Required</b></td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">value</td> | |||||
<td align="center" rowspan="4">See | |||||
<a href="../using.html#arg">Command-line Arguments</a>.</td> | |||||
<td align="center" rowspan="4">Exactly one of these.</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">line</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">file</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">path</td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">implementation</td> | |||||
<td>Only pass the specified argument if the chosen compiler | |||||
implementation matches the value of this attribute. Legal values | |||||
are the same as those in the above <a | |||||
href="#implementationvalues">list</a> of valid compilers.)</td> | |||||
<td align="center">No</td> | |||||
</tr> | |||||
</table> | |||||
<h3>Examples</h3> | <h3>Examples</h3> | ||||
<pre> <javah destdir="c" class="org.foo.bar.Wibble"/></pre> | <pre> <javah destdir="c" class="org.foo.bar.Wibble"/></pre> | ||||
<p>makes a JNI header of the named class, using the JDK1.2 JNI model. Assuming | <p>makes a JNI header of the named class, using the JDK1.2 JNI model. Assuming | ||||
@@ -110,7 +170,7 @@ writes the corresponding .c stubs. The verbose option will cause Javah to | |||||
describe its progress.</p> | describe its progress.</p> | ||||
<hr> | <hr> | ||||
<p align="center">Copyright © 2001-2002,2004 The Apache Software Foundation. All rights | |||||
<p align="center">Copyright © 2001-2002,2004-2005 The Apache Software Foundation. All rights | |||||
Reserved.</p> | Reserved.</p> | ||||
</body> | </body> | ||||
@@ -0,0 +1,47 @@ | |||||
<?xml version="1.0"?> | |||||
<!-- | |||||
Copyright 2005 The Apache Software Foundation | |||||
Licensed under the Apache License, Version 2.0 (the "License"); | |||||
you may not use this file except in compliance with the License. | |||||
You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
--> | |||||
<project default="no"> | |||||
<property name="out" location="output"/> | |||||
<property name="in" location="input"/> | |||||
<target name="no"> | |||||
<fail>For tests only</fail> | |||||
</target> | |||||
<target name="setUp"> | |||||
<mkdir dir="${out}"/> | |||||
</target> | |||||
<target name="tearDown"> | |||||
<delete dir="${out}"/> | |||||
</target> | |||||
<target name="compile" depends="setUp"> | |||||
<javac srcdir="${in}" destdir="${out}"/> | |||||
</target> | |||||
<target name="simple-compile" depends="compile"> | |||||
<javah destdir="${out}"> | |||||
<class name="org.example.Foo"/> | |||||
<classpath> | |||||
<pathelement location="${out}"/> | |||||
</classpath> | |||||
</javah> | |||||
</target> | |||||
</project> |
@@ -0,0 +1,25 @@ | |||||
/* | |||||
* Copyright 2005 The Apache Software Foundation | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.example; | |||||
public class Foo { | |||||
public Foo() {} | |||||
public native String bar(Object baz); | |||||
} |
@@ -18,18 +18,21 @@ | |||||
package org.apache.tools.ant.taskdefs.optional; | package org.apache.tools.ant.taskdefs.optional; | ||||
import java.io.File; | import java.io.File; | ||||
import java.lang.reflect.Constructor; | |||||
import java.lang.reflect.Method; | |||||
import java.util.ArrayList; | |||||
import java.util.Enumeration; | import java.util.Enumeration; | ||||
import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapter; | |||||
import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapterFactory; | |||||
import org.apache.tools.ant.types.Commandline; | import org.apache.tools.ant.types.Commandline; | ||||
import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
import org.apache.tools.ant.types.Reference; | import org.apache.tools.ant.types.Reference; | ||||
import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
import org.apache.tools.ant.util.facade.FacadeTaskHelper; | |||||
import org.apache.tools.ant.util.facade.ImplementationSpecificArgument; | |||||
/** | /** | ||||
* Generates JNI header files using javah. | * Generates JNI header files using javah. | ||||
@@ -76,6 +79,11 @@ public class Javah extends Task { | |||||
private Path bootclasspath; | private Path bootclasspath; | ||||
//private Path extdirs; | //private Path extdirs; | ||||
private static String lSep = System.getProperty("line.separator"); | private static String lSep = System.getProperty("line.separator"); | ||||
private FacadeTaskHelper facade = null; | |||||
public Javah() { | |||||
facade = new FacadeTaskHelper(JavahAdapterFactory.getDefault()); | |||||
} | |||||
/** | /** | ||||
* the fully-qualified name of the class (or classes, separated by commas). | * the fully-qualified name of the class (or classes, separated by commas). | ||||
@@ -101,7 +109,6 @@ public class Javah extends Task { | |||||
public void setName(String name) { | public void setName(String name) { | ||||
this.name = name; | this.name = name; | ||||
log("ClassArgument.name=" + name); | |||||
} | } | ||||
public String getName() { | public String getName() { | ||||
@@ -109,6 +116,28 @@ public class Javah extends Task { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Names of the classes to process. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public String[] getClasses() { | |||||
ArrayList al = new ArrayList(); | |||||
if (cls != null) { | |||||
StringTokenizer tok = new StringTokenizer(cls, ",", false); | |||||
while (tok.hasMoreTokens()) { | |||||
al.add(tok.nextToken().trim()); | |||||
} | |||||
} | |||||
Enumeration e = classes.elements(); | |||||
while (e.hasMoreElements()) { | |||||
ClassArgument arg = (ClassArgument) e.nextElement(); | |||||
al.add(arg.getName()); | |||||
} | |||||
return (String[]) al.toArray(new String[0]); | |||||
} | |||||
/** | /** | ||||
* Set the destination directory into which the Java source | * Set the destination directory into which the Java source | ||||
* files should be compiled. | * files should be compiled. | ||||
@@ -117,6 +146,15 @@ public class Javah extends Task { | |||||
this.destDir = destDir; | this.destDir = destDir; | ||||
} | } | ||||
/** | |||||
* The destination directory, if any. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public File getDestdir() { | |||||
return destDir; | |||||
} | |||||
/** | /** | ||||
* the classpath to use. | * the classpath to use. | ||||
*/ | */ | ||||
@@ -146,6 +184,15 @@ public class Javah extends Task { | |||||
createClasspath().setRefid(r); | createClasspath().setRefid(r); | ||||
} | } | ||||
/** | |||||
* The classpath to use. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public Path getClasspath() { | |||||
return classpath; | |||||
} | |||||
/** | /** | ||||
* location of bootstrap class files. | * location of bootstrap class files. | ||||
*/ | */ | ||||
@@ -175,27 +222,14 @@ public class Javah extends Task { | |||||
createBootclasspath().setRefid(r); | createBootclasspath().setRefid(r); | ||||
} | } | ||||
///** | |||||
// * Sets the extension directories that will be used during the | |||||
// * compilation. | |||||
// */ | |||||
//public void setExtdirs(Path extdirs) { | |||||
// if (this.extdirs == null) { | |||||
// this.extdirs = extdirs; | |||||
// } else { | |||||
// this.extdirs.append(extdirs); | |||||
// } | |||||
//} | |||||
///** | |||||
// * Maybe creates a nested classpath element. | |||||
// */ | |||||
//public Path createExtdirs() { | |||||
// if (extdirs == null) { | |||||
// extdirs = new Path(project); | |||||
// } | |||||
// return extdirs.createPath(); | |||||
//} | |||||
/** | |||||
* The bootclasspath to use. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public Path getBootclasspath() { | |||||
return bootclasspath; | |||||
} | |||||
/** | /** | ||||
* Concatenates the resulting header or source files for all | * Concatenates the resulting header or source files for all | ||||
@@ -205,6 +239,15 @@ public class Javah extends Task { | |||||
this.outputFile = outputFile; | this.outputFile = outputFile; | ||||
} | } | ||||
/** | |||||
* The destination file, if any. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public File getOutputfile() { | |||||
return outputFile; | |||||
} | |||||
/** | /** | ||||
* If true, output files should always be written (JDK1.2 only). | * If true, output files should always be written (JDK1.2 only). | ||||
*/ | */ | ||||
@@ -212,6 +255,15 @@ public class Javah extends Task { | |||||
this.force = force; | this.force = force; | ||||
} | } | ||||
/** | |||||
* Whether output files should always be written. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public boolean getForce() { | |||||
return force; | |||||
} | |||||
/** | /** | ||||
* If true, specifies that old JDK1.0-style header files should be | * If true, specifies that old JDK1.0-style header files should be | ||||
* generated. | * generated. | ||||
@@ -221,6 +273,15 @@ public class Javah extends Task { | |||||
this.old = old; | this.old = old; | ||||
} | } | ||||
/** | |||||
* Whether old JDK1.0-style header files should be generated. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public boolean getOld() { | |||||
return old; | |||||
} | |||||
/** | /** | ||||
* If true, generate C declarations from the Java object file (used with old). | * If true, generate C declarations from the Java object file (used with old). | ||||
*/ | */ | ||||
@@ -228,6 +289,15 @@ public class Javah extends Task { | |||||
this.stubs = stubs; | this.stubs = stubs; | ||||
} | } | ||||
/** | |||||
* Whether C declarations from the Java object file should be generated. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public boolean getStubs() { | |||||
return stubs; | |||||
} | |||||
/** | /** | ||||
* If true, causes Javah to print a message concerning | * If true, causes Javah to print a message concerning | ||||
* the status of the generated files. | * the status of the generated files. | ||||
@@ -236,6 +306,51 @@ public class Javah extends Task { | |||||
this.verbose = verbose; | this.verbose = verbose; | ||||
} | } | ||||
/** | |||||
* Whether verbose output should get generated. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public boolean getVerbose() { | |||||
return verbose; | |||||
} | |||||
/** | |||||
* Choose the implementation for this particular task. | |||||
* @param impl the name of the implemenation | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public void setImplementation(String impl) { | |||||
if ("default".equals(impl)) { | |||||
facade.setImplementation(JavahAdapterFactory.getDefault()); | |||||
} else { | |||||
facade.setImplementation(impl); | |||||
} | |||||
} | |||||
/** | |||||
* Adds an implementation specific command-line argument. | |||||
* @return a ImplementationSpecificArgument to be configured | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public ImplementationSpecificArgument createArg() { | |||||
ImplementationSpecificArgument arg = | |||||
new ImplementationSpecificArgument(); | |||||
facade.addImplementationArgument(arg); | |||||
return arg; | |||||
} | |||||
/** | |||||
* Returns the (implementation specific) settings given as nested | |||||
* arg elements. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public String[] getCurrentArgs() { | |||||
return facade.getArgs(); | |||||
} | |||||
/** | /** | ||||
* Execute the task | * Execute the task | ||||
* | * | ||||
@@ -271,132 +386,20 @@ public class Javah extends Task { | |||||
classpath = classpath.concatSystemClasspath("ignore"); | classpath = classpath.concatSystemClasspath("ignore"); | ||||
} | } | ||||
/* unused. | |||||
TODO: If anyone cannot come up with a reason for this, lets delete it | |||||
String compiler = getProject().getProperty("build.compiler"); | |||||
if (compiler == null) { | |||||
if (!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1) | |||||
&& !JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2)) { | |||||
compiler = "modern"; | |||||
} else { | |||||
compiler = "classic"; | |||||
} | |||||
JavahAdapter ad = | |||||
JavahAdapterFactory.getAdapter(facade.getImplementation(), | |||||
this); | |||||
if (!ad.compile(this)) { | |||||
throw new BuildException("compilation failed"); | |||||
} | } | ||||
*/ | |||||
doClassicCompile(); | |||||
} | } | ||||
// XXX | |||||
// we need a way to not use the current classpath. | |||||
/** | /** | ||||
* Performs a compile using the classic compiler that shipped with | |||||
* JDK 1.1 and 1.2. | |||||
*/ | |||||
private void doClassicCompile() throws BuildException { | |||||
Commandline cmd = setupJavahCommand(); | |||||
// Use reflection to be able to build on all JDKs | |||||
/* | |||||
// provide the compiler a different message sink - namely our own | |||||
sun.tools.javac.Main compiler = | |||||
new sun.tools.javac.Main(new LogOutputStream(this, Project.MSG_WARN), "javac"); | |||||
if (!compiler.compile(cmd.getArguments())) { | |||||
throw new BuildException("Compile failed"); | |||||
} | |||||
*/ | |||||
try { | |||||
Class javahMainClass = null; | |||||
try { | |||||
// first search for the "old" javah class in 1.4.2 tools.jar | |||||
javahMainClass = Class.forName("com.sun.tools.javah.oldjavah.Main"); | |||||
} catch (ClassNotFoundException cnfe) { | |||||
// assume older than 1.4.2 tools.jar | |||||
javahMainClass = Class.forName("com.sun.tools.javah.Main"); | |||||
} | |||||
// now search for the constructor that takes in String[] arguments. | |||||
Class[] strings = new Class[] {String[].class}; | |||||
Constructor constructor = javahMainClass.getConstructor(strings); | |||||
// construct the javah Main instance | |||||
Object javahMain = constructor.newInstance(new Object[] {cmd.getArguments()}); | |||||
// find the run method | |||||
Method runMethod = javahMainClass.getMethod("run", new Class[0]); | |||||
runMethod.invoke(javahMain, new Object[0]); | |||||
} catch (Exception ex) { | |||||
if (ex instanceof BuildException) { | |||||
throw (BuildException) ex; | |||||
} else { | |||||
throw new BuildException("Error starting javah: " + ex, ex, getLocation()); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Does the command line argument processing common to classic and | |||||
* modern. | |||||
* Logs the compilation parameters, adds the files to compile and logs the | |||||
* "niceSourceList" | |||||
*/ | */ | ||||
private Commandline setupJavahCommand() { | |||||
Commandline cmd = new Commandline(); | |||||
if (destDir != null) { | |||||
cmd.createArgument().setValue("-d"); | |||||
cmd.createArgument().setFile(destDir); | |||||
} | |||||
if (outputFile != null) { | |||||
cmd.createArgument().setValue("-o"); | |||||
cmd.createArgument().setFile(outputFile); | |||||
} | |||||
if (classpath != null) { | |||||
cmd.createArgument().setValue("-classpath"); | |||||
cmd.createArgument().setPath(classpath); | |||||
} | |||||
// JDK1.1 is rather simpler than JDK1.2 | |||||
if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) { | |||||
if (verbose) { | |||||
cmd.createArgument().setValue("-v"); | |||||
} | |||||
} else { | |||||
if (verbose) { | |||||
cmd.createArgument().setValue("-verbose"); | |||||
} | |||||
if (old) { | |||||
cmd.createArgument().setValue("-old"); | |||||
} | |||||
if (force) { | |||||
cmd.createArgument().setValue("-force"); | |||||
} | |||||
} | |||||
if (stubs) { | |||||
if (!old) { | |||||
throw new BuildException("stubs only available in old mode.", getLocation()); | |||||
} | |||||
cmd.createArgument().setValue("-stubs"); | |||||
} | |||||
Path bcp = new Path(getProject()); | |||||
if (bootclasspath != null) { | |||||
bcp.append(bootclasspath); | |||||
} | |||||
bcp = bcp.concatSystemBootClasspath("ignore"); | |||||
if (bcp.size() > 0) { | |||||
cmd.createArgument().setValue("-bootclasspath"); | |||||
cmd.createArgument().setPath(bcp); | |||||
} | |||||
public void logAndAddFiles(Commandline cmd) { | |||||
logAndAddFilesToCompile(cmd); | logAndAddFilesToCompile(cmd); | ||||
return cmd; | |||||
} | } | ||||
/** | /** | ||||
@@ -404,32 +407,18 @@ public class Javah extends Task { | |||||
* "niceSourceList" | * "niceSourceList" | ||||
*/ | */ | ||||
protected void logAndAddFilesToCompile(Commandline cmd) { | protected void logAndAddFilesToCompile(Commandline cmd) { | ||||
int n = 0; | |||||
log("Compilation " + cmd.describeArguments(), | log("Compilation " + cmd.describeArguments(), | ||||
Project.MSG_VERBOSE); | Project.MSG_VERBOSE); | ||||
StringBuffer niceClassList = new StringBuffer(); | StringBuffer niceClassList = new StringBuffer(); | ||||
if (cls != null) { | |||||
StringTokenizer tok = new StringTokenizer(cls, ",", false); | |||||
while (tok.hasMoreTokens()) { | |||||
String aClass = tok.nextToken().trim(); | |||||
cmd.createArgument().setValue(aClass); | |||||
niceClassList.append(" " + aClass + lSep); | |||||
n++; | |||||
} | |||||
} | |||||
Enumeration e = classes.elements(); | |||||
while (e.hasMoreElements()) { | |||||
ClassArgument arg = (ClassArgument) e.nextElement(); | |||||
String aClass = arg.getName(); | |||||
cmd.createArgument().setValue(aClass); | |||||
niceClassList.append(" " + aClass + lSep); | |||||
n++; | |||||
String[] c = getClasses(); | |||||
for (int i = 0; i < c.length; i++) { | |||||
cmd.createArgument().setValue(c[i]); | |||||
niceClassList.append(" " + c[i] + lSep); | |||||
} | } | ||||
StringBuffer prefix = new StringBuffer("Class"); | StringBuffer prefix = new StringBuffer("Class"); | ||||
if (n > 1) { | |||||
if (c.length > 1) { | |||||
prefix.append("es"); | prefix.append("es"); | ||||
} | } | ||||
prefix.append(" to be compiled:"); | prefix.append(" to be compiled:"); | ||||
@@ -123,7 +123,7 @@ public class Native2Ascii extends MatchingTask { | |||||
/** | /** | ||||
* Choose the implementation for this particular task. | * Choose the implementation for this particular task. | ||||
* @param compiler the name of the compiler | |||||
* @param impl the name of the implemenation | |||||
* @since Ant 1.6.3 | * @since Ant 1.6.3 | ||||
*/ | */ | ||||
public void setImplementation(String impl) { | public void setImplementation(String impl) { | ||||
@@ -0,0 +1,34 @@ | |||||
/* | |||||
* Copyright 2005 The Apache Software Foundation | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.optional.javah; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.taskdefs.optional.Javah; | |||||
/** | |||||
* Interface for different backend implementations of the Javah task. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public interface JavahAdapter { | |||||
/** | |||||
* Performs the actual compilation. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
boolean compile(Javah javah) throws BuildException; | |||||
} |
@@ -0,0 +1,96 @@ | |||||
/* | |||||
* Copyright 2005 The Apache Software Foundation | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.optional.javah; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.ProjectComponent; | |||||
import org.apache.tools.ant.util.JavaEnvUtils; | |||||
/** | |||||
* Creates the JavahAdapter based on the user choice and | |||||
* potentially the VM vendor. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public class JavahAdapterFactory { | |||||
/** | |||||
* Determines the default choice of adapter based on the VM | |||||
* vendor. | |||||
* | |||||
* @return the default choice of adapter based on the VM | |||||
* vendor | |||||
*/ | |||||
public static String getDefault() { | |||||
if (JavaEnvUtils.isKaffe()) { | |||||
return Kaffeh.IMPLEMENTATION_NAME; | |||||
} | |||||
return SunJavah.IMPLEMENTATION_NAME; | |||||
} | |||||
/** | |||||
* Creates the JavahAdapter based on the user choice and | |||||
* potentially the VM vendor. | |||||
* | |||||
* @param choice the user choice (if any). | |||||
* @param log a ProjectComponent instance used to access Ant's | |||||
* logging system. | |||||
* @return The adapter to use. | |||||
*/ | |||||
public static JavahAdapter getAdapter(String choice, | |||||
ProjectComponent log) | |||||
throws BuildException { | |||||
if ((JavaEnvUtils.isKaffe() && choice == null) | |||||
|| Kaffeh.IMPLEMENTATION_NAME.equals(choice)) { | |||||
return new Kaffeh(); | |||||
} else if (SunJavah.IMPLEMENTATION_NAME.equals(choice)) { | |||||
return new SunJavah(); | |||||
} else if (choice != null) { | |||||
return resolveClassName(choice); | |||||
} | |||||
// This default has been good enough until Ant 1.6.3, so stick | |||||
// with it | |||||
return new SunJavah(); | |||||
} | |||||
/** | |||||
* Tries to resolve the given classname into a native2ascii adapter. | |||||
* Throws a fit if it can't. | |||||
* | |||||
* @param className The fully qualified classname to be created. | |||||
* @throws BuildException This is the fit that is thrown if className | |||||
* isn't an instance of JavahAdapter. | |||||
*/ | |||||
private static JavahAdapter resolveClassName(String className) | |||||
throws BuildException { | |||||
try { | |||||
Class c = Class.forName(className); | |||||
Object o = c.newInstance(); | |||||
return (JavahAdapter) o; | |||||
} catch (ClassNotFoundException cnfe) { | |||||
throw new BuildException("Can't load " + className, cnfe); | |||||
} catch (ClassCastException cce) { | |||||
throw new BuildException(className | |||||
+ " is not a Javah adapter", cce); | |||||
} catch (Throwable t) { | |||||
// for all other possibilities | |||||
throw new BuildException(className + " caused an interesting " | |||||
+ "exception.", t); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,90 @@ | |||||
/* | |||||
* Copyright 2005 The Apache Software Foundation | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.optional.javah; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.taskdefs.Execute; | |||||
import org.apache.tools.ant.taskdefs.optional.Javah; | |||||
import org.apache.tools.ant.types.Commandline; | |||||
import org.apache.tools.ant.types.Path; | |||||
import org.apache.tools.ant.util.JavaEnvUtils; | |||||
/** | |||||
* Adapter to the native kaffeh compiler. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public class Kaffeh implements JavahAdapter { | |||||
public static final String IMPLEMENTATION_NAME = "kaffeh"; | |||||
/** | |||||
* Performs the actual compilation. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public boolean compile(Javah javah) throws BuildException { | |||||
Commandline cmd = setupKaffehCommand(javah); | |||||
try { | |||||
Execute.runCommand(javah, cmd.getCommandline()); | |||||
return true; | |||||
} catch (BuildException e) { | |||||
if (e.getMessage().indexOf("failed with return code") == -1) { | |||||
throw e; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
private Commandline setupKaffehCommand(Javah javah) { | |||||
Commandline cmd = new Commandline(); | |||||
cmd.setExecutable(JavaEnvUtils.getJdkExecutable("kaffeh")); | |||||
if (javah.getDestdir() != null) { | |||||
cmd.createArgument().setValue("-d"); | |||||
cmd.createArgument().setFile(javah.getDestdir()); | |||||
} | |||||
if (javah.getOutputfile() != null) { | |||||
cmd.createArgument().setValue("-o"); | |||||
cmd.createArgument().setFile(javah.getOutputfile()); | |||||
} | |||||
Path cp = new Path(javah.getProject()); | |||||
if (javah.getBootclasspath() != null) { | |||||
cp.append(javah.getBootclasspath()); | |||||
} | |||||
cp = cp.concatSystemBootClasspath("ignore"); | |||||
if (javah.getClasspath() != null) { | |||||
cp.append(javah.getClasspath()); | |||||
} | |||||
if (cp.size() > 0) { | |||||
cmd.createArgument().setValue("-classpath"); | |||||
cmd.createArgument().setPath(cp); | |||||
} | |||||
if (!javah.getOld()) { | |||||
cmd.createArgument().setValue("-jni"); | |||||
} | |||||
cmd.addArguments(javah.getCurrentArgs()); | |||||
javah.logAndAddFiles(cmd); | |||||
return cmd; | |||||
} | |||||
} |
@@ -0,0 +1,120 @@ | |||||
/* | |||||
* Copyright 2005 The Apache Software Foundation | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.optional.javah; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.taskdefs.ExecuteJava; | |||||
import org.apache.tools.ant.taskdefs.optional.Javah; | |||||
import org.apache.tools.ant.types.Commandline; | |||||
import org.apache.tools.ant.types.Path; | |||||
import org.apache.tools.ant.util.JavaEnvUtils; | |||||
/** | |||||
* Adapter to com.sun.tools.javah.oldjavah.Main or com.sun.tools.javah.Main. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public class SunJavah implements JavahAdapter { | |||||
public static final String IMPLEMENTATION_NAME = "sun"; | |||||
/** | |||||
* Performs the actual compilation. | |||||
* | |||||
* @since Ant 1.6.3 | |||||
*/ | |||||
public boolean compile(Javah javah) throws BuildException { | |||||
Commandline cmd = setupJavahCommand(javah); | |||||
ExecuteJava ej = new ExecuteJava(); | |||||
try { | |||||
try { | |||||
// first search for the "old" javah class in 1.4.2 tools.jar | |||||
Class.forName("com.sun.tools.javah.oldjavah.Main"); | |||||
cmd.setExecutable("com.sun.tools.javah.oldjavah.Main"); | |||||
} catch (ClassNotFoundException cnfe) { | |||||
// assume older than 1.4.2 tools.jar | |||||
Class.forName("com.sun.tools.javah.Main"); | |||||
cmd.setExecutable("com.sun.tools.javah.Main"); | |||||
} | |||||
} catch (ClassNotFoundException ex) { | |||||
throw new BuildException("Can't load javah", ex, | |||||
javah.getLocation()); | |||||
} | |||||
ej.setJavaCommand(cmd); | |||||
return ej.fork(javah) == 0; | |||||
} | |||||
private Commandline setupJavahCommand(Javah javah) { | |||||
Commandline cmd = new Commandline(); | |||||
if (javah.getDestdir() != null) { | |||||
cmd.createArgument().setValue("-d"); | |||||
cmd.createArgument().setFile(javah.getDestdir()); | |||||
} | |||||
if (javah.getOutputfile() != null) { | |||||
cmd.createArgument().setValue("-o"); | |||||
cmd.createArgument().setFile(javah.getOutputfile()); | |||||
} | |||||
if (javah.getClasspath() != null) { | |||||
cmd.createArgument().setValue("-classpath"); | |||||
cmd.createArgument().setPath(javah.getClasspath()); | |||||
} | |||||
// JDK1.1 is rather simpler than JDK1.2 | |||||
if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) { | |||||
if (javah.getVerbose()) { | |||||
cmd.createArgument().setValue("-v"); | |||||
} | |||||
} else { | |||||
if (javah.getVerbose()) { | |||||
cmd.createArgument().setValue("-verbose"); | |||||
} | |||||
if (javah.getOld()) { | |||||
cmd.createArgument().setValue("-old"); | |||||
} | |||||
if (javah.getForce()) { | |||||
cmd.createArgument().setValue("-force"); | |||||
} | |||||
if (javah.getStubs() && !javah.getOld()) { | |||||
throw new BuildException("stubs only available in old mode.", | |||||
javah.getLocation()); | |||||
} | |||||
} | |||||
if (javah.getStubs()) { | |||||
cmd.createArgument().setValue("-stubs"); | |||||
} | |||||
Path bcp = new Path(javah.getProject()); | |||||
if (javah.getBootclasspath() != null) { | |||||
bcp.append(javah.getBootclasspath()); | |||||
} | |||||
bcp = bcp.concatSystemBootClasspath("ignore"); | |||||
if (bcp.size() > 0) { | |||||
cmd.createArgument().setValue("-bootclasspath"); | |||||
cmd.createArgument().setPath(bcp); | |||||
} | |||||
cmd.addArguments(javah.getCurrentArgs()); | |||||
javah.logAndAddFiles(cmd); | |||||
return cmd; | |||||
} | |||||
} |
@@ -0,0 +1,44 @@ | |||||
/* | |||||
* Copyright 2005 The Apache Software Foundation | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs.optional; | |||||
import org.apache.tools.ant.BuildFileTest; | |||||
public class JavahTest extends BuildFileTest { | |||||
private final static String BUILD_XML = | |||||
"src/etc/testcases/taskdefs/optional/javah/build.xml"; | |||||
public JavahTest(String name) { | |||||
super(name); | |||||
} | |||||
public void setUp() { | |||||
configureProject(BUILD_XML); | |||||
} | |||||
public void tearDown() { | |||||
executeTarget("tearDown"); | |||||
} | |||||
public void testSimpleCompile() { | |||||
executeTarget("simple-compile"); | |||||
assertTrue(getProject().resolveFile("output/org_example_Foo.h") | |||||
.exists()); | |||||
} | |||||
} |