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 | |||
specification of multiple sub-build targets, which are executed | |||
with a single dependency analysis. | |||
* Refactored Target invocation into org.apache.tools.ant.Executor | |||
implementations. Bugzilla Reports 21421, 29248. | |||
@@ -203,7 +203,7 @@ Other changes: | |||
* 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 | |||
setting its recurse attribute to false. | |||
@@ -1291,6 +1291,18 @@ Other changes: | |||
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 | |||
=================================== | |||
@@ -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> | |||
(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> | |||
<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> | |||
<table border="1" cellpadding="2" cellspacing="0"> | |||
<tr> | |||
@@ -74,8 +84,58 @@ systems are used.</p> | |||
<td valign="top"> location of installed extensions.</td> | |||
<td valign="top" align="center">No</td> | |||
</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> | |||
<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> | |||
<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 | |||
@@ -110,7 +170,7 @@ writes the corresponding .c stubs. The verbose option will cause Javah to | |||
describe its progress.</p> | |||
<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> | |||
</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; | |||
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.StringTokenizer; | |||
import java.util.Vector; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
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.Path; | |||
import org.apache.tools.ant.types.Reference; | |||
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. | |||
@@ -76,6 +79,11 @@ public class Javah extends Task { | |||
private Path bootclasspath; | |||
//private Path extdirs; | |||
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). | |||
@@ -101,7 +109,6 @@ public class Javah extends Task { | |||
public void setName(String name) { | |||
this.name = name; | |||
log("ClassArgument.name=" + name); | |||
} | |||
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 | |||
* files should be compiled. | |||
@@ -117,6 +146,15 @@ public class Javah extends Task { | |||
this.destDir = destDir; | |||
} | |||
/** | |||
* The destination directory, if any. | |||
* | |||
* @since Ant 1.6.3 | |||
*/ | |||
public File getDestdir() { | |||
return destDir; | |||
} | |||
/** | |||
* the classpath to use. | |||
*/ | |||
@@ -146,6 +184,15 @@ public class Javah extends Task { | |||
createClasspath().setRefid(r); | |||
} | |||
/** | |||
* The classpath to use. | |||
* | |||
* @since Ant 1.6.3 | |||
*/ | |||
public Path getClasspath() { | |||
return classpath; | |||
} | |||
/** | |||
* location of bootstrap class files. | |||
*/ | |||
@@ -175,27 +222,14 @@ public class Javah extends Task { | |||
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 | |||
@@ -205,6 +239,15 @@ public class Javah extends Task { | |||
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). | |||
*/ | |||
@@ -212,6 +255,15 @@ public class Javah extends Task { | |||
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 | |||
* generated. | |||
@@ -221,6 +273,15 @@ public class Javah extends Task { | |||
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). | |||
*/ | |||
@@ -228,6 +289,15 @@ public class Javah extends Task { | |||
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 | |||
* the status of the generated files. | |||
@@ -236,6 +306,51 @@ public class Javah extends Task { | |||
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 | |||
* | |||
@@ -271,132 +386,20 @@ public class Javah extends Task { | |||
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); | |||
return cmd; | |||
} | |||
/** | |||
@@ -404,32 +407,18 @@ public class Javah extends Task { | |||
* "niceSourceList" | |||
*/ | |||
protected void logAndAddFilesToCompile(Commandline cmd) { | |||
int n = 0; | |||
log("Compilation " + cmd.describeArguments(), | |||
Project.MSG_VERBOSE); | |||
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"); | |||
if (n > 1) { | |||
if (c.length > 1) { | |||
prefix.append("es"); | |||
} | |||
prefix.append(" to be compiled:"); | |||
@@ -123,7 +123,7 @@ public class Native2Ascii extends MatchingTask { | |||
/** | |||
* 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 | |||
*/ | |||
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()); | |||
} | |||
} |