From bd8fc7d5c8f4bf00a3272db3ec0e00096d16eed0 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 9 Nov 2000 16:18:50 +0000 Subject: [PATCH] New tasks csc and ilasm for Microsoft's .NET SDK. Submitted by: Steve Loughran git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268165 13f79535-47bb-0310-9956-ffa450edef68 --- WHATSNEW | 2 +- docs/dotnet.html | 126 +++ docs/index.html | 3 +- .../tools/ant/taskdefs/defaults.properties | 2 + .../ant/taskdefs/optional/dotnet/CSharp.java | 756 ++++++++++++++++++ .../ant/taskdefs/optional/dotnet/Ilasm.java | 510 ++++++++++++ .../taskdefs/optional/dotnet/NetCommand.java | 237 ++++++ 7 files changed, 1634 insertions(+), 2 deletions(-) create mode 100644 docs/dotnet.html create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java diff --git a/WHATSNEW b/WHATSNEW index 8fe4fc7eb..4c13ec83c 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -6,7 +6,7 @@ Other changes: * A GUI Frontend: Antidote -* New tasks: propertyfile, depend, antlr, telnet +* New tasks: propertyfile, depend, antlr, telnet, csc, ilasm * Added output attribute to . diff --git a/docs/dotnet.html b/docs/dotnet.html new file mode 100644 index 000000000..e1a887fdd --- /dev/null +++ b/docs/dotnet.html @@ -0,0 +1,126 @@ + + + .Net classes for Ant + + +

.Net classes for Ant

+ + +Vision: make ant the definative build tool for .net projects, just +as it is becoming for java projects +

+ +

Detail.

+ +The emergent policy in big java projects is 'IDE for code and debug'; +Ant for builds, test and deployment. While IDEs are great for an +individual development task, Ant not only rebuilds everything insanely +fast, it has great support for modern deployment tasks -ftp upload, +EJB servers, SQL commands, all can be done from a relatively simple +XML declaration of what you want done. Also in a large project +(especially open source) there is no means of dictating which IDE to use. +Ant gives IDE independence, cross platform portability and ease of +extensibility. + +

+ +Projects using .net should be able to use the same tool. This will +avoid everyone being dependent on Visual Studio.net (if they have it) +supplemented with makefiles and batch files. Anyone doing mixed java/dotnet +development will be particulary grateful, as they can have a unified build +process. + +

+ +If at sometime in the future bits of .net do appear on different platforms +then ant based build files will migrate -once the ant tasks have been +migrated and any hard codings of DOS-descendant file system conventions +removed from the build.xml files + +

Key .net Tasks

