Browse Source

refactoring so that ilasm can share code (and moved something into NetCommand as it may be more at home there, but that may be bogus). Fixed ilasm to handle multiple files and do dependency checking. More convoluted than one would have thought.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274217 13f79535-47bb-0310-9956-ffa450edef68
master
Steve Loughran 23 years ago
parent
commit
77ee46ba7a
4 changed files with 296 additions and 234 deletions
  1. +213
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetBaseMatchingTask.java
  2. +9
    -176
      src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java
  3. +38
    -58
      src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java
  4. +36
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java

+ 213
- 0
src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetBaseMatchingTask.java View File

@@ -0,0 +1,213 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 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", "Ant", 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
* <http://www.apache.org/>.
*/


package org.apache.tools.ant.taskdefs.optional.dotnet;

import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.DirectoryScanner;

import java.io.File;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;

/**
* refactoring of some stuff so that different things (like ILASM)
* can use shared code.
* @author steve loughran
*/
public class DotnetBaseMatchingTask extends MatchingTask {
/**
* output file. If not supplied this is derived from the source file
*/
protected File outputFile;
/**
* sets of file to compile
*/
protected Vector filesets = new Vector();
/**
* source directory upon which the search pattern is applied
*/
protected File srcDir;

/**
* Overridden because we need to be able to set the srcDir.
*/
public File getSrcDir() {
return this.srcDir;
}

/**
* Set the source directory of the files to be compiled.
*
*@param srcDirName The new SrcDir value
*/
public void setSrcDir(File srcDirName) {
this.srcDir = srcDirName;
}

/**
* Set the name of exe/library to create.
*
*@param file The new outputFile value
*/
public void setDestFile(File file) {
outputFile = file;
}

/**
* add a new source directory to the compile
* @param src
*/
public void addSrc(FileSet src) {
filesets.add(src);
}

/**
* get the destination file
* @return the dest file or null for not assigned
*/
public File getDestFile() {
return outputFile;
}

/**
* create the list of files
* @param filesToBuild vector to add files to
* @param outputTimestamp timestamp to compare against
* @return number of files out of date
*/
protected int buildFileList(NetCommand command, Hashtable filesToBuild, long outputTimestamp) {
int filesOutOfDate=0;
boolean scanImplicitFileset=getSrcDir()!=null || filesets.size()==0;
if(scanImplicitFileset) {
//scan for an implicit fileset if there was a srcdir set
//or there was no srcDir set but the @
if (getSrcDir() == null) {
//if there is no src dir here, set it
setSrcDir(getProject().resolveFile("."));
}
log("working from source directory " + getSrcDir(),
Project.MSG_VERBOSE);
//get dependencies list.
DirectoryScanner scanner = getDirectoryScanner(getSrcDir());
filesOutOfDate = command.scanOneFileset(scanner,
filesToBuild, outputTimestamp);
}
//get any included source directories
for (int i = 0; i < filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
filesOutOfDate+= command.scanOneFileset(
fs.getDirectoryScanner(getProject()),
filesToBuild,
outputTimestamp);
}

return filesOutOfDate;
}

/**
* add the list of files to a command
* @param filesToBuild vector of files
* @param command the command to append to
*/
protected void addFilesToCommand(Hashtable filesToBuild, NetCommand command) {
int count=filesToBuild.size();
log("compiling " + count + " file" + ((count== 1) ? "" : "s"));
Enumeration files=filesToBuild.elements();
while (files.hasMoreElements()) {
File file = (File) files.nextElement();
command.addArgument(file.toString());
}
}

/**
* determine the timestamp of the output file
* @return a timestamp or 0 for no output file known/exists
*/
protected long getOutputFileTimestamp() {
long outputTimestamp;
if (getDestFile() != null && getDestFile().exists()) {
outputTimestamp = getDestFile().lastModified();
} else {
outputTimestamp = 0;
}
return outputTimestamp;
}

/**
* finish off the command by adding all dependent files, execute
* @param command
*/
protected void addFilesAndExecute(NetCommand command) {
long outputTimestamp = getOutputFileTimestamp();
Hashtable filesToBuild =new Hashtable();
int filesOutOfDate = buildFileList(command,filesToBuild, outputTimestamp);

//add the files to the command
addFilesToCommand(filesToBuild, command);

//now run the command of exe + settings + files
if (filesOutOfDate > 0) {
command.runCommand();
} else {
log("output file is up to date",Project.MSG_VERBOSE);
}
}


}

+ 9
- 176
src/main/org/apache/tools/ant/taskdefs/optional/dotnet/DotnetCompile.java View File

@@ -108,7 +108,7 @@ import org.apache.tools.ant.types.EnumeratedAttribute;
*/

public abstract class DotnetCompile
extends MatchingTask {
extends DotnetBaseMatchingTask {

/**
* list of reference classes. (pretty much a classpath equivalent)
@@ -130,11 +130,6 @@ public abstract class DotnetCompile
*/
private File win32res;

/**
* output file. If not supplied this is derived from the source file
*/
private File outputFile;

/**
* flag to control action on execution trouble
*/
@@ -152,11 +147,6 @@ public abstract class DotnetCompile
*/
private boolean optimize;

/**
* sets of file to compile
*/
protected Vector filesets = new Vector();

/**
* a list of definitions to support;
*/
@@ -222,11 +212,6 @@ public abstract class DotnetCompile
*/
protected String extraOptions;

/**
* source directory upon which the search pattern is applied
*/
private File srcDir;

/**
* 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
@@ -244,7 +229,7 @@ public abstract class DotnetCompile
/**
* list of extra modules to refer to
*/
String additionalModules;
protected String additionalModules;


/**
@@ -552,23 +537,6 @@ public abstract class DotnetCompile
}


/**
* Overridden because we need to be able to set the srcDir.
*/
public File getSrcDir() {
return this.srcDir;
}

/**
* Set the source directory of the files to be compiled.
*
*@param srcDirName The new SrcDir value
*/
public void setSrcDir(File srcDirName) {
this.srcDir = srcDirName;
}


/**
* Set the destination directory of files to be compiled.
*
@@ -595,12 +563,12 @@ public abstract class DotnetCompile
*/
public void setTargetType(String ttype)
throws BuildException {
targetType = ttype.toLowerCase();
if (targetType.equals("exe") || targetType.equals("library") ||
targetType.equals("module") || targetType.equals("winexe")) {
targetType = targetType;
ttype = ttype.toLowerCase();
if (ttype.equals("exe") || ttype.equals("library") ||
ttype.equals("module") || ttype.equals("winexe")) {
targetType = ttype;
} else {
throw new BuildException("targetType " + targetType
throw new BuildException("targetType " + ttype
+ " is not one of 'exe', 'module', 'winexe' or 'library'" );
}
}
@@ -766,17 +734,6 @@ public abstract class DotnetCompile
}



/**
* Set the name of exe/library to create.
*
*@param file The new outputFile value
*/
public void setDestFile(File file) {
outputFile = file;
}


/**
* get the argument or null for no argument needed
*
@@ -810,14 +767,6 @@ public abstract class DotnetCompile
return failOnError;
}

/**
* add a new source directory to the compile
* @param src
*/
public void addSrc(FileSet src) {
filesets.add(src);
}

/**
* test for a string containing something useful
*
@@ -861,14 +810,6 @@ public abstract class DotnetCompile
return "**/*." + getFileExtension();
}

/**
* get the destination file
* @return the dest file or null for not assigned
*/
public File getDestFile() {
return outputFile;
}

/**
* do the work by building the command line and then calling it
*
@@ -904,98 +845,6 @@ public abstract class DotnetCompile
*/
public abstract String getFileExtension();

/**
* create the list of files
* @param filesToBuild vector to add files to
* @param outputTimestamp timestamp to compare against
* @return number of files out of date
*/
protected int buildFileList(Hashtable filesToBuild, long outputTimestamp) {
int filesOutOfDate=0;
boolean scanImplicitFileset=getSrcDir()!=null || filesets.size()==0;
if(scanImplicitFileset) {
//scan for an implicit fileset if there was a srcdir set
//or there was no srcDir set but the @
if (getSrcDir() == null) {
//if there is no src dir here, set it
setSrcDir(getProject().resolveFile("."));
}
log("working from source directory " + getSrcDir(), Project.MSG_VERBOSE);
//get dependencies list.
DirectoryScanner scanner = super.getDirectoryScanner(getSrcDir());
filesOutOfDate = scanOneFileset(scanner, filesToBuild, outputTimestamp);
}
//get any included source directories
for (int i = 0; i < filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
filesOutOfDate+=scanOneFileset(fs.getDirectoryScanner(getProject()),
filesToBuild,
outputTimestamp);
}

return filesOutOfDate;
}

/**
* scan through one fileset for files to include
* @param scanner
* @param filesToBuild
* @param outputTimestamp timestamp to compare against
* @return #of files out of date
* @todo: should FAT granularity be included here?
*/
protected int scanOneFileset(DirectoryScanner scanner, Hashtable filesToBuild,
long outputTimestamp) {
int filesOutOfDate = 0;
String[] dependencies = scanner.getIncludedFiles();
File base = scanner.getBasedir();
//add to the list
for (int i = 0; i < dependencies.length; i++) {
File targetFile = new File(base, dependencies[i]);
if(filesToBuild.get(targetFile)==null) {
log(targetFile.toString(), Project.MSG_VERBOSE);
filesToBuild.put(targetFile,targetFile);
if (targetFile.lastModified() > outputTimestamp) {
filesOutOfDate++;
log("Source file " + targetFile.toString() + " is out of date",
Project.MSG_VERBOSE);
} else {
log("Source file " + targetFile.toString() + " is up to date",
Project.MSG_VERBOSE);
}
}
}
return filesOutOfDate;
}

/**
* add the list of files to a command
* @param filesToBuild vector of files
* @param command the command to append to
*/
protected void addFilesToCommand(Hashtable filesToBuild, NetCommand command) {
int count=filesToBuild.size();
log("compiling " + count + " file" + ((count== 1) ? "" : "s"));
Enumeration files=filesToBuild.elements();
while (files.hasMoreElements()) {
File file = (File) files.nextElement();
command.addArgument(file.toString());
}
}

/**
* determine the timestamp of the output file
* @return a timestamp or 0 for no output file known/exists
*/
protected long getOutputFileTimestamp() {
long outputTimestamp;
if (getDestFile() != null && getDestFile().exists()) {
outputTimestamp = getDestFile().lastModified();
} else {
outputTimestamp = 0;
}
return outputTimestamp;
}

/**
* fill in the common information
@@ -1035,24 +884,6 @@ public abstract class DotnetCompile
*/
protected abstract void addCompilerSpecificOptions(NetCommand command);

/**
* finish off the command by adding all dependent files, execute
* @param command
*/
protected void addFilesAndExecute(NetCommand command) {
long outputTimestamp = getOutputFileTimestamp();
Hashtable filesToBuild =new Hashtable();
int filesOutOfDate = buildFileList(filesToBuild, outputTimestamp);

//add the files to the command
addFilesToCommand(filesToBuild, command);

//now run the command of exe + settings + files
if (filesOutOfDate > 0) {
command.runCommand();
}
}

/**
* override point for delimiting definitions
* @return
@@ -1138,6 +969,8 @@ public abstract class DotnetCompile
|| owner.getProject().getProperty(condition) != null;
}
}


}



+ 38
- 58
src/main/org/apache/tools/ant/taskdefs/optional/dotnet/Ilasm.java View File

@@ -55,25 +55,16 @@
* 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 java.io.File;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.taskdefs.MatchingTask;

/**
@@ -93,15 +84,14 @@ import org.apache.tools.ant.taskdefs.MatchingTask;
*
* The task is a directory based task, so attributes like <b>includes="*.il"
* </b> and <b>excludes="broken.il"</b> 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 <b>outfile</b>
* in. You can also use nested &lt;src&gt filesets to refer to source.
*
*@author Steve Loughran steve_l@iseran.com
*@version 0.5
*@version 0.6
*/

public class Ilasm
extends MatchingTask {
extends DotnetBaseMatchingTask {

/**
* Name of the executable. The .exe suffix is deliberately not included in
@@ -124,11 +114,6 @@ public class Ilasm
*/
protected static final String exe_title = "ilasm";

/**
* source directory upon which the search pattern is applied
*/
private File srcDir;

/**
* 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
@@ -148,11 +133,6 @@ public class Ilasm

protected boolean listing;

/**
* output file. If not supplied this is derived from the source file
*/
protected File outputFile;

/**
* resource file (.res format) to include in the app.
*/
@@ -205,15 +185,6 @@ public class Ilasm
}


/**
* Set the source directory containing the files to be compiled.
*
* @param srcDirName The new SrcDir value
*/
public void setSrcDir(File srcDirName) {
srcDir = srcDirName;
}


/**
* Sets the type of target, either "exe" or "library".
@@ -324,8 +295,8 @@ public class Ilasm


/**
* Set the output file.
*
* Set the output file; identical to setDestFile
* @see DotnetBaseMatchingTask.setDestFile
*@param params The new outputFile value
*/
public void setOutputFile(File params) {
@@ -385,7 +356,7 @@ public class Ilasm
*
*@return The failFailOnError value
*/
public boolean getFailFailOnError() {
public boolean getFailOnError() {
return failOnError;
}

@@ -478,6 +449,13 @@ public class Ilasm
}
}

/**
* set the target type to one of exe|library
* @param targetType
*/
public void setTargetType(TargetTypes targetType) {
this.targetType = targetType.getValue();
}

/**
* This is the execution entry point. Build a list of files and call ilasm
@@ -491,32 +469,21 @@ public class Ilasm
srcDir = getProject().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);
}
NetCommand command = buildIlasmCommand();

addFilesAndExecute(command);

}
// end execute


/**
* do the work for one file by building the command line then calling it
*
*@param targetFile name of the the file to assemble
*@throws BuildException if the assembly failed and FailOnError is true
* build up our ilasm command
* @return
*/
public void executeOneFile(String targetFile)
throws BuildException {
private NetCommand buildIlasmCommand() {
NetCommand command = new NetCommand(this, exe_title, exe_name);
command.setFailOnError(getFailFailOnError());
command.setFailOnError(getFailOnError());
//fill in args
command.addArgument(getDebugParameter());
command.addArgument(getTargetTypeParameter());
@@ -532,10 +499,23 @@ public class Ilasm
* command.addArgument();
* command.addArgument();
*/
command.addArgument(targetFile);
//now run the command of exe + settings + file
command.runCommand();
return command;
}



/**
* Target types to build.
* valid build types are exe|library|module|winexe
*/
public static class TargetTypes extends EnumeratedAttribute {
public String[] getValues() {
return new String[]{
"exe",
"library",
};
}
}
// end executeOneFile
}


+ 36
- 0
src/main/org/apache/tools/ant/taskdefs/optional/dotnet/NetCommand.java View File

@@ -65,9 +65,12 @@ package org.apache.tools.ant.taskdefs.optional.dotnet;

import java.io.File;
import java.io.IOException;
import java.util.Hashtable;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
import org.apache.tools.ant.taskdefs.LogStreamHandler;
@@ -259,5 +262,38 @@ public class NetCommand {
throw new BuildException(title + " failed: " + e, e, owner.getLocation());
}
}


/**
* scan through one fileset for files to include
* @param scanner
* @param filesToBuild
* @param outputTimestamp timestamp to compare against
* @return #of files out of date
* @todo: should FAT granularity be included here?
*/
public int scanOneFileset(DirectoryScanner scanner, Hashtable filesToBuild,
long outputTimestamp) {
int filesOutOfDate = 0;
String[] dependencies = scanner.getIncludedFiles();
File base = scanner.getBasedir();
//add to the list
for (int i = 0; i < dependencies.length; i++) {
File targetFile = new File(base, dependencies[i]);
if (filesToBuild.get(targetFile) == null) {
owner.log(targetFile.toString(), Project.MSG_VERBOSE);
filesToBuild.put(targetFile, targetFile);
if (targetFile.lastModified() > outputTimestamp) {
filesOutOfDate++;
owner.log("Source file " + targetFile.toString() + " is out of date",
Project.MSG_VERBOSE);
} else {
owner.log("Source file " + targetFile.toString() + " is up to date",
Project.MSG_VERBOSE);
}
}
}
return filesOutOfDate;
}
}


Loading…
Cancel
Save