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()); | |||||
| } | |||||
| } | |||||