// 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 // // Gerry Shaw (gerry_shaw@yahoo.com) // Mike Krueger (mike@icsharpcode.net) // Gert Driesen (gert.driesen@ardatis.com) // Ian MacLean (ian_maclean@another.com) // Giuseppe Greco (giuseppe.greco@agamura.com) using System; using System.Globalization; using System.IO; using System.Text.RegularExpressions; using NAnt.Core; using NAnt.Core.Attributes; using NAnt.Core.Types; using NAnt.Core.Util; using NAnt.DotNet.Types; namespace NAnt.DotNet.Tasks { /// /// Compiles C# programs. /// /// /// /// In order to have generate manifest resource names /// that match those generated by Microsoft Visual Studio.NET, the value of /// the attribute of the <> /// element should match the "Default Namespace" of the C# project, and the /// value of the attribute /// should be set to "". /// /// /// /// Compile a "HelloWorld" application, including embedded resources. /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ]]> /// /// [TaskName("csc")] [ProgramLocation(LocationType.FrameworkDir)] public class CscTask : CompilerBase { #region Private Instance Fields private DebugOutput _debugOutput = DebugOutput.None; private FileInfo _docFile; private int _fileAlign; private bool _nostdlib; private bool _noconfig; private bool _checked; private bool _unsafe; private bool _optimize; private string _warningLevel; private string _codepage; private string _baseAddress; private string _platform; private string _langVersion; // framework configuration settings private bool _supportsDocGeneration = true; private bool _supportsPlatform; private bool _supportsLangVersion; #endregion Private Instance Fields #region Private Static Fields private static Regex _classNameRegex = new Regex(@"^((?/\*.*?(\*/|$))|[\s\.\{]+|class\s+(?\w+)|(?\w+))*"); private static Regex _namespaceRegex = new Regex(@"^((?/\*.*?(\*/|$))|[\s\.\{]+|namespace\s+(?(\w+(\.\w+)*)+)|(?\w+))*"); #endregion Private Static Fields #region Public Instance Properties /// /// The preferred base address at which to load a DLL. The default base /// address for a DLL is set by the .NET Framework common language /// runtime. /// /// /// The preferred base address at which to load a DLL. /// /// /// This address can be specified as a decimal, hexadecimal, or octal /// number. /// [TaskAttribute("baseaddress")] public string BaseAddress { get { return _baseAddress; } set { _baseAddress = StringUtils.ConvertEmptyToNull(value); } } /// /// Specifies the type of debugging information generated by the /// compiler. The default is . /// [TaskAttribute("debug")] public DebugOutput DebugOutput { get { return _debugOutput; } set { _debugOutput = value; } } /// /// No longer expose this to build authors. Use /// instead. /// public override bool Debug { get { return DebugOutput != DebugOutput.None; } set { DebugOutput = DebugOutput.Enable; } } /// /// The name of the XML documentation file to generate. /// /// /// /// Corresponds with the /doc: flag. /// /// [TaskAttribute("doc")] public FileInfo DocFile { get { return _docFile; } set { _docFile = value; } } /// /// Specifies the size of sections in the output file. Valid values are /// 512, 1024, 2048, 4096, and 8192. /// /// /// The size of sections in the output file. /// [TaskAttribute("filealign")] [Int32Validator(512, 8192)] public int FileAlign { get { return _fileAlign; } set { _fileAlign = value; } } /// /// Instructs the compiler not to import mscorlib.dll. The default is /// . /// /// /// /// Corresponds with the /nostdlib[+|-] flag. /// /// [FrameworkConfigurable("nostdlib")] [TaskAttribute("nostdlib")] [BooleanValidator()] public bool NoStdLib { get { return _nostdlib; } set { _nostdlib = value; } } /// /// Instructs the compiler not to use implicit references to assemblies. /// The default is . /// /// /// /// Corresponds with the /noconfig flag. /// /// [FrameworkConfigurable("noconfig")] [TaskAttribute("noconfig")] [BooleanValidator()] public bool NoConfig { get { return _noconfig; } set { _noconfig = value; } } /// /// Specifies whether an integer arithmetic statement that is not in /// the scope of the checked or unchecked keywords and /// that results in a value outside the range of the data type should /// cause a run-time exception. The default is . /// /// /// /// Corresponds with the /checked[+|-] flag. /// /// [TaskAttribute("checked")] [BooleanValidator()] public bool Checked { get { return _checked; } set { _checked = value; } } /// /// Instructs the compiler to allow code that uses the unsafe /// keyword. The default is . /// /// /// /// Corresponds with the /unsafe[+|-] flag. /// /// [TaskAttribute("unsafe")] [BooleanValidator()] public bool Unsafe { get { return _unsafe; } set { _unsafe = value; } } /// /// Causes the compiler to only accept syntax that is included in a /// given specification. /// /// /// /// Corresponds with the /langversion flag. /// /// [TaskAttribute("langversion")] public string LangVersion { get { return _langVersion; } set { _langVersion = StringUtils.ConvertEmptyToNull(value); } } /// /// Specifies whether the compiler should perform optimizations to the /// make output files smaller, faster, and more effecient. The default /// is . /// /// /// if the compiler should perform optimizations; /// otherwise, . /// /// /// /// Corresponds with the /optimize[+|-] flag. /// /// [TaskAttribute("optimize")] [BooleanValidator()] public bool Optimize { get { return _optimize; } set { _optimize = value; } } /// /// Specifies which platform version of common language runtime (CLR) /// can run the output file. /// /// /// The platform version of common language runtime (CLR) that can run /// the output file. /// /// /// /// Corresponds with the /platform flag. /// /// [TaskAttribute("platform")] public string Platform { get { return _platform; } set { _platform = StringUtils.ConvertEmptyToNull(value); } } /// /// Specifies the warning level for the compiler to display. Valid values /// are 0-4. The default is 4. /// /// /// The warning level for the compiler to display. /// /// /// /// Corresponds with the /warn flag. /// /// [TaskAttribute("warninglevel")] [Int32Validator(0, 4)] public string WarningLevel { get { return _warningLevel; } set { _warningLevel = StringUtils.ConvertEmptyToNull(value); } } /// /// Specifies the code page to use for all source code files in the /// compilation. /// /// /// /// Corresponds with the /codepage flag. /// /// [TaskAttribute("codepage")] public string Codepage { get { return _codepage; } set { _codepage = StringUtils.ConvertEmptyToNull(value); } } /// /// Specifies whether the compiler for the active target framework /// supports generation of XML Documentation file. The default is /// . /// [FrameworkConfigurable("supportsdocgeneration")] public bool SupportsDocGeneration { get { return _supportsDocGeneration; } set { _supportsDocGeneration = value; } } /// /// Specifies whether the compiler for the active target framework /// supports limiting the platform on which the compiled code can run. /// The default is . /// [FrameworkConfigurable("supportsplatform")] public bool SupportsPlatform { get { return _supportsPlatform; } set { _supportsPlatform = value; } } /// /// Specifies whether the compiler for the active target framework /// supports accepting only a specific language syntax. /// The default is . /// [FrameworkConfigurable("supportslangversion")] public bool SupportsLangVersion { get { return _supportsLangVersion; } set { _supportsLangVersion = value; } } #endregion Public Instance Properties #region Override implementation of CompilerBase /// /// Writes the compiler options to the specified . /// /// to which the compiler options should be written. protected override void WriteOptions(TextWriter writer) { // causes the compiler to specify the full path of the file in which // an error was found WriteOption(writer, "fullpaths"); // the base address for the DLL if (BaseAddress != null) { WriteOption(writer, "baseaddress", BaseAddress); } // XML documentation if (DocFile != null) { if (SupportsDocGeneration) { WriteOption(writer, "doc", DocFile.FullName); } else { Log(Level.Warning, ResourceUtils.GetString("String_CompilerDoesNotSupportXmlDoc"), Project.TargetFramework.Description); } } // langversion if (LangVersion != null) { if (SupportsLangVersion) { WriteOption(writer, "langversion", LangVersion); } else { Log(Level.Warning, ResourceUtils.GetString("String_CompilerDoesNotSupportLangVersion"), Project.TargetFramework.Description); } } // platform if (Platform != null) { if (SupportsPlatform) { WriteOption(writer, "platform", Platform); } else { Log(Level.Warning, ResourceUtils.GetString("String_CompilerDoesNotSupportPlatform"), Project.TargetFramework.Description); } } // handle debug builds. switch (DebugOutput) { case DebugOutput.None: break; case DebugOutput.Enable: WriteOption(writer, "debug"); WriteOption(writer, "define", "DEBUG"); WriteOption(writer, "define", "TRACE"); break; case DebugOutput.Full: WriteOption(writer, "debug"); break; case DebugOutput.PdbOnly: WriteOption(writer, "debug", "pdbonly"); break; default: throw new BuildException(string.Format(CultureInfo.InvariantCulture, ResourceUtils.GetString("NA2011"), DebugOutput), Location); } if (FileAlign > 0) { WriteOption(writer, "filealign", FileAlign.ToString(CultureInfo.InvariantCulture)); } if (NoStdLib) { WriteOption(writer, "nostdlib"); } if (Checked) { WriteOption(writer, "checked"); } if (Unsafe) { WriteOption(writer, "unsafe"); } if (Optimize) { WriteOption(writer, "optimize"); } if (WarningLevel != null) { WriteOption(writer, "warn", WarningLevel); } if (Codepage != null) { WriteOption(writer, "codepage", Codepage); } if (NoConfig && !Arguments.Contains("/noconfig")) { Arguments.Add(new Argument("/noconfig")); } } /// /// Determines whether compilation is needed. /// protected override bool NeedsCompiling() { if (DocFile != null && SupportsDocGeneration) { if (!DocFile.Exists) { Log(Level.Verbose, ResourceUtils.GetString("String_DocFileDoesNotExist"), DocFile.FullName); return true; } } return base.NeedsCompiling(); } /// /// Gets the file extension required by the current compiler. /// /// /// For the C# compiler, the file extension is always cs. /// public override string Extension { get { return "cs"; } } /// /// Gets the class name regular expression for the language of the /// current compiler. /// /// /// Class name regular expression for the language of the current /// compiler. /// protected override Regex ClassNameRegex { get { return _classNameRegex; } } /// /// Gets the namespace regular expression for the language of the current compiler. /// /// /// Namespace regular expression for the language of the current /// compiler. /// protected override Regex NamespaceRegex { get { return _namespaceRegex; } } #endregion Override implementation of CompilerBase } }