예제 #1
0
        public override Microsoft.CodeAnalysis.ParseOptions CreateParseOptions(DotNetProjectConfiguration configuration)
        {
            var symbols = GetDefineSymbols();

            if (configuration != null)
            {
                symbols = symbols.Concat(configuration.GetDefineSymbols()).Distinct();
            }
            return(new Microsoft.CodeAnalysis.CSharp.CSharpParseOptions(
                       GetRoslynLanguageVersion(langVersion),
                       Microsoft.CodeAnalysis.DocumentationMode.Parse,
                       Microsoft.CodeAnalysis.SourceCodeKind.Regular,
                       ImmutableArray <string> .Empty.AddRange(symbols)
                       ));
        }
        public override ParseOptions CreateParseOptions(DotNetProjectConfiguration configuration)
        {
            var symbols = GetDefineSymbols();

            if (configuration != null)
            {
                symbols = symbols.Concat(configuration.GetDefineSymbols()).Distinct();
            }
            LanguageVersionFacts.TryParse(langVersion, out LanguageVersion lv);

            return(new CSharpParseOptions(
                       lv,
                       DocumentationMode.Parse,
                       SourceCodeKind.Regular,
                       ImmutableArray <string> .Empty.AddRange(symbols)
                       ));
        }
		public override Microsoft.CodeAnalysis.ParseOptions CreateParseOptions (DotNetProjectConfiguration configuration)
		{
			var symbols = GetDefineSymbols ();
			if (configuration != null)
				symbols = symbols.Concat (configuration.GetDefineSymbols ()).Distinct ();
			return new Microsoft.CodeAnalysis.CSharp.CSharpParseOptions (
				GetRoslynLanguageVersion (langVersion),
				Microsoft.CodeAnalysis.DocumentationMode.Parse,
				Microsoft.CodeAnalysis.SourceCodeKind.Regular,
				ImmutableArray<string>.Empty.AddRange (symbols)
			);
		}