+ +
    +
  1. csc - csharp compiler - *.csc -> output +
  2. ilasm - IL assembler - *.il ->.exe or .dll +
  3. ResX - ResXToResources.exe .resx -> .resources +
  4. al - assembly linker (.dll) -> +
  5. Signcode - .exe + keys -> .exe' +
  6. Resgen - .properties -> .resources +
  7. Type Library Exporter (TlbExp.exe- .dll -> .tlb +
  8. TlbImp.exe Type Library Importer +
  9. RegAsm.exe Assembly Registration Tool .dll -> .reg | registration +
  10. WebServiceUtil -SOAP proxy import, SDL generation tool +
+ +

Ant Wrapper for net tasks

+ +Rarely used .net command line tools can be invoked manually. The key tasks +to address are the common steps in a build process and those which benefit +from the file pattern matching function. + +

+ +The esoteric tasks can then supported on demand by those who need them. +The initial .net tasks should provide a foundation for that demand creation +to be simple. + +

Plan

+ +
    + +
  1. code up C sharp task and distribute for feedback & identify possible +aid +
  2. Add the next task I need (whatever that is) +
  3. Refactor to produce a base class for .net tasks +
  4. Leave it other people write all the other tasks +
+ +

Risks

+
    +
  • +The .net SDK is unstable; the next builds will change the commands, arguments +and behaviours. Probability: 100%. Impact: 2 days. +
  • Portable tasks turn out to be harder than envisaged + (=reworking if/when non Win32 .net build tools appear) + +
+ +
+

Using Ant in .net projects

+ +

+Setup

+ +To use the net tasks one needs +
    + +
  • A win2K box (or any other platform which supports the .net build tools) + +
  • JavaVM - Java1.1 or later + +
  • Ant downloaded and the environment and path variables set up so +that typing 'ant' invokes ant via a batch file. + +
  • An XML parser for ant. The usual distributions include an appropriate +version parser.jar and jaxp.jar. + +
  • the .net tasks archive (dotnettasks.jar) included in the + ant\lib directory + +
  • The .net sdk installed with the binaries on the path. (Test: type CSC) + +
  • A build.xml file to describe the build process +
+ +An example build.xml file is included in the test directory. + +

Task: CSC

+ +This task compiles CSharp source into executables or modules. +Consult the javadoc file for parameter details. +

Task: ilasm

+Task to assemble .il files. +Consult the javadoc file for parameter details. + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 14d4f7ae4..994eb7603 100644 --- a/docs/index.html +++ b/docs/index.html @@ -26,7 +26,7 @@
  • Dave Walend (dwalend@cs.tufts.edu)
  • -

    Version 1.3 - 2000/11/02

    +

    Version 1.3 - 2000/11/10


    Table of Contents

    @@ -4535,6 +4535,7 @@ it had been located at htdocs/manual/ChangeLog.txt.


    Optional tasks

      +
    • .NET tasks
    • Cab
    • FTP
    • JavaCC
    • diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties index ba9e5f9b9..54f8b0be2 100644 --- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties +++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties @@ -71,6 +71,8 @@ vajload=org.apache.tools.ant.taskdefs.optional.ide.VAJLoadProjects vajexport=org.apache.tools.ant.taskdefs.optional.ide.VAJExport vajimport=org.apache.tools.ant.taskdefs.optional.ide.VAJImport telnet=org.apache.tools.ant.taskdefs.optional.net.TelnetTask +csc=org.apache.tools.ant.taskdefs.optional.dotnet.CSharp +ilasm=org.apache.tools.ant.taskdefs.optional.dotnet.Ilasm # deprecated ant tasks (kept for back compatibility) javadoc2=org.apache.tools.ant.taskdefs.Javadoc diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java new file mode 100644 index 000000000..84cbe3f22 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java @@ -0,0 +1,756 @@ +/* -*-Java-*- +******************************************************************* +* +* File: Csharp.java +* RCS: $Header$ +* Author: Steve Loughran +* Created: July 21, 2000 +* Modified: $Modtime: 00-11-01 12:57 $ +* Language: Java +* Status: Experimental +* +*********************************************************************/ + +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/* build notes + +-The reference CD to listen to while editing this file is +nap: Underworld - Everything, Everything +-variable naming policy from Fowler's refactoring book. +-tested against the PDC pre-beta of csc.exe; future versions will +inevitably change things +*/ + +// ==================================================================== +// place in the optional ant tasks package +// but in its own dotnet group +// ==================================================================== + +package org.apache.tools.ant.taskdefs.optional.dotnet; + +// ==================================================================== +// imports +// ==================================================================== + +import org.apache.tools.ant.*; +import org.apache.tools.ant.taskdefs.*; +import org.apache.tools.ant.types.*; +import java.io.*; +import java.util.*; +import java.text.*; + + +// ==================================================================== +/** +This task compiles CSharp source into executables or modules. +The task will only work on win2K until other platforms support csc.exe or +an equivalent. CSC.exe must be on the execute path too. + +

      +All parameters are optional: <csc/> should suffice to produce a debug +build of all *.cs files. References to external files do require explicit +enumeration, so are one of the first attributes to consider adding. + +

      + +The task is a directory based task, so attributes like includes="*.cs" and +excludes="broken.cs" can be used to control the files pulled in. By default, +all *.cs files from the project folder down are included in the command. +When this happens the output file -if not specified- +is taken as the first file in the list, which may be somewhat hard to control. +Specifying the output file with 'outfile' seems prudent. + +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributeDescriptionExample
      additionalModules + Semicolon separated list of modules to refer to +
      defaultexcludesindicates whether default excludes should be used or not + ("yes"/"no"). Default excludes are used when omitted.
      definitions + defined constants + "RELEASE;BETA1" +
      debug + include debug information + "true" or "false" +
      docFile + name of file for documentation + "doc.xml" +
      excludescomma separated list of patterns of files that must be + excluded. No files (except default excludes) are excluded when omitted.
      excludesfilethe name of a file. Each line of this file is + taken to be an exclude pattern
      failOnError + Should a failed compile halt the build? + "true" or "false" +
      includescomma separated list of patterns of files that must be + included. All files are included when omitted.
      includesfilethe name of a file. Each line of this file is + taken to be an include pattern
      incremental + Incremental build flag. Off by default + "false" +
      mainClass + name of main class for executables + com.example.project.entrypoint +
      optimize + optimisation flag + "true" or "false" +
      outputFile + filename of output + "example.exe" +
      references + Semicolon separated list of dlls to refer to +
      srcDir + source directory (default = project directory) + +
      targetType + Type of target + "exe","module","winexe","library" +
      unsafe + enable unsafe code + "true" or "false" +
      warnLevel + level of warning + 1-4 +
      win32Icon + filename of icon to include + +
      + + + +

      +The first pass is just a proof of concept; enough to test. +

      +TODO +

        +
      1. get PATH incorporated into reference/module lookup +
      2. is Win32Icon broken? +
      3. all the missing options +
      +

      +History + + + + + + + + +
      0.2 Slightly different Split command execution to a separate class; +
      0.1 "I can't believe it's so rudimentary" First pass; minimal builds only support; +
      +@version 0.2 +@author Steve Loughran steve_l@iseran.com + + */ +// ==================================================================== + +public class CSharp + extends org.apache.tools.ant.taskdefs.MatchingTask { + + //============================================================================= + /** constructor inits everything and set up the search pattern + */ + + public CSharp () { + Clear(); + setIncludes(csc_file_pattern); + } + + + //----------------------------------------------------------------------------- + /** name of the executable. the .exe suffix is deliberately not included + * in anticipation of the unix version + */ + protected static final String csc_exe_name="csc"; + + /** what is the file extension we search on? + */ + protected static final String csc_file_ext="cs"; + + /** and now derive the search pattern from the extension + */ + protected static final String csc_file_pattern="*."+csc_file_ext; + + + //============================================================================= + /** list of reference classes. (pretty much a classpath equivalent) + */ + + protected String _references; + + /** + * Set the reference list to be used for this compilation. + */ + + public void setReferences(String s) { + _references=s; + } + + /** get the argument or null for no argument needed + */ + protected String getReferencesParameter() { + //bail on no references + if (_references==null ||_references.length()==0) + return null; + else + return "/reference:"+_references; + } + + + /* using the path approach didnt work as it could not handle the implicit + execution path. Perhaps that could be extracted from the runtime and then + the path approach would be viable + + + protected Path _references; + + public void setReferences(Path s) { + //demand create pathlist + if(_references==null) + _references=new Path(this.project); + _references.append(s); + } + + protected String getReferencesParameter() + { + //bail on no references + if (_references==null) + return null; + //iterate through the ref list & generate an entry for each + //or just rely on the fact that the toString operator does this, but + //noting that the separator is ';' on windows, ':' on unix + String refpath=_references.toString(); + + //bail on no references listed + if (refpath.length()==0) + return null; + + StringBuffer s=new StringBuffer("/reference:"); + s.append(refpath); + return new String(s); + } + */ + + //============================================================================= + /* optimise flag + */ + + protected boolean _optimize; + + /** set the optimise flag on or off + @param on/off flag + */ + public void setOptimize(boolean f) { + _optimize=f; + } + + /** query the optimise flag + @return true if optimise is turned on + */ + public boolean getOptimize() { + return _optimize; + } + + /** get the argument or null for no argument needed + */ + protected String getOptimizeParameter() { + return "/optimize"+(_optimize?"+":"-"); + } + + //============================================================================= + /** incremental build flag */ + protected boolean _incremental; + + /** set the incremental compilation flag on or off + *@param on/off flag + */ + public void setIncremental(boolean f){ + _incremental=f; + } + + /** query the incrementalflag + * @return true iff incremental compilation is turned on + */ + public boolean getIncremental() { + return _incremental; + } + + /** get the argument or null for no argument needed + */ + protected String getIncrementalParameter() { + return "/incremental"+(_incremental?"+":"-"); + } + + //============================================================================= + /** debug flag. Controls generation of debug information. + */ + + protected boolean _debug; + + /** set the debug flag on or off + * @param on/off flag + */ + + public void setDebug(boolean f) + {_debug=f;} + + /** query the debug flag + * @return true if debug is turned on + */ + + public boolean getDebug() { + return _debug; + } + + /** get the argument or null for no argument needed + */ + protected String getDebugParameter() { + return "/debug"+(_debug?"+":"-"); + } + + + //============================================================================= + /** output XML documentation flag + */ + + protected File _docFile; + + /** file for generated XML documentation + * @param output file + */ + + public void setDocFile(String f) { + _docFile=project.resolveFile(f); + } + + + + /** get the argument or null for no argument needed + */ + protected String getDocFileParameter() { + if (_docFile!=null) + return "/doc:"+_docFile.toString(); + else + return null; + } + + //============================================================================= + /** warning level: 0-4, with 4 being most verbose + */ + private int _warnLevel; + + /** set warn level (no range checking) + * @param warn level -see .net docs for valid range (probably 0-4) + */ + public void setWarnLevel(int warnLevel) + {this._warnLevel=warnLevel;} + + /** query warn level + * @return current value + */ + public int getWarnLevel() + {return _warnLevel;} + + /** get the argument or null for no argument needed + */ + protected String getWarnLevelParameter() { + return "/warn:"+_warnLevel; + } + + //============================================================================= + /** enable unsafe code flag. Clearly set to false by default + */ + + protected boolean _unsafe; + + public void setUnsafe(boolean unsafe) + {this._unsafe=unsafe;} + + public boolean getUnsafe() + {return this._unsafe;} + + /** get the argument or null for no argument needed + */ + protected String getUnsafeParameter(){ + return _unsafe?"/unsafe":null; + } + + //============================================================================= + /** main class (or null for automatic choice) + */ + protected String _mainClass; + + public void setMainClass(String mainClass) + {this._mainClass=mainClass;} + + public String getMainClass() + {return this._mainClass;} + + /** get the argument or null for no argument needed + */ + protected String getMainClassParameter(){ + if (_mainClass!=null && _mainClass.length()!=0) + return "/main:"+_mainClass; + else + return null; + } + + //============================================================================= + /** source directory upon which the search pattern is applied + */ + private File _srcDir; + + /** + * Set the source dir to find the files to be compiled + */ + public void setSrcDir(String srcDirName){ + _srcDir = project.resolveFile(srcDirName); + } + + //============================================================================= + /** destination directory (null means use the source directory) + */ + private File _destDir; + + /** + * Set the source dir to find the files to be compiled + */ + public void setDestDir(String dirName) { + _destDir = project.resolveFile(dirName); + } + + + //============================================================================= + /** type of target. Should be one of exe|library|module|winexe|(null) + default is exe; the actual value (if not null) is fed to the command line. +
      See /target + */ + protected String _targetType; + + /** define the target + * param target. + * @throws BuildException if target is not one of exe|library|module|winexe + */ + + public void setTargetType(String targetType) + throws BuildException { + targetType=targetType.toLowerCase(); + if(targetType.equals("exe") || targetType.equals("library") || + targetType.equals("module") ||targetType.equals("winexe") ) { + _targetType=targetType; + } + else + throw new BuildException("targetType " +targetType+" is not a valid type"); + } + + public String getTargetType() { + return _targetType; + } + + /** get the argument or null for no argument needed + */ + protected String getTargetTypeParameter() { + if (_targetType!=null) + return "/target:"+_targetType; + else + return null; + } + + + //============================================================================= + /* icon for incorporation into apps + */ + + protected File _win32icon; + + /** + * Set the win32 icon + * @param path to the file. Can be relative, absolute, whatever. + */ + public void setWin32Icon(String fileName) { + _win32icon = project.resolveFile(fileName); + } + + /** get the argument or null for no argument needed + */ + protected String getWin32IconParameter() { + if (_win32icon!=null) + return "/win32icon:"+_win32icon.toString(); + else + return null; + } + + //============================================================================= + /** defines list 'RELEASE;WIN32;NO_SANITY_CHECKS;;SOMETHING_ELSE' + * + */ + + String _definitions; + + /** + * Set the definitions + * @param list of definitions split by ; or , or even : + */ + public void setDefinitions(String params) { + _definitions=params; + } + + /** get the argument or null for no argument needed + */ + protected String getDefinitionsParameter() { + if (_definitions==null || _definitions.length()==0) + return null; + else return "/DEFINE:"+_definitions; + } + + //============================================================================= + /** list of extra modules to refer to + * + */ + + String _additionalModules; + + /** + * Set the definitions + * @param list of definitions split by ; or , or even : + */ + public void setAdditionalModules(String params) { + _additionalModules=params; + } + + /** get the argument or null for no argument needed + */ + protected String getAdditionalModulesParameter() { + if (_additionalModules==null || _additionalModules.length()==0) + return null; + else return "/addmodule:"+_additionalModules; + } + + //============================================================================= + /** output file. If not supplied this is derived from the + * source file + */ + + protected String _outputFile; + + /** + * Set the definitions + * @param list of definitions split by ; or , or even : + */ + public void setOutputFile(String params) { + _outputFile=params; + } + + /** get the argument or null for no argument needed + */ + protected String getOutputFileParameter() { + if (_outputFile==null || _outputFile.length()==0) + return null; + File f=project.resolveFile(_outputFile); + return "/out:"+f.toString(); + } + + //============================================================================= + /** flag to control action on execution trouble + */ + + protected boolean _failOnError; + + /**set fail on error flag + */ + public void setFailOnError(boolean b){ + _failOnError=b; + } + + /** query fail on error flag + */ + public boolean getFailFailOnError() { + return _failOnError; + } + + //============================================================================= + /** reset all contents. + */ + public void Clear() { + _targetType=null; + _win32icon=null; + _srcDir=null; + _destDir=null; + _mainClass=null; + _unsafe=false; + _warnLevel=3; + _docFile = null; + _incremental=false; + _optimize=false; + _debug=true; + _references=null; + _failOnError=true; + _definitions=null; + _additionalModules=null; + } + + + //============================================================================= + /** do the work by building the command line and then calling it + */ + + public void execute() + throws BuildException { + if (_srcDir == null) + _srcDir=project.resolveFile("."); + + NetCommand command=new NetCommand(this,"CSC",csc_exe_name); + command.setFailOnError(getFailFailOnError()); + //DEBUG helper + command.setTraceCommandLine(true); + //fill in args + command.addArgument("/nologo"); + command.addArgument(getAdditionalModulesParameter()); + command.addArgument(getDefinitionsParameter()); + command.addArgument(getDebugParameter()); + command.addArgument(getDocFileParameter()); + command.addArgument(getIncrementalParameter()); + command.addArgument(getMainClassParameter()); + command.addArgument(getOptimizeParameter()); + command.addArgument(getReferencesParameter()); + command.addArgument(getTargetTypeParameter()); + command.addArgument(getUnsafeParameter()); + command.addArgument(getWarnLevelParameter()); + command.addArgument(getWin32IconParameter()); + command.addArgument(getOutputFileParameter()); + /* space for more argumentativeness + command.addArgument(); + command.addArgument(); + */ + + + //get dependencies list. + DirectoryScanner scanner = super.getDirectoryScanner(_srcDir); + String[] dependencies = scanner.getIncludedFiles(); + log("compiling "+dependencies.length+" file"+((dependencies.length==1)?"":"s")); + String baseDir=scanner.getBasedir().toString(); + //add to the command + for (int i = 0; i < dependencies.length; i++) { + String targetFile=dependencies[i]; + targetFile=baseDir+File.separator+targetFile; + command.addArgument(targetFile); + } + + //now run the command of exe + settings + files + command.runCommand(); + } // end execute + + + +} //end class diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java new file mode 100644 index 000000000..d17425d38 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java @@ -0,0 +1,510 @@ +/* -*-Java-*- +******************************************************************* +* +* File: Csharp.java +* RCS: $Header$ +* Author: Steve Loughran +* Created: July 21, 2000 +* Modified: $Modtime: 00-11-01 10:25 $ +* Language: Java +* Status: Experimental +* +*********************************************************************/ + +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/* build notes + +-The reference CD to listen to while editing this file is +nap: Underworld - Everything, Everything +-variable naming policy from Fowler's refactoring book. +-tested against the PDC pre-beta of csc.exe; future versions will +inevitably change things +*/ + +// ==================================================================== +// place in the optional ant tasks package +// but in its own dotnet group +// ==================================================================== + +package org.apache.tools.ant.taskdefs.optional.dotnet; + +// ==================================================================== +// imports +// ==================================================================== + +import org.apache.tools.ant.*; +import org.apache.tools.ant.taskdefs.*; +import org.apache.tools.ant.types.*; +import java.io.*; +import java.util.*; +import java.text.*; + +/** + Task to assemble .net 'Intermediate Language' files. + The task will only work on win2K until other platforms support csc.exe or + an equivalent. ilasm.exe must be on the execute path too. +

      + +

      + All parameters are optional: <il/> should suffice to produce a debug + build of all *.il files. + The option set is roughly compatible with the CSharp class; + even though the command line options are only vaguely + equivalent. [The low level commands take things like /OUT=file, + csc wants /out:file ... /verbose is used some places; /quiet here in + ildasm... etc.] It would be nice if someone made all the command line + tools consistent (and not as brittle as the java cmdline tools) + + +

      + + The task is a directory based task, so attributes like includes="*.il" and + excludes="broken.il" can be used to control the files pulled in. + Each file is built on its own, producing an appropriately named output file unless + manually specified with outfile + +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      AttributeDescriptionExample
      defaultexcludesindicates whether default excludes should be used or not + ("yes"/"no"). Default excludes are used when omitted.
      debug + include debug information + true (default) +
      excludescomma separated list of patterns of files that must be + excluded. No files (except default excludes) are excluded when omitted.
      excludesfilethe name of a file. Each line of this file is + taken to be an exclude pattern
      failOnError + Should a failed compile halt the build? + true(default) +
      includescomma separated list of patterns of files that must be + included. All files are included when omitted.
      includesfilethe name of a file. Each line of this file is + taken to be an include pattern
      listing + Produce a listing (off by default) + off (default) +
      outputFile + filename of output + "example.exe" +
      owner + restrict disassembly by setting the 'owner' string + "secret" +
      resourceFile + name of resource file to include + "resources.res" +
      srcDir + source directory (default = project directory) + +
      targetType + Type of target. library means DLL is output. + "exe","library" +
      verbose + output progress messages + off (default) +
      + + + + + @author Steve Loughran steve_l@iseran.com + @version 0.1 +*/ +// ==================================================================== + +public class Ilasm + extends org.apache.tools.ant.taskdefs.MatchingTask { + + //============================================================================= + /** constructor inits everything and set up the search pattern + */ + + public Ilasm () { + Clear(); + setIncludes(file_pattern); + } + + + //----------------------------------------------------------------------------- + /** name of the executable. the .exe suffix is deliberately not included + * in anticipation of the unix version + */ + protected static final String exe_name="ilasm"; + + /** what is the file extension we search on? + */ + protected static final String file_ext="il"; + + /** and now derive the search pattern from the extension + */ + protected static final String file_pattern="*."+file_ext; + + /** title of task for external presentation + */ + protected static final String exe_title="ilasm"; + + //============================================================================= + /** reset all contents. + */ + public void Clear() { + _targetType=null; + _srcDir=null; + _listing = false; + _verbose=false; + _debug=true; + _owner=null; + _outputFile=null; + _failOnError=true; + _resourceFile=null; + _owner=null; + } + + //============================================================================= + /** source directory upon which the search pattern is applied + */ + private File _srcDir; + + /** + * Set the source dir to find the files to be compiled + */ + public void setSrcDir(String srcDirName){ + _srcDir = project.resolveFile(srcDirName); + } + + + //============================================================================= + /** type of target. Should be one of exe|library|module|winexe|(null) + default is exe; the actual value (if not null) is fed to the command line. +
      See /target + */ + protected String _targetType; + + /** define the target + * param target. + * @throws BuildException if target is not one of exe|library|module|winexe + */ + + public void setTargetType(String targetType) + throws BuildException { + targetType=targetType.toLowerCase(); + if(targetType.equals("exe") || targetType.equals("library")) { + _targetType=targetType; + } + else + throw new BuildException("targetType " +targetType+" is not a valid type"); + } + + public String getTargetType() { + return _targetType; + } + + /** get the argument or null for no argument needed + */ + + protected String getTargetTypeParameter() { + if(!notEmpty(_targetType)) + return null; + if (_targetType.equals("exe")) + return "/exe"; + else + if (_targetType.equals("library")) + return "/dll"; + else + return null; + } + + //============================================================================= + /** owner string is a slightly trivial barrier to disassembly + */ + + protected String _owner; + + public void setOwner(String s) { + _owner=s; + } + + protected String getOwnerParameter() { + if(notEmpty(_owner)) + return "/owner="+_owner; + else + return null; + } + + //============================================================================= + /** test for a string containing something useful + * @param string to test + * @returns true if the argument is not null or empty + */ + protected boolean notEmpty(String s) + {return s!=null && s.length()!=0;} + + //============================================================================= + /** verbose flag + */ + + protected boolean _verbose; + + public void setVerbose(boolean b) { + _verbose=b; + } + + protected String getVerboseParameter() { + return _verbose?null:"/quiet"; + } + + //============================================================================= + /** listing flag + */ + + protected boolean _listing; + + public void setListing(boolean b) { + _listing=b; + } + + protected String getListingParameter() { + return _listing?"/listing":"/nolisting"; + } + + //============================================================================= + /** output file. If not supplied this is derived from the + * source file + */ + + protected String _outputFile; + + /** + * Set the definitions + * @param list of definitions split by ; or , or even : + */ + public void setOutputFile(String params) { + _outputFile=params; + } + + /** get the argument or null for no argument needed + */ + protected String getOutputFileParameter() { + if (_outputFile==null || _outputFile.length()==0) + return null; + File f=project.resolveFile(_outputFile); + return "/output="+f.toString(); + } + + //============================================================================= + /** resource file (.res format) to include in the app. + */ + + protected String _resourceFile; + + public void setResourceFile(String s) { + _resourceFile=s; + } + + protected String getResourceFileParameter() { + if(notEmpty(_resourceFile)) { + return "/resource="+_resourceFile; + } + else + return null; + } + + //============================================================================= + /** flag to control action on execution trouble + */ + + protected boolean _failOnError; + + /**set fail on error flag + */ + public void setFailOnError(boolean b){ + _failOnError=b; + } + + /** query fail on error flag + */ + public boolean getFailFailOnError() { + return _failOnError; + } + + //============================================================================= + /** debug flag. Controls generation of debug information. + */ + + protected boolean _debug; + + /** set the debug flag on or off + * @param on/off flag + */ + + public void setDebug(boolean f) + {_debug=f;} + + /** query the debug flag + * @return true if debug is turned on + */ + + public boolean getDebug() { + return _debug; + } + + /** get the argument or null for no argument needed + */ + protected String getDebugParameter() { + return _debug?"/debug":null; + } + + //============================================================================= + /** This is the execution entry point. Build a list of files and + * call ilasm on each of them. + */ + + public void execute() + throws BuildException { + if (_srcDir == null) + _srcDir=project.resolveFile("."); + + //get dependencies list. + DirectoryScanner scanner = super.getDirectoryScanner(_srcDir); + String[] dependencies = scanner.getIncludedFiles(); + log("assembling "+dependencies.length+" file"+((dependencies.length==1)?"":"s")); + String baseDir=scanner.getBasedir().toString(); + //add to the command + for (int i = 0; i < dependencies.length; i++) { + String targetFile=dependencies[i]; + targetFile=baseDir+File.separator+targetFile; + executeOneFile(targetFile); + } + + } // end execute + + //============================================================================= + /** do the work by building the command line and then calling it + */ + + public void executeOneFile(String targetFile) + throws BuildException { + NetCommand command=new NetCommand(this,exe_title,exe_name); + command.setFailOnError(getFailFailOnError()); + //DEBUG helper + command.setTraceCommandLine(true); + //fill in args + command.addArgument(getDebugParameter()); + command.addArgument(getTargetTypeParameter()); + command.addArgument(getListingParameter()); + command.addArgument(getOutputFileParameter()); + command.addArgument(getOwnerParameter()); + command.addArgument(getResourceFileParameter()); + command.addArgument(getVerboseParameter()); + + + /* space for more argumentativeness + command.addArgument(); + command.addArgument(); + */ + + command.addArgument(targetFile); + //now run the command of exe + settings + file + command.runCommand(); + } // end executeOneFile + + + +} //class diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java new file mode 100644 index 000000000..1a8464acb --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java @@ -0,0 +1,237 @@ +/* -*-Java-*- + ******************************************************************* + * + * File: CSharp.java + * RCS: $Header$ + * Author: Steve Loughran + * Created: July 21, 2000 + * Modified: $Modtime: 00-11-01 10:09 $ + * Language: Java + * Status: Experimental + * + *********************************************************************/ + +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/* build notes + +The reference CD to listen to while editing this file is +Underworld Everything, Everything +variable naming policy from Fowler's refactoring book. +*/ + +// place below the optional ant tasks package + +package org.apache.tools.ant.taskdefs.optional.dotnet; + +// imports + +import org.apache.tools.ant.*; +import org.apache.tools.ant.taskdefs.*; +import org.apache.tools.ant.types.*; +import java.io.*; +import java.util.*; +import java.text.*; + + + +/** +This is a helper class to spawn net commands out. +In its initial form it contains no .net specifics, just contains +all the command line/exe construction stuff. However, it may be handy in future +to have a means of setting the path to point to the dotnet bin directory; in which +case the shared code should go in here. +@author Steve Loughran steve_l@iseran.com + + */ + + +public class NetCommand { + + /** constructor + @param owning task + @param title (for logging/errors) + @param executable. Leave off the '.exe. for future portability + */ + + public NetCommand(Task owner, String title, String program) + throws BuildException { + _owner=owner; + _title=title; + _program=program; + _commandLine=new Commandline(); + _commandLine.setExecutable(_program); + prepareExecutor(); + } + + /** owner project + */ + protected Task _owner; + + /** executabe + */ + protected Execute _exe; + + /** what is the command line + */ + protected Commandline _commandLine; + + /** title of the command + */ + protected String _title; + + /** actual program to invoke + */ + protected String _program; + + /** trace flag + */ + protected boolean _traceCommandLine=false; + + public void setTraceCommandLine(boolean b){ + _traceCommandLine=b; + } + + /** flag to control action on execution trouble + */ + + protected boolean _failOnError; + + /**set fail on error flag + */ + public void setFailOnError(boolean b){ + _failOnError=b; + } + + /** query fail on error flag + */ + public boolean getFailFailOnError() { + return _failOnError; + } + + + + /** verbose text log + * @param string to add to log iff verbose is defined for the build + */ + protected void logVerbose(String msg){ + _owner.getProject().log(msg,Project.MSG_VERBOSE); + } + + + /** error text log + * @param string to add to the error log + */ + protected void logError(String msg) { + _owner.getProject().log(msg,Project.MSG_ERR); + } + + /* + * add an argument to a command line; do nothing if the arg is null or empty string + * @param commandline to extend + * @param next arg + */ + public void addArgument(String argument){ + if(argument!=null && argument.length()!=0) { + _commandLine.createArgument().setValue(argument); + } + } + + /** + * set up the command sequence.. + */ + protected void prepareExecutor() throws BuildException { + // default directory to the project's base directory + File dir = _owner.getProject().getBaseDir(); + ExecuteStreamHandler handler=new LogStreamHandler(_owner, + Project.MSG_INFO, Project.MSG_WARN); + _exe = new Execute(handler, null); + _exe.setAntRun(_owner.getProject()); + _exe.setWorkingDirectory(dir); + /* do nothing with env variables. REVISIT: SDK command line? + String[] environment = env.getVariables(); + exe.setEnvironment(environment); + */ + } + + /** + * Run the command using the given Execute instance. + * @throws an exception of something goes wrong and the failOnError flag is true + */ + public void runCommand() + throws BuildException { + int err = -1; // assume the worst + try { + if(_traceCommandLine) { + _owner.log(_commandLine.toString()); + } + else + logVerbose(_commandLine.toString()); + _exe.setCommandline(_commandLine.getCommandline()); + err = _exe.execute(); + if (err != 0) { + if (_failOnError) { + throw new BuildException(_title+" returned: "+err, _owner.getLocation()); + } else { + _owner.log(_title+" Result: " + err, Project.MSG_ERR); + } + } + } catch (IOException e) { + throw new BuildException(_title+" failed: " + e, e, _owner.getLocation()); + } + } + + +} //class