Ian,
Here's the source file.
j3d.
> hmm - that commandline does seem ok. I just tested locally with a test
> .il file. I don't have any other ideas right now but if you want to send
> me the source I could take a quick look at it.
>
>
> Ian
> Giuseppe Greco wrote:
>
>>Ian,
>>
>>Here's what NAnt reports:
>>
>>[ilasm] Starting 'C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\ilasm.exe
>> (/NOLOGO /EXE
>> "/OUTPUT=C:\Home\Projects\temp\.net\ilasm\OddOrEven\OddOrEven.exe"
>> "C:\Home\Projects\temp\.net\ilasm\OddOrEven\MainClass.il")'
>> in 'C:\Home\Projects\temp\.net\ilasm\OddOrEven'
>>
>>The command-line arguments are fine... I've tested them manually.
>>
>>j3d.
>>
>>
>>
>>>What does the generated commandline look like ? Just use nant -v to
>>>output it or take a look in the debugger.
>>>
>>>Ian
>>>
>>>
>>>Giuseppe Greco wrote:
>>>
>>>
>>>
>>>>OK guys,
>>>>
>>>>Now the IlasmTask class inherits from ExternalProbramBase...
>>>>but I'm still unable to get the <ilasm> task working. I
>>>>always get the following error message:
>>>>
>>>>Could not open C:\Home\Projects\temp\.net\ilasm\OddOrEven\MainClass.il
>>>>
>>>>The arguments list is OK (I've tried it manually and it does function)
>>>>and the file above exists.
>>>>
>>>>Is there something else that I should know?
>>>>
>>>>Thanks,
>>>>j3d.
>>>>
>>>>----------------------------------------
>>>>Giuseppe Greco
>>>>
>>>>::agamura::
>>>>
>>>>phone: +41 (0)91 604 67 65
>>>>mobile: +41 (0)76 390 60 32
>>>>email: [EMAIL PROTECTED]
>>>>web: www.agamura.com
>>>>----------------------------------------
>>>>
>>>>
>>>>-------------------------------------------------------
>>>>This SF.Net email sponsored by Black Hat Briefings & Training.
>>>>Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
>>>>digital self defense, top technical experts, no vendor pitches,
>>>>unmatched networking opportunities. Visit www.blackhat.com
>>>>_______________________________________________
>>>>nant-developers mailing list
>>>>[EMAIL PROTECTED]
>>>>https://lists.sourceforge.net/lists/listinfo/nant-developers
>>>>
>>>>
>>>>
>>>>
>>>
>>>-------------------------------------------------------
>>>This SF.Net email sponsored by Black Hat Briefings & Training.
>>>Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
>>>digital self defense, top technical experts, no vendor pitches,
>>>unmatched networking opportunities. Visit www.blackhat.com
>>>_______________________________________________
>>>nant-developers mailing list
>>>[EMAIL PROTECTED]
>>>https://lists.sourceforge.net/lists/listinfo/nant-developers
>>>
>>>
>>>
>>
>>
>>----------------------------------------
>>Giuseppe Greco
>>
>>::agamura::
>>
>>phone: +41 (0)91 604 67 65
>>mobile: +41 (0)76 390 60 32
>>email: [EMAIL PROTECTED]
>>web: www.agamura.com
>>----------------------------------------
>>
>>
>>-------------------------------------------------------
>>This SF.Net email sponsored by Black Hat Briefings & Training.
>>Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
>>digital self defense, top technical experts, no vendor pitches,
>>unmatched networking opportunities. Visit www.blackhat.com
>>_______________________________________________
>>nant-developers mailing list
>>[EMAIL PROTECTED]
>>https://lists.sourceforge.net/lists/listinfo/nant-developers
>>
>>
>
>
> --
> Ian MacLean, Developer,
> ActiveState, a division of Sophos
> http://www.ActiveState.com
>
----------------------------------------
Giuseppe Greco
::agamura::
phone: +41 (0)91 604 67 65
mobile: +41 (0)76 390 60 32
email: [EMAIL PROTECTED]
web: www.agamura.com
----------------------------------------
// NAnt - A .NET build tool
// Copyright (C) 2001-2002 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Giuseppe Greco ([EMAIL PROTECTED])
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Tasks;
using NAnt.Core.Types;
using NAnt.Core.Util;
namespace NAnt.DotNet.Tasks {
/// <summary>
/// Compiles ILASM programs.
/// </summary>
/// <example>
/// <para>Compiles <c>helloworld.il</c> to <c>helloworld.exe</c>.</para>
/// <code>
/// <![CDATA[
/// <ilasm target="exe" output="helloworld.exe" debug="true">
/// <sources>
/// <include name="helloworld.il" />
/// </sources>
/// </ilasm>
/// ]]>
/// </code>
/// </example>
[TaskName("ilasm")]
[ProgramLocation(LocationType.FrameworkDir)]
public class IlasmTask : ExternalProgramBase {
#region Private Instance Fields
private bool _listing;
private bool _quiet;
private string _target;
private bool _debug;
private bool _forceRebuild;
private bool _clock;
private FileInfo _resourceFile;
private FileInfo _outputFile;
private FileInfo _keyFile;
private string _keySource;
private string _subsystem;
private string _flags;
private string _alignment;
private string _base;
private bool _error;
private FileSet _sources;
private string _options;
#endregion Private Instance Fields
#region Public Instance Properties
/// <summary>
/// Specifies whether or not the compiler should type a formatted
/// listing of the compilation result.
/// </summary>
/// <value>
/// <see langword="true" /> if a formatted listing of the compilation
/// result should be typed; otherwise, <see langword="false" />. The
/// default is <see langword="false" />.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/LISTING</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("listing")]
[BooleanValidator()]
public bool Listing {
get { return _listing; }
set { _listing = value; }
}
/// <summary>
/// Specifies which output type should be generated.
/// </summary>
/// <value>
/// A <see cref="System.String" /> that contains the target type.
/// Possible values are <c>dll</c> and <c>exe</c>.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/OUTPUT</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("target", Required=true)]
[StringValidator(AllowEmpty=false)]
public string Target {
get { return _target; }
set { _target = StringUtils.ConvertEmptyToNull(value); }
}
/// <summary>
/// Specifies whether or not the compiler should suppress the
/// compilation progress report.
/// </summary>
/// <value>
/// <see langword="true" /> if the compilation progress report should
/// be suppressed; otherwise, <see langword="false" />. The default is
/// <see langword="false" />.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/QUIET</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("quiet")]
[BooleanValidator()]
public bool Quiet {
get { return _quiet; }
set { _quiet = value; }
}
/// <summary>
/// Specifies whether or not the compiler should generate debug
/// information.
/// </summary>
/// <value>
/// <see langword="true" /> if debug information should be generated;
/// otherwise, <see langword="false" />. The default is
/// <see langword="false" />.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/DEBUG</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("debug")]
[BooleanValidator()]
public bool Debug {
get { return _debug; }
set { _debug = value; }
}
/// <summary>
/// Instructs NAnt to recompile the output file regardless of the file
/// timestamps.
/// </summary>
/// <value>
/// <see langword="true" /> if the output file should be recompiled
/// regardless of its timestamps; otherwise <see langword="false" />.
/// The default is <see langword="false" />.
/// </value>
[TaskAttribute("rebuild")]
[BooleanValidator()]
public bool ForceRebuild {
get { return _forceRebuild; }
set { _forceRebuild = value; }
}
/// <summary>
/// Specifies whether or not the compiler should measure and report
/// the compilation times.
/// </summary>
/// <value>
/// <see langword="true" /> if the compilation times should be
/// measured and reported; otherwise, <see langword="false" />. The
/// default is <see langword="false" />.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/CLOCK</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("clock")]
[BooleanValidator()]
public bool Clock {
get { return _clock; }
set { _clock = value; }
}
/// <summary>
/// Instructs the compiler to link the specified unmanaged resource
/// file into the resulting PE file.
/// </summary>
/// <value>
/// A <see cref="System.String" /> that specifies the name of the
/// unmanaged resource file to link.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/RESOURCE</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("resourcefile")]
public FileInfo ResourceFile {
get { return _resourceFile; }
set { _resourceFile = value; }
}
/// <summary>
/// Specifies the name of the output file created by the compiler.
/// </summary>
/// <value>
/// A <see cref="System.String" /> that specifies the name of the
/// output file.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/OUTPUT</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("output")]
public FileInfo OutputFile {
get { return _outputFile; }
set { _outputFile = value; }
}
/// <summary>
/// Instructs the compiler to generate a strong signature of the PE
/// file.
/// </summary>
/// <value>
/// A <see cref="System.String" /> that specifies the name of the file
/// that contains the private encryption key.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/KEY=<![CDATA[<]]>keyfile<![CDATA[>]]></c>
/// flag.
/// </para>
/// </remarks>
[TaskAttribute("keyfile")]
public FileInfo KeyFile {
get { return _keyFile; }
set { _keyFile = value; }
}
/// <summary>
/// Instructs the compiler to generate a strong signature of the PE
/// file.
/// </summary>
/// <value>
/// A <see cref="System.String" /> that contains the private
/// encryption key.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/KEY=<![CDATA[@<]]>keysource<![CDATA[>]]></c>
/// flag.
/// </para>
/// </remarks>
[TaskAttribute("keysource")]
public string KeySource {
get { return _keySource; }
set { _keySource = value; }
}
/// <summary>
/// Instructs the compiler to set the <i>Subsystem</i> value in the PE
/// header.
/// </summary>
/// <value>
/// An <see cref="System.Int32" /> that represents the <i>Subsystem</i>
/// value to set in the PE header. The most frequently value are 3
/// (console application) and 2 (GUI application).
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/SUBSYSTEM</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("subsystem")]
public string Subsystem {
get { return _subsystem; }
set { _subsystem = value; }
}
/// <summary>
/// Instructs the compiler to set the <i>Flags</i> value in the CLR
/// header.
/// </summary>
/// <value>
/// An <see cref="System.Int32" /> that represents the <i>Flags</i>
/// value to set in the CLR header. The most frequently value are 1
/// (pre-IL code) and 2 (mixed code). The third bit indicating that
/// the PE file is strong signed, is ignored.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/FLAGS</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("flags")]
public string Flags {
get { return _flags; }
set { _flags = value; }
}
/// <summary>
/// Instructs the compiler to set the <i>FileAlignment</i> value in
/// the PE header.
/// </summary>
/// <value>
/// An <see cref="System.Int32" /> that represents the <i>FileAlignment</i>
/// value to set in the PE header. The value must be a power of 2, in
/// range from 512 to 65536.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/ALIGNMENT</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("alignment")]
public string Alignment {
get { return _alignment; }
set { _alignment = value; }
}
/// <summary>
/// Instructs the compiler to set the <i>ImageBase</i> value in
/// the PE header.
/// </summary>
/// <value>
/// A <see cref="System.Int32" /> that represents the <i>ImageBase</i>
/// value to set in the PE header.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/BASE</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("base")]
public string Base {
get { return _base; }
set { _base = value; }
}
/// <summary>
/// Specifies whether or not the compiler should attempt to create a
/// PE file even if compilation errors have been reported.
/// </summary>
/// <value>
/// <see langword="true" /> if a PE file has to be created even if
/// compilation errors have been reported; otherwise,
/// <see langword="false" />. The default is <see langword="false" />.
/// </value>
/// <remarks>
/// <para>
/// Corresponds to the <c>/ERROR</c> flag.
/// </para>
/// </remarks>
[TaskAttribute("error")]
[BooleanValidator()]
public bool Error {
get { return _error; }
set { _error = value; }
}
/// <summary>
/// Specifies the set of source files to compile.
/// </summary>
/// <value>
/// A <see cref="NAnt.Core.Types.FileSet" /> that represents the set
/// of source files to compile.
/// </value>
[BuildElement("sources", Required=true)]
public FileSet Sources {
get { return _sources; }
set { _sources = value; }
}
#endregion Public Instance Properties
#region Public Instance Methods
/// <summary>
/// Gets the command-line arguments for the external program.
/// </summary>
/// <value>
/// A <see cref="System.String" /> that contains the command-line
/// arguments for the external program.
/// </value>
public override string ProgramArguments {
get { return _options; }
}
#endregion Public Instance Methods
#region Protected Instance Methods
/// <summary>
/// Compiles the sources.
/// </summary>
protected override void ExecuteTask() {
if (NeedsCompiling()) {
//
// ensure base directory is set, even if fileset was not initialized
// from XML
//
if (Sources.BaseDirectory == null) {
Sources.BaseDirectory = new DirectoryInfo(Project.BaseDirectory);
}
Log(Level.Info, LogPrefix + "Compiling {0} files to '{1}'.",
Sources.FileNames.Count, OutputFile.FullName);
//
// set command-line arguments for the ILASM compiler
//
WriteOptions();
//
// call base class to do the work
//
base.ExecuteTask();
}
}
#endregion Protected Instance Methdos
#region Private Instance Methods
/// <summary>
/// Writes the compiler options.
/// </summary>
private void WriteOptions() {
StringWriter writer = new StringWriter();
try {
//
// always suppress logo and copyright statements
//
WriteOption(writer, "NOLOGO");
if (Listing) {
WriteOption(writer, "LISTING");
}
if (Quiet) {
WriteOption(writer, "QUIET");
}
if (Target != null) {
WriteOption(writer, Target.ToUpper());
}
if (Debug) {
WriteOption(writer, "DEBUG");
}
if (Clock) {
WriteOption(writer, "CLOCK");
}
if (ResourceFile != null) {
WriteOption(writer, "RESOURCE", ResourceFile.FullName);
}
if (OutputFile != null) {
WriteOption(writer, "OUTPUT", OutputFile.FullName);
}
if (KeyFile != null) {
WriteOption(writer, "KEY", KeyFile.FullName);
}
if (KeySource != null) {
WriteOption(writer, "KEY", "@" + KeySource);
}
if (Subsystem != null) {
WriteOption(writer, "SUBSYSTEM", Subsystem);
}
if (Flags != null) {
WriteOption(writer, "FLAGS", Flags);
}
if (Alignment != null) {
WriteOption(writer, "ALIGNMENT", Alignment);
}
if (Base != null) {
WriteOption(writer, "BASE", Base);
}
if (Error) {
WriteOption(writer, "ERROR");
}
foreach (string fileName in Sources.FileNames) {
writer.WriteLine("\"" + fileName + "\"");
}
} finally {
//
// close the StreamWriter and the underlying stream
//
writer.Close();
}
_options = writer.ToString();
}
/// <summary>
/// Writes an option using the default output format.
/// </summary>
/// <param name="writer">
/// The <see cref="StringWriter" /> to which the compiler options should
/// be written.
///</param>
/// <param name="name">
/// A <see cref="System.String" /> that contains the name of the
/// option which should be passed to the compiler.
/// </param>
private void WriteOption(StringWriter writer, string name) {
writer.Write("/{0} ", name);
}
/// <summary>
/// Writes an option and its value using the default output format.
/// </summary>
/// <param name="writer">
/// The <see cref="StringWriter" /> to which the compiler options should
/// be written.
/// </param>
/// <param name="name">
/// A <see cref="System.String" /> that contains the name of the
/// option which should be passed to the compiler.
/// </param>
/// <param name="arg">
/// A <see cref="System.String" /> that contains the value of the
/// option which should be passed to the compiler.
/// </param>
private void WriteOption(StringWriter writer, string name, string arg) {
//
// always quote arguments
//
writer.Write("\"/{0}={1}\" ", name, arg);
}
/// <summary>
/// Determines whether or not compilation is needed.
/// </summary>
private bool NeedsCompiling() {
//
// return true as soon as we know we need to compile
//
if (ForceRebuild) {
Log(Level.Verbose, LogPrefix +
"'rebuild' attribute set to true, recompiling.");
return true;
}
if (!OutputFile.Exists) {
return true;
}
//
// check if sources were updated
//
string fileName = FileSet.FindMoreRecentLastWriteTime(
Sources.FileNames, OutputFile.LastWriteTime);
if (fileName != null) {
Log(Level.Verbose, LogPrefix +
"'{0}' has been updated, recompiling.", fileName);
return true;
}
//
// check if unmanaged resources were updated
//
if (ResourceFile != null) {
fileName = FileSet.FindMoreRecentLastWriteTime(
ResourceFile.FullName, OutputFile.LastWriteTime);
if (fileName != null) {
Log(Level.Verbose, LogPrefix +
"'{0}' has been updated, recompiling.", fileName);
return true;
}
}
//
// check if strong name signature was updated
//
if (KeyFile != null) {
fileName = FileSet.FindMoreRecentLastWriteTime(
KeyFile.FullName, OutputFile.LastWriteTime);
if (fileName != null) {
Log(Level.Verbose, LogPrefix +
"'{0}' has been updated, recompiling.", fileName);
return true;
}
}
//
// if we made it here then we don't have to recompile
//
return false;
}
#endregion Private Instance Methods
}
}