// 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 // // Kevin Connors (connors@karmet.com) // Ian MacLean (ian_maclean@another.com) using System.Globalization; using System.IO; using NAnt.Core; using NAnt.Core.Attributes; using NAnt.Core.Tasks; using NAnt.Core.Util; namespace NAnt.VisualCpp.Tasks { /// /// Compiles messages using mc.exe, Microsoft's Win32 message compiler. /// /// /// /// Compile text.mc using the default options. /// /// /// /// ]]> /// /// /// Compile text.mc, passing a path to store the header, the rc /// file and some additonal options. /// /// /// /// ]]> /// /// [TaskName("mc")] public class McTask : ExternalProgramBase { #region Private Instance Fields private DirectoryInfo _headerPath; private DirectoryInfo _rcPath; private string _options; private FileInfo _mcFile; #endregion Private Instance Fields #region Public Instance Properties /// /// Options to pass to the compiler. /// [TaskAttribute("options")] public string Options { get { return _options; } set { _options = value; } } /// /// Path to store header file. The default is the project base directory. /// [TaskAttribute("headerpath")] public DirectoryInfo HeaderPath { get { if (_headerPath == null) { return new DirectoryInfo(Project.BaseDirectory); } return _headerPath; } set { _headerPath = value; } } /// /// Path to store RC file. The default is the project base directory. /// [TaskAttribute("rcpath")] public DirectoryInfo RCPath { get { if (_rcPath == null) { return new DirectoryInfo(Project.BaseDirectory); } return _rcPath; } set { _rcPath = value; } } /// /// Input filename. /// [TaskAttribute("mcfile", Required=true)] public FileInfo McFile { get { return _mcFile; } set { _mcFile = value; } } #endregion Public Instance Properties #region Override implementation of ExternalProgramBase /// /// Gets the filename of the external program to start. /// /// /// The filename of the external program. /// public override string ProgramFileName { get { return Name; } } /// /// Gets the command-line arguments for the external program. /// /// /// The command-line arguments for the external program. /// public override string ProgramArguments { get { string str = ""; if (Verbose) { str += "/v "; } if (HeaderPath != null) { str += string.Format(CultureInfo.InvariantCulture, "-h \"{0}\" ", HeaderPath.FullName); } if (RCPath != null) { str += string.Format(CultureInfo.InvariantCulture, "-r \"{0}\" ", RCPath.FullName); } if (Options != null) { str += string.Format(CultureInfo.InvariantCulture, "{0} ", Options); } str += string.Format(CultureInfo.InvariantCulture, "\"{0}\" ", McFile.FullName); return str.ToString(); } } #endregion Override implementation of ExternalProgramBase #region Override implementation of Task /// /// Compiles the sources. /// protected override void ExecuteTask() { string header = Path.Combine(HeaderPath.FullName, Path.GetFileNameWithoutExtension(McFile.FullName)) + ".h"; string rc = Path.Combine(RCPath.FullName, Path.GetFileNameWithoutExtension(McFile.FullName)) + ".rc"; if (!NeedsCompiling(header) && !NeedsCompiling(rc)) { Log(Level.Info, "Target(s) up-to-date, not compiling '{0}'.", McFile.FullName); } else { Log(Level.Info, "Target out of date, compiling '{0}'.", McFile.FullName); if (HeaderPath != null) { Log(Level.Info, "Header file to '{0}'.", HeaderPath.FullName); } if (RCPath != null) { Log(Level.Info, "RC file to '{0}'.", RCPath.FullName); } Log(Level.Info, ""); base.ExecuteTask(); } } #endregion Override implementation of Task #region Private Instance Methods /// /// Determine if source files need re-building. /// private bool NeedsCompiling(string destinationFile) { if (McFile.Exists) { FileInfo dstInfo = new FileInfo(Project.GetFullPath(destinationFile)); if ((!dstInfo.Exists) || (McFile.LastWriteTime > dstInfo.LastWriteTime)) { return true; } else { return false; } } else { // if the source file doesn't exist, let the compiler throw the error Log(Level.Info, "Source file '{0}' doesn't exist!", McFile.FullName); return true; } } #endregion Private Instance Methods } } #if unused Microsoft (R) Message Compiler Version 1.00.5239 Copyright (c) Microsoft Corp 1992-1995. All rights reserved. usage: MC [-?vcdwso] [-m maxmsglen] [-h dirspec] [-e extension] [-r dirspec] [-x dbgFileSpec] [-u] [-U] filename.mc -? - displays this message -v - gives verbose output. -c - sets the Customer bit in all the message Ids. -d - FACILTY and SEVERITY values in header file in decimal. Sets message values in header to decimal initially. -w - warns if message text contains non-OS/2 compatible inserts. -s - insert symbolic name as first line of each message. -o - generate OLE2 header file (use HRESULT definition instead of status code definition) -m maxmsglen - generate a warning if the size of any message exceeds maxmsglen characters. -h pathspec - gives the path of where to create the C include file Default is .\ -e extension - Specify the extension for the header file. From 1 - 3 chars. -r pathspec - gives the path of where to create the RC include file and the binary message resource files it includes. Default is .\ -x pathspec - gives the path of where to create the .dbg C include file that maps message Ids to their symbolic name. -u - input file is Unicode. -U - messages in .BIN file should be Unicode. filename.mc - gives the names of a message text file to compile. Generated files have the Archive bit cleared. #endif