예제 #4
0
        public static BuildResult Compile(ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, ProgressMonitor monitor)
        {
            var compilerParameters = (CSharpCompilerParameters)configuration.CompilationParameters ?? new CSharpCompilerParameters();
            var projectParameters  = (CSharpProject)configuration.ParentItem;

            FilePath outputName       = configuration.CompiledOutputName;
            string   responseFileName = Path.GetTempFileName();

            //make sure that the output file is writable
            if (File.Exists(outputName))
            {
                bool isWriteable = false;
                int  count       = 0;
                do
                {
                    try {
                        outputName.MakeWritable();
                        using (var stream = File.OpenWrite(outputName)) {
                            isWriteable = true;
                        }
                    } catch (Exception) {
                        Thread.Sleep(20);
                    }
                } while (count++ < 5 && !isWriteable);
                if (!isWriteable)
                {
                    MessageService.ShowError(string.Format(GettextCatalog.GetString("Can't lock file: {0}."), outputName));
                    return(null);
                }
            }

            //get the runtime
            TargetRuntime runtime = MonoDevelop.Core.Runtime.SystemAssemblyService.DefaultRuntime;
            DotNetProject project = configuration.ParentItem as DotNetProject;

            if (project != null)
            {
                runtime = project.TargetRuntime;
            }

            //get the compiler name
            string compilerName;

            try {
                compilerName = GetCompilerName(runtime, configuration.TargetFramework);
            } catch (Exception e) {
                string message = "Could not obtain a C# compiler";
                monitor.ReportError(message, e);
                return(null);
            }

            var sb = new StringBuilder();

            HashSet <string> alreadyAddedReference = new HashSet <string> ();

            var monoRuntime = runtime as MonoTargetRuntime;

            if (!compilerParameters.NoStdLib && (monoRuntime == null || monoRuntime.HasMultitargetingMcs))
            {
                string corlib = project.AssemblyContext.GetAssemblyFullName("mscorlib", project.TargetFramework);
                if (corlib != null)
                {
                    corlib = project.AssemblyContext.GetAssemblyLocation(corlib, project.TargetFramework);
                }
                if (corlib == null)
                {
                    var br = new BuildResult();
                    br.AddError(string.Format("Could not find mscorlib for framework {0}", project.TargetFramework.Id));
                    return(br);
                }
                AppendQuoted(sb, "/r:", corlib);
                sb.AppendLine("-nostdlib");
            }

            List <string> gacRoots = new List <string> ();

            sb.AppendFormat("\"/out:{0}\"", outputName);
            sb.AppendLine();

            foreach (ProjectReference lib in projectItems.GetAll <ProjectReference> ())
            {
                if (lib.ReferenceType == ReferenceType.Project)
                {
                    var ownerProject = lib.OwnerProject;
                    if (ownerProject != null)
                    {
                        var parentSolution = ownerProject.ParentSolution;
                        if (parentSolution != null && !(lib.ResolveProject(parentSolution) is DotNetProject))
                        {
                            continue;
                        }
                    }
                }
                string refPrefix = string.IsNullOrEmpty(lib.Aliases) ? "" : lib.Aliases + "=";
                foreach (string fileName in lib.GetReferencedFileNames(configSelector))
                {
                    switch (lib.ReferenceType)
                    {
                    case ReferenceType.Package:
                        SystemPackage pkg = lib.Package;
                        if (pkg == null)
                        {
                            string msg = string.Format(GettextCatalog.GetString("{0} could not be found or is invalid."), lib.Reference);
                            monitor.ReportWarning(msg);
                            continue;
                        }

                        if (alreadyAddedReference.Add(fileName))
                        {
                            AppendQuoted(sb, "/r:", refPrefix + fileName);
                        }

                        if (pkg.GacRoot != null && !gacRoots.Contains(pkg.GacRoot))
                        {
                            gacRoots.Add(pkg.GacRoot);
                        }
                        if (!string.IsNullOrEmpty(pkg.Requires))
                        {
                            foreach (string requiredPackage in pkg.Requires.Split(' '))
                            {
                                SystemPackage rpkg = runtime.AssemblyContext.GetPackage(requiredPackage);
                                if (rpkg == null)
                                {
                                    continue;
                                }
                                foreach (SystemAssembly assembly in rpkg.Assemblies)
                                {
                                    if (alreadyAddedReference.Add(assembly.Location))
                                    {
                                        AppendQuoted(sb, "/r:", assembly.Location);
                                    }
                                }
                            }
                        }
                        break;

                    default:
                        if (alreadyAddedReference.Add(fileName))
                        {
                            AppendQuoted(sb, "/r:", refPrefix + fileName);
                        }
                        break;
                    }
                }
            }

            if (alreadyAddedReference.Any(reference => SystemAssemblyService.ContainsReferenceToSystemRuntime(reference)))
            {
                LoggingService.LogInfo("Found PCLv2 assembly.");
                var facades = runtime.FindFacadeAssembliesForPCL(project.TargetFramework);
                foreach (var facade in facades)
                {
                    AppendQuoted(sb, "/r:", facade);
                }
            }

            string sysCore = project.AssemblyContext.GetAssemblyFullName("System.Core", project.TargetFramework);

            if (sysCore != null && !alreadyAddedReference.Contains(sysCore))
            {
                var asm = project.AssemblyContext.GetAssemblyFromFullName(sysCore, null, project.TargetFramework);
                if (asm != null)
                {
                    AppendQuoted(sb, "/r:", asm.Location);
                }
            }

            sb.AppendLine("/nologo");
            sb.Append("/warn:"); sb.Append(compilerParameters.WarningLevel.ToString());
            sb.AppendLine();

            if (configuration.SignAssembly)
            {
                if (File.Exists(configuration.AssemblyKeyFile))
                {
                    AppendQuoted(sb, "/keyfile:", configuration.AssemblyKeyFile);
                }
                if (configuration.DelaySign)
                {
                    sb.AppendLine("/delaySign");
                }
            }

            var debugType = configuration.DebugType;

            if (string.IsNullOrEmpty(debugType))
            {
                debugType = configuration.DebugSymbols ? "full" : "none";
            }
            else if (string.Equals(debugType, "pdbonly", StringComparison.OrdinalIgnoreCase))
            {
                //old Mono compilers don't support pdbonly
                if (monoRuntime != null && !monoRuntime.HasMultitargetingMcs)
                {
                    debugType = "full";
                }
            }
            if (!string.Equals(debugType, "none", StringComparison.OrdinalIgnoreCase))
            {
                sb.AppendLine("/debug:" + debugType);
            }

            if (compilerParameters.LangVersion != LangVersion.Default)
            {
                var langVersionString = CSharpCompilerParameters.TryLangVersionToString(compilerParameters.LangVersion);
                if (langVersionString == null)
                {
                    string message = "Invalid LangVersion enum value '" + compilerParameters.LangVersion.ToString() + "'";
                    monitor.ReportError(message, null);
                    LoggingService.LogError(message);
                    return(null);
                }
                sb.AppendLine("/langversion:" + langVersionString);
            }

            // mcs default is + but others might not be
            if (compilerParameters.Optimize)
            {
                sb.AppendLine("/optimize+");
            }
            else
            {
                sb.AppendLine("/optimize-");
            }

            bool hasWin32Res = !string.IsNullOrEmpty(projectParameters.Win32Resource) && File.Exists(projectParameters.Win32Resource);

            if (hasWin32Res)
            {
                AppendQuoted(sb, "/win32res:", projectParameters.Win32Resource);
            }

            if (!string.IsNullOrEmpty(projectParameters.Win32Icon) && File.Exists(projectParameters.Win32Icon))
            {
                if (hasWin32Res)
                {
                    monitor.ReportWarning("Both Win32 icon and Win32 resource cannot be specified. Ignoring the icon.");
                }
                else
                {
                    AppendQuoted(sb, "/win32icon:", projectParameters.Win32Icon);
                }
            }

            if (projectParameters.CodePage != 0)
            {
                sb.AppendLine("/codepage:" + projectParameters.CodePage);
            }
            else if (runtime is MonoTargetRuntime)
            {
                sb.AppendLine("/codepage:utf8");
            }

            if (compilerParameters.UnsafeCode)
            {
                sb.AppendLine("-unsafe");
            }
            if (compilerParameters.NoStdLib)
            {
                sb.AppendLine("-nostdlib");
            }

            if (!string.IsNullOrEmpty(compilerParameters.PlatformTarget) && compilerParameters.PlatformTarget.ToLower() != "anycpu")
            {
                //HACK: to ignore the platform flag for Mono <= 2.4, because gmcs didn't support it
                if (runtime.RuntimeId == "Mono" && runtime.AssemblyContext.GetAssemblyLocation("Mono.Debugger.Soft", null) == null)
                {
                    LoggingService.LogWarning("Mono runtime '" + runtime.DisplayName +
                                              "' appears to be too old to support the 'platform' C# compiler flag.");
                }
                else
                {
                    sb.AppendLine("/platform:" + compilerParameters.PlatformTarget);
                }
            }

            if (compilerParameters.TreatWarningsAsErrors)
            {
                sb.AppendLine("-warnaserror");
                if (!string.IsNullOrEmpty(compilerParameters.WarningsNotAsErrors))
                {
                    sb.AppendLine("-warnaserror-:" + compilerParameters.WarningsNotAsErrors);
                }
            }

            foreach (var define in configuration.GetDefineSymbols())
            {
                AppendQuoted(sb, "/define:", define);
                sb.AppendLine();
            }

            CompileTarget ctarget = configuration.CompileTarget;

            if (!string.IsNullOrEmpty(projectParameters.MainClass))
            {
                sb.AppendLine("/main:" + projectParameters.MainClass);
                // mcs does not allow providing a Main class when compiling a dll
                // As a workaround, we compile as WinExe (although the output will still
                // have a .dll extension).
                if (ctarget == CompileTarget.Library)
                {
                    ctarget = CompileTarget.WinExe;
                }
            }

            switch (ctarget)
            {
            case CompileTarget.Exe:
                sb.AppendLine("/t:exe");
                break;

            case CompileTarget.WinExe:
                sb.AppendLine("/t:winexe");
                break;

            case CompileTarget.Library:
                sb.AppendLine("/t:library");
                break;
            }

            foreach (ProjectFile finfo in projectItems.GetAll <ProjectFile> ())
            {
                if (finfo.Subtype == Subtype.Directory)
                {
                    continue;
                }

                switch (finfo.BuildAction)
                {
                case "Compile":
                    AppendQuoted(sb, "", finfo.Name);
                    break;

                case "EmbeddedResource":
                    string fname = finfo.Name;
                    if (string.Compare(Path.GetExtension(fname), ".resx", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        fname = Path.ChangeExtension(fname, ".resources");
                    }
                    sb.Append('"'); sb.Append("/res:");
                    sb.Append(fname); sb.Append(','); sb.Append(finfo.ResourceId);
                    sb.Append('"'); sb.AppendLine();
                    break;

                default:
                    continue;
                }
            }
            if (!compilerParameters.DocumentationFile.IsNullOrEmpty)
            {
                AppendQuoted(sb, "/doc:", compilerParameters.DocumentationFile);
            }

            if (!string.IsNullOrEmpty(compilerParameters.NoWarnings))
            {
                AppendQuoted(sb, "/nowarn:", compilerParameters.NoWarnings);
            }

            if (runtime.RuntimeId == "MS.NET")
            {
                sb.AppendLine("/fullpaths");
                sb.AppendLine("/utf8output");
            }

            string output = "";
            string error  = "";

            File.WriteAllText(responseFileName, sb.ToString());

            monitor.Log.WriteLine(compilerName + " /noconfig " + sb.ToString().Replace('\n', ' '));

            // Dummy projects created for single files have no filename
            // and so no BaseDirectory.
            string workingDir = null;

            if (configuration.ParentItem != null)
            {
                workingDir = configuration.ParentItem.BaseDirectory;
            }

            LoggingService.LogInfo(compilerName + " " + sb);

            ExecutionEnvironment envVars = runtime.GetToolsExecutionEnvironment(project.TargetFramework);
            string cargs = "/noconfig @\"" + responseFileName + "\"";

            int exitCode = DoCompilation(monitor, compilerName, cargs, workingDir, envVars, gacRoots, ref output, ref error);

            BuildResult result = ParseOutput(workingDir, output, error);

            if (result.CompilerOutput.Trim().Length != 0)
            {
                monitor.Log.WriteLine(result.CompilerOutput);
            }

            //if compiler crashes, output entire error string
            if (result.ErrorCount == 0 && exitCode != 0)
            {
                try {
                    monitor.Log.Write(File.ReadAllText(error));
                } catch (IOException) {
                }
                result.AddError("The compiler appears to have crashed. Check the build output pad for details.");
                LoggingService.LogError("C# compiler crashed. Response file '{0}', stdout file '{1}', stderr file '{2}'",
                                        responseFileName, output, error);
            }
            else
            {
                FileService.DeleteFile(responseFileName);
                FileService.DeleteFile(output);
                FileService.DeleteFile(error);
            }
            return(result);
        }
		public static BuildResult Compile (ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, IProgressMonitor monitor)
		{
			var compilerParameters = (CSharpCompilerParameters)configuration.CompilationParameters ?? new CSharpCompilerParameters ();
			var projectParameters = (CSharpProjectParameters)configuration.ProjectParameters ?? new CSharpProjectParameters ();
			
			FilePath outputName = configuration.CompiledOutputName;
			string responseFileName = Path.GetTempFileName ();

			//make sure that the output file is writable
			if (File.Exists (outputName)) {
				bool isWriteable = false;
				int count = 0;
				do {
					try {
						outputName.MakeWritable ();
						using (var stream = File.OpenWrite (outputName)) {
							isWriteable = true;
						}
					} catch (Exception) {
						Thread.Sleep (20);
					}
				} while (count++ < 5 && !isWriteable);
				if (!isWriteable) {
					MessageService.ShowError (string.Format (GettextCatalog.GetString ("Can't lock file: {0}."), outputName));
					return null;
				}
			}

			//get the runtime
			TargetRuntime runtime = MonoDevelop.Core.Runtime.SystemAssemblyService.DefaultRuntime;
			DotNetProject project = configuration.ParentItem as DotNetProject;
			if (project != null)
				runtime = project.TargetRuntime;

			//get the compiler name
			string compilerName;
			try {
				compilerName = GetCompilerName (runtime, configuration.TargetFramework);
			} catch (Exception e) {
				string message = "Could not obtain a C# compiler";
				monitor.ReportError (message, e);
				return null;
			}

			var sb = new StringBuilder ();

			HashSet<string> alreadyAddedReference = new HashSet<string> ();

			var monoRuntime = runtime as MonoTargetRuntime;
			if (!compilerParameters.NoStdLib && (monoRuntime == null || monoRuntime.HasMultitargetingMcs)) {
				string corlib = project.AssemblyContext.GetAssemblyFullName ("mscorlib", project.TargetFramework);
				if (corlib != null) {
					corlib = project.AssemblyContext.GetAssemblyLocation (corlib, project.TargetFramework);
				}
				if (corlib == null) {
					var br = new BuildResult ();
					br.AddError (string.Format ("Could not find mscorlib for framework {0}", project.TargetFramework.Id));
					return br;
				}
				AppendQuoted (sb, "/r:", corlib);
				sb.AppendLine ("-nostdlib");
			}

			List<string> gacRoots = new List<string> ();
			sb.AppendFormat ("\"/out:{0}\"", outputName);
			sb.AppendLine ();
			
			foreach (ProjectReference lib in projectItems.GetAll <ProjectReference> ()) {
				if (lib.ReferenceType == ReferenceType.Project) {
					var ownerProject = lib.OwnerProject;
					if (ownerProject != null) {
						var parentSolution = ownerProject.ParentSolution;
						if (parentSolution != null && !(parentSolution.FindProjectByName (lib.Reference) is DotNetProject))
							continue;
					}
				} 
				string refPrefix = string.IsNullOrEmpty (lib.Aliases) ? "" : lib.Aliases + "=";
				foreach (string fileName in lib.GetReferencedFileNames (configSelector)) {
					switch (lib.ReferenceType) {
					case ReferenceType.Package:
						SystemPackage pkg = lib.Package;
						if (pkg == null) {
							string msg = string.Format (GettextCatalog.GetString ("{0} could not be found or is invalid."), lib.Reference);
							monitor.ReportWarning (msg);
							continue;
						}

						if (alreadyAddedReference.Add (fileName))
							AppendQuoted (sb, "/r:", refPrefix + fileName);
						
						if (pkg.GacRoot != null && !gacRoots.Contains (pkg.GacRoot))
							gacRoots.Add (pkg.GacRoot);
						if (!string.IsNullOrEmpty (pkg.Requires)) {
							foreach (string requiredPackage in pkg.Requires.Split(' ')) {
								SystemPackage rpkg = runtime.AssemblyContext.GetPackage (requiredPackage);
								if (rpkg == null)
									continue;
								foreach (SystemAssembly assembly in rpkg.Assemblies) {
									if (alreadyAddedReference.Add (assembly.Location))
										AppendQuoted (sb, "/r:", assembly.Location);
								}
							}
						}
						break;
					default:
						if (alreadyAddedReference.Add (fileName))
							AppendQuoted (sb, "/r:", refPrefix + fileName);
						break;
					}
				}
			}

			if (alreadyAddedReference.Any (reference => SystemAssemblyService.ContainsReferenceToSystemRuntime (reference))) {
				LoggingService.LogInfo ("Found PCLv2 assembly.");
				var facades = runtime.FindFacadeAssembliesForPCL (project.TargetFramework);
				foreach (var facade in facades)
					AppendQuoted (sb, "/r:", facade);
			}

			string sysCore = project.AssemblyContext.GetAssemblyFullName ("System.Core", project.TargetFramework);
			if (sysCore != null && !alreadyAddedReference.Contains (sysCore)) {
				var asm = project.AssemblyContext.GetAssemblyFromFullName (sysCore, null, project.TargetFramework);
				if (asm != null)
					AppendQuoted (sb, "/r:", asm.Location);
			}
			
			sb.AppendLine ("/nologo");
			sb.Append ("/warn:");sb.Append (compilerParameters.WarningLevel.ToString ());
			sb.AppendLine ();
			
			if (configuration.SignAssembly) {
				if (File.Exists (configuration.AssemblyKeyFile))
					AppendQuoted (sb, "/keyfile:", configuration.AssemblyKeyFile);
				if (configuration.DelaySign)
					sb.AppendLine ("/delaySign");
			}

			var debugType = compilerParameters.DebugType;
			if (string.IsNullOrEmpty (debugType)) {
				debugType = configuration.DebugMode ? "full" : "none";
			} else if (string.Equals (debugType, "pdbonly", StringComparison.OrdinalIgnoreCase)) {
				//old Mono compilers don't support pdbonly
				if (monoRuntime != null && !monoRuntime.HasMultitargetingMcs)
					debugType = "full";
			}
			if (!string.Equals (debugType, "none", StringComparison.OrdinalIgnoreCase)) {
					sb.AppendLine ("/debug:" + debugType);
			}

			if (compilerParameters.LangVersion != LangVersion.Default) {
				var langVersionString = CSharpCompilerParameters.TryLangVersionToString (compilerParameters.LangVersion);
				if (langVersionString == null) {
					string message = "Invalid LangVersion enum value '" + compilerParameters.LangVersion.ToString () + "'";
					monitor.ReportError (message, null);
					LoggingService.LogError (message);
					return null;
				}
				sb.AppendLine ("/langversion:" + langVersionString);
			}
			
			// mcs default is + but others might not be
			if (compilerParameters.Optimize)
				sb.AppendLine ("/optimize+");
			else
				sb.AppendLine ("/optimize-");
			
			bool hasWin32Res = !string.IsNullOrEmpty (projectParameters.Win32Resource) && File.Exists (projectParameters.Win32Resource);
			if (hasWin32Res) 
				AppendQuoted (sb, "/win32res:", projectParameters.Win32Resource);
			
			if (!string.IsNullOrEmpty (projectParameters.Win32Icon) && File.Exists (projectParameters.Win32Icon)) {
				if (hasWin32Res) {
					monitor.ReportWarning ("Both Win32 icon and Win32 resource cannot be specified. Ignoring the icon.");
				} else {
					AppendQuoted (sb, "/win32icon:", projectParameters.Win32Icon);
				}
			}
			
			if (projectParameters.CodePage != 0)
				sb.AppendLine ("/codepage:" + projectParameters.CodePage);
			else if (runtime is MonoTargetRuntime)
				sb.AppendLine ("/codepage:utf8");
			
			if (compilerParameters.UnsafeCode) 
				sb.AppendLine ("-unsafe");
			if (compilerParameters.NoStdLib) 
				sb.AppendLine ("-nostdlib");
			
			if (!string.IsNullOrEmpty (compilerParameters.PlatformTarget) && compilerParameters.PlatformTarget.ToLower () != "anycpu") {
				//HACK: to ignore the platform flag for Mono <= 2.4, because gmcs didn't support it
				if (runtime.RuntimeId == "Mono" && runtime.AssemblyContext.GetAssemblyLocation ("Mono.Debugger.Soft", null) == null) {
					LoggingService.LogWarning ("Mono runtime '" + runtime.DisplayName + 
					                           "' appears to be too old to support the 'platform' C# compiler flag.");
				} else {
					sb.AppendLine ("/platform:" + compilerParameters.PlatformTarget);
				}
			}

			if (compilerParameters.TreatWarningsAsErrors) {
				sb.AppendLine ("-warnaserror");
				if (!string.IsNullOrEmpty (compilerParameters.WarningsNotAsErrors))
					sb.AppendLine ("-warnaserror-:" + compilerParameters.WarningsNotAsErrors);
			}

			foreach (var define in configuration.GetDefineSymbols ()) {
				AppendQuoted (sb, "/define:", define);
				sb.AppendLine ();
			}

			CompileTarget ctarget = configuration.CompileTarget;
			
			if (!string.IsNullOrEmpty (projectParameters.MainClass)) {
				sb.AppendLine ("/main:" + projectParameters.MainClass);
				// mcs does not allow providing a Main class when compiling a dll
				// As a workaround, we compile as WinExe (although the output will still
				// have a .dll extension).
				if (ctarget == CompileTarget.Library)
					ctarget = CompileTarget.WinExe;
			}
			
			switch (ctarget) {
				case CompileTarget.Exe:
					sb.AppendLine ("/t:exe");
					break;
				case CompileTarget.WinExe:
					sb.AppendLine ("/t:winexe");
					break;
				case CompileTarget.Library:
					sb.AppendLine ("/t:library");
					break;
			}
			
			foreach (ProjectFile finfo in projectItems.GetAll<ProjectFile> ()) {
				if (finfo.Subtype == Subtype.Directory)
					continue;

				switch (finfo.BuildAction) {
					case "Compile":
						AppendQuoted (sb, "", finfo.Name);
						break;
					case "EmbeddedResource":
						string fname = finfo.Name;
						if (string.Compare (Path.GetExtension (fname), ".resx", StringComparison.OrdinalIgnoreCase) == 0)
							fname = Path.ChangeExtension (fname, ".resources");
						sb.Append ('"');sb.Append ("/res:");
						sb.Append (fname);sb.Append (',');sb.Append (finfo.ResourceId);
						sb.Append ('"');sb.AppendLine ();
						break;
					default:
						continue;
				}
			}
			if (!compilerParameters.DocumentationFile.IsNullOrEmpty) 
				AppendQuoted (sb, "/doc:", compilerParameters.DocumentationFile);
			
			if (!string.IsNullOrEmpty (compilerParameters.NoWarnings)) 
				AppendQuoted (sb, "/nowarn:", compilerParameters.NoWarnings);

			if (runtime.RuntimeId == "MS.NET") {
				sb.AppendLine("/fullpaths");
				sb.AppendLine("/utf8output");
			}

			string output = "";
			string error  = "";
			
			File.WriteAllText (responseFileName, sb.ToString ());

			monitor.Log.WriteLine (compilerName + " /noconfig " + sb.ToString ().Replace ('\n',' '));

			// Dummy projects created for single files have no filename
			// and so no BaseDirectory.
			string workingDir = null;
			if (configuration.ParentItem != null)
				workingDir = configuration.ParentItem.BaseDirectory;

			LoggingService.LogInfo (compilerName + " " + sb);

			ExecutionEnvironment envVars = runtime.GetToolsExecutionEnvironment (project.TargetFramework);
			string cargs = "/noconfig @\"" + responseFileName + "\"";

			int exitCode = DoCompilation (monitor, compilerName, cargs, workingDir, envVars, gacRoots, ref output, ref error);
			
			BuildResult result = ParseOutput (workingDir, output, error);
			if (result.CompilerOutput.Trim ().Length != 0)
				monitor.Log.WriteLine (result.CompilerOutput);
			
			//if compiler crashes, output entire error string
			if (result.ErrorCount == 0 && exitCode != 0) {
				try {
					monitor.Log.Write (File.ReadAllText (error));
				} catch (IOException) {
				}
				result.AddError ("The compiler appears to have crashed. Check the build output pad for details.");
				LoggingService.LogError ("C# compiler crashed. Response file '{0}', stdout file '{1}', stderr file '{2}'",
				                         responseFileName, output, error);
			} else {
				FileService.DeleteFile (responseFileName);
				FileService.DeleteFile (output);
				FileService.DeleteFile (error);
			}
			return result;
		}