Пример #1
0
		public static BuildResult Compile (ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configurationSelector, IProgressMonitor monitor)
		{
			JavaCompilerParameters parameters = (configuration.CompilationParameters as JavaCompilerParameters) ?? new JavaCompilerParameters ();
			string outdir   = configuration.OutputDirectory;
			string options  = GenerateOptionString (configuration);
			string compiler = parameters.CompilerPath;
			if (String.IsNullOrEmpty (compiler))
				compiler = "javac";
			
			StringBuilder files = new StringBuilder ();
			foreach (ProjectFile finfo in projectItems.GetAll<ProjectFile> ()) {
				if (finfo.Subtype != Subtype.Directory && finfo.BuildAction == BuildAction.Compile) {
					files.Append (" \"");
					files.Append (finfo.Name);
					files.Append ("\"");
				}
			}

			StringBuilder classpath = new StringBuilder (parameters.ClassPath);
			AppendClasspath (classpath, GenerateReferenceStubs (monitor, configurationSelector, configuration, parameters, projectItems));
			AppendClasspath (classpath, GenerateReferenceStub (monitor, configurationSelector, configuration, new ProjectReference(ReferenceType.Gac, "mscorlib")));
			
			StringBuilder args = new StringBuilder ();
			args.Append (options.ToString ());
			if (parameters.Compiler == JavaCompiler.Gcj)
				args.Append ("-C ");
			if (classpath.Length != 0) {
				args.Append (" -classpath ");
				args.Append (classpath.ToString ());
			}
			args.Append (files.ToString ());
			args.Append (" -d ");
			args.Append (outdir);
			
			CompilerResults results = new CompilerResults (new TempFileCollection ());
			StringWriter output = new StringWriter ();
			StringWriter error = new StringWriter ();

			bool success;
			try {
				success = Compile (monitor, compiler, args.ToString (), configuration, parameters, output, error);
				ParseJavaOutput (parameters.Compiler, error.ToString(), results);
			} catch (Exception ex) {
				string errorMsg = AddinManager.CurrentLocalizer.GetString ("Execution on '{0}' failed. Make sure the Java compiler is properly installed", compiler);
				monitor.ReportError (errorMsg, ex);
				success = false;
				results.Errors.Add (new CompilerError ("", 0, 0, "", errorMsg));
			}
			
			if (success) {
				output = new StringWriter ();
				error = new StringWriter ();
				CompileToAssembly (monitor, configuration, parameters, projectItems, output, error);
				ParseIkvmOutput (parameters.Compiler, error.ToString(), results);
			}
			
			return new BuildResult (results, "");
		}
        static string GenerateReferenceStubs(IProgressMonitor monitor, ConfigurationSelector configurationSelector, DotNetProjectConfiguration configuration, JavaCompilerParameters compilerparameters, ProjectItemCollection projectItems)
        {
            StringBuilder result = new StringBuilder();

            foreach (ProjectReference reference in projectItems.GetAll <ProjectReference> ())
            {
                AppendClasspath(result, GenerateReferenceStub(monitor, configurationSelector, configuration, reference));
            }
            return(result.ToString());
        }
        static void CompileToAssembly(IProgressMonitor monitor, DotNetProjectConfiguration configuration, JavaCompilerParameters compilerparameters, ProjectItemCollection projectItems, TextWriter output, TextWriter error)
        {
            monitor.Log.WriteLine(GettextCatalog.GetString("Generating assembly ..."));

            LogTextWriter chainedError = new LogTextWriter();

            chainedError.ChainWriter(monitor.Log);
            chainedError.ChainWriter(error);

            LogTextWriter chainedOutput = new LogTextWriter();

            chainedOutput.ChainWriter(monitor.Log);
            chainedOutput.ChainWriter(output);

            string outdir   = configuration.OutputDirectory;
            string outclass = Path.Combine(outdir, configuration.OutputAssembly + ".class");
            string asm      = Path.GetFileNameWithoutExtension(outclass);

            StringBuilder args = new StringBuilder("*.class ");

            args.Append("-assembly:"); args.Append(asm);
            args.Append(" -target:"); args.Append(TargetToString(configuration.CompileTarget));
            if (configuration.DebugMode)
            {
                args.Append(" -debug");
            }
            args.Append(" -srcpath:"); args.Append(configuration.ParentItem.BaseDirectory);

            foreach (ProjectReference lib in projectItems.GetAll <ProjectReference> ())
            {
                foreach (string fileName in lib.GetReferencedFileNames(configuration.Selector))
                {
                    args.Append(" -r:"); args.Append(fileName);
                }
            }

            foreach (string fileName in new ProjectReference(ReferenceType.Gac, "mscorlib").GetReferencedFileNames(configuration.Selector))
            {
                args.Append(" -r:"); args.Append(fileName);
            }

            monitor.Log.WriteLine("ikvmc " + args);
            Process process = Runtime.ProcessService.StartProcess("ikvmc", args.ToString(), configuration.OutputDirectory, chainedOutput, chainedError, null);

            process.WaitForExit();
        }
Пример #4
0
 public BuildResult Compile(ProjectItemCollection items, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, IProgressMonitor monitor)
 {
     try
     {
         var outWriter = new StringWriter();
         var arguments = String.Join(" ", items.GetAll<ProjectFile>().Select(pf => pf.FilePath.ToString()).ToArray());
         using (var processWrapper = processStarter.StartProcess("booc", arguments, configuration.OutputDirectory.ToString(), outWriter, monitor.Log))
         {
             using (var aggregatedOperationMonitor = new AggregatedOperationMonitor(monitor, processWrapper))
             {
                 processWrapper.WaitForExit();
                 if (monitor.IsCancelRequested)
                 {
                     monitor.Log.WriteLine("Build canceled");
                     monitor.ReportError("Build canceled", null);
                 }
                 monitor.EndTask(); // TODO: Do we need this?
                 var output = outWriter.ToString();
                 var compilerResults = new CompilerResults(new TempFileCollection());
                 using (var stringReader = new StringReader(output))
                 {
                     for (var line = stringReader.ReadLine(); line != null; line = stringReader.ReadLine())
                     {
                         var error = ParseOutputLine(line);
                         if (error != null)
                         {
                             compilerResults.Errors.Add(error);
                         }
                     }
                 }
                 return new BuildResult(compilerResults, output);
             }
         }
     }
     catch (Exception ex)
     {
         monitor.Log.WriteLine(ex.ToString());
     }
     return null;
 }
        public static BuildResult Compile(ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, IProgressMonitor monitor)
        {
//			ILAsmCompilerParameters compilerParameters = (ILAsmCompilerParameters)configuration.CompilationParameters ?? new ILAsmCompilerParameters ();
            string outputName = configuration.CompiledOutputName;

            var sb = new StringBuilder();

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

            var gacRoots = new List <string> ();


            switch (configuration.CompileTarget)
            {
            case CompileTarget.WinExe:
            case CompileTarget.Exe:
                sb.Append("/exe ");
                break;

            case CompileTarget.Library:
                sb.Append("/dll ");
                break;
            }

            if (configuration.DebugMode)
            {
                sb.Append("/debug ");
            }

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

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

                default:
                    continue;
                }
            }

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

            string ilasm = configuration.TargetRuntime.GetToolPath(configuration.TargetFramework, "ilasm");

            if (ilasm == null)
            {
                var res = new BuildResult();
                res.AddError(GettextCatalog.GetString("IL compiler (ilasm) not found."));
                if (configuration.TargetRuntime is MsNetTargetRuntime)
                {
                    res.AddError(GettextCatalog.GetString("You may need to install the .NET SDK."));
                }
                return(res);
            }
            string outstr = ilasm + " " + sb;

            monitor.Log.WriteLine(outstr);

            string workingDir = ".";

            if (configuration.ParentItem != null)
            {
                workingDir = configuration.ParentItem.BaseDirectory;
                if (workingDir == null)
                {
                    // Dummy projects created for single files have no filename
                    // and so no BaseDirectory.
                    // This is a workaround for a bug in
                    // ProcessStartInfo.WorkingDirectory - not able to handle null
                    workingDir = ".";
                }
            }

            LoggingService.LogInfo("ilasm " + sb);

            var envVars  = configuration.TargetRuntime.GetToolsExecutionEnvironment(configuration.TargetFramework);
            int exitCode = DoCompilation(outstr, workingDir, envVars, gacRoots, ref output, ref error);

            BuildResult result = ParseOutput(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)
            {
                if (!string.IsNullOrEmpty(error))
                {
                    result.AddError(error);
                }
                else
                {
                    result.AddError("The compiler appears to have crashed without any error output.");
                }
            }

            FileService.DeleteFile(output);
            FileService.DeleteFile(error);
            return(result);
        }
        public static BuildResult Compile(ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, IProgressMonitor monitor)
        {
            FSharpCompilerParameters compilerParameters = (FSharpCompilerParameters)configuration.CompilationParameters ?? new FSharpCompilerParameters ();
            FSharpProjectParameters projectParameters = (FSharpProjectParameters)configuration.ProjectParameters ?? new FSharpProjectParameters ();

            string outputName       = configuration.CompiledOutputName;

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

            StringBuilder sb = new StringBuilder ();
            List<string> gacRoots = new List<string> ();
            sb.AppendFormat ("--out:{0}", outputName);
            sb.AppendLine ();

            HashSet<string> alreadyAddedReference = new HashSet<string> ();
            foreach (ProjectReference lib in projectItems.GetAll <ProjectReference> ()) {
                if (lib.ReferenceType == ReferenceType.Project && !(lib.OwnerProject.ParentSolution.FindProjectByName (lib.Reference) is DotNetProject))
                    continue;
                foreach (string fileName in lib.GetReferencedFileNames (configSelector)) {
                    switch (lib.ReferenceType) {
                    case ReferenceType.Gac:
                        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;
                        }
                        string referencedName = pkg.IsCorePackage ? Path.GetFileName (fileName) : fileName;
                        if (!alreadyAddedReference.Contains (referencedName)) {
                        alreadyAddedReference.Add (referencedName);
                            AppendQuoted (sb, "--reference:", referencedName);
                        }

                        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.Contains (assembly.Location))
                                        continue;
                                    alreadyAddedReference.Add (assembly.Location);
                                    AppendQuoted (sb, "--reference:", assembly.Location);
                                }
                            }
                        }
                        break;
                    default://
                        AppendQuoted (sb, "--reference:", fileName);
                        break;
                    }
                }
            }

            // THINK!! WNH			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.DebugMode) {
            // WNH REVIEW				sb.AppendLine ("/debug:+");
            //			sb.AppendLine ("/debug:full");
                sb.AppendLine ("-g");
            }

            // mcs default is + but others might not be   <<<<< what about FSC default??? WNH
            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)    // WNH RIP OUT???
                sb.AppendLine ("--codepage:" + projectParameters.CodePage);
            else if (runtime is MonoTargetRuntime)
                sb.AppendLine ("--utf8output");

            //			if (compilerParameters.UnsafeCode)    WNH RIP OUT??
            //				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' F# compiler flag.");
                } else {
                    sb.AppendLine ("--platform:" + compilerParameters.PlatformTarget);
                }
            }

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

            if (compilerParameters.DefineSymbols.Length > 0) {
                string define_str = string.Join (";", compilerParameters.DefineSymbols.Split (new char [] {',', ' ', ';'}, StringSplitOptions.RemoveEmptyEntries));
                if (define_str.Length > 0) {
            // WNH					AppendQuoted (sb, "--define:", define_str);  // WNH REVIEW!!!!
            // WNH					AppendQuoted (sb, "--define:", define_str);  // WNH REVIEW!!!!
                    sb.AppendFormat("--define:{0}", define_str);   // WNH
                    sb.AppendLine ();
                }
            }

            CompileTarget ctarget = configuration.CompileTarget;

            switch (ctarget) {
                case CompileTarget.Exe:
                    sb.AppendLine ("--target:exe");
                    break;
                case CompileTarget.WinExe:
                    sb.AppendLine ("--target:winexe");
                    break;
                case CompileTarget.Library:
                    sb.AppendLine ("--target:library");
                    break;
            }

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

                switch (finfo.BuildAction) {
                    case "Compile":
            // WNH 						AppendQuoted (sb, "", finfo.Name);
                        sb.AppendLine (finfo.Name);   // WNH
                        break;
                    case "EmbeddedResource":
                        string fname = finfo.Name;
                        if (string.Compare (Path.GetExtension (fname), ".resx", true) == 0)
                            fname = Path.ChangeExtension (fname, ".resources");
                        sb.Append ('"');sb.Append ("--resource:");
                        sb.Append (fname);sb.Append (',');sb.Append (finfo.ResourceId);
                        sb.Append ('"');sb.AppendLine ();
                        break;
                    default:
                        continue;
                }
            }
            if (compilerParameters.GenerateXmlDocumentation)
                AppendQuoted (sb, "--doc:", Path.ChangeExtension (outputName, ".xml"));

            if (!string.IsNullOrEmpty (compilerParameters.AdditionalArguments))
                sb.AppendLine (compilerParameters.AdditionalArguments);

            if (!string.IsNullOrEmpty (compilerParameters.NoWarnings))
                AppendQuoted (sb, "--no-warn:", compilerParameters.NoWarnings);  // WNH can't be a list on FSC!!!! FIX!!!

            if (runtime.RuntimeId == "MS.NET")
                sb.AppendLine ("--fullpaths");

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

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

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

            string workingDir = ".";
            if (configuration.ParentItem != null) {
                workingDir = configuration.ParentItem.BaseDirectory;
                if (workingDir == null)
                    // Dummy projects created for single files have no filename
                    // and so no BaseDirectory.
                    // This is a workaround for a bug in
                    // ProcessStartInfo.WorkingDirectory - not able to handle null
                    workingDir = ".";
            }

            // Log the fsc command line
            LoggingService.LogInfo (compilerName + " " + sb.ToString ());

            // Compile!
            Dictionary<string,string> envVars = runtime.GetToolsEnvironmentVariables (project.TargetFramework);
            int exitCode = DoCompilation (compilerName, sb.ToString(), workingDir, envVars, gacRoots, ref output, ref error);

            BuildResult result = ParseOutput (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.");
            } else {
                FileService.DeleteFile (output);
                FileService.DeleteFile (error);
            }

            return result;
        }
        public BuildResult Compile(ProjectItemCollection items, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, IProgressMonitor monitor)
        {
            VBCompilerParameters compilerparameters = (VBCompilerParameters)configuration.CompilationParameters;

            if (compilerparameters == null)
            {
                compilerparameters = new VBCompilerParameters();
            }

            VBProjectParameters projectparameters = (VBProjectParameters)configuration.ProjectParameters;

            if (projectparameters == null)
            {
                projectparameters = new VBProjectParameters();
            }

            string       exe = configuration.CompiledOutputName;
            string       responseFileName = Path.GetTempFileName();
            StreamWriter writer           = new StreamWriter(responseFileName);

            writer.WriteLine(GenerateOptions(configuration, compilerparameters, projectparameters, exe));

            // Write references
            foreach (ProjectReference lib in items.GetAll <ProjectReference> ())
            {
                foreach (string fileName in lib.GetReferencedFileNames(configSelector))
                {
                    writer.Write("\"-r:");
                    writer.Write(fileName);
                    writer.WriteLine("\"");
                }
            }

            // Write source files and embedded resources
            foreach (ProjectFile finfo in items.GetAll <ProjectFile> ())
            {
                if (finfo.Subtype != Subtype.Directory)
                {
                    switch (finfo.BuildAction)
                    {
                    case "Compile":
                        writer.WriteLine("\"" + finfo.Name + "\"");
                        break;

                    case "EmbeddedResource":
                        string fname = finfo.Name;
                        if (String.Compare(Path.GetExtension(fname), ".resx", true) == 0)
                        {
                            fname = Path.ChangeExtension(fname, ".resources");
                        }

                        writer.WriteLine("\"-resource:{0},{1}\"", fname, finfo.ResourceId);
                        break;

                    default:
                        continue;
                    }
                }
            }

            // Write source files and embedded resources
            foreach (Import import in items.GetAll <Import> ())
            {
                writer.WriteLine("-imports:{0}", import.Include);
            }

            TempFileCollection tf = new TempFileCollection();

            writer.Close();

            string output       = "";
            string compilerName = configuration.TargetRuntime.GetToolPath(configuration.TargetFramework, "vbc");

            if (compilerName == null)
            {
                BuildResult res = new BuildResult();
                res.AddError(string.Format("Visual Basict .NET compiler not found ({0})", configuration.TargetRuntime.DisplayName));
                return(res);
            }

            string outstr = String.Concat(compilerName, " @", responseFileName);


            string workingDir = ".";

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

            var envVars = configuration.TargetRuntime.GetToolsExecutionEnvironment(configuration.TargetFramework);

            monitor.Log.WriteLine(Path.GetFileName(compilerName) + " " + string.Join(" ", File.ReadAllLines(responseFileName)));
            exitCode = DoCompilation(outstr, tf, workingDir, envVars, ref output);

            monitor.Log.WriteLine(output);
            BuildResult result = ParseOutput(tf, output);

            if (result.Errors.Count == 0 && exitCode != 0)
            {
                // Compilation failed, but no errors?
                // Show everything the compiler said.
                result.AddError(output);
            }

            FileService.DeleteFile(responseFileName);
            if (configuration.CompileTarget != CompileTarget.Library)
            {
                WriteManifestFile(exe);
            }
            return(result);
        }
		public static BuildResult Compile (ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, IProgressMonitor monitor)
		{
			CSharpCompilerParameters compilerParameters = (CSharpCompilerParameters)configuration.CompilationParameters ?? new CSharpCompilerParameters ();
			CSharpProjectParameters projectParameters = (CSharpProjectParameters)configuration.ProjectParameters ?? new CSharpProjectParameters ();
			
			string outputName       = configuration.CompiledOutputName;
			string responseFileName = Path.GetTempFileName();
			
			if (File.Exists (outputName)) {
				bool isWriteable = false;
				int count = 0;
				do {
					try {
						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;
				}
			}
			
			TargetRuntime runtime = MonoDevelop.Core.Runtime.SystemAssemblyService.DefaultRuntime;
			DotNetProject project = configuration.ParentItem as DotNetProject;
			if (project != null)
				runtime = project.TargetRuntime;

			StringBuilder sb = new StringBuilder ();
			List<string> gacRoots = new List<string> ();
			sb.AppendFormat ("\"/out:{0}\"", outputName);
			sb.AppendLine ();
			
			HashSet<string> alreadyAddedReference = new HashSet<string> ();
			foreach (ProjectReference lib in projectItems.GetAll <ProjectReference> ()) {
				if (lib.ReferenceType == ReferenceType.Project && !(lib.OwnerProject.ParentSolution.FindProjectByName (lib.Reference) is DotNetProject))
					continue;
				foreach (string fileName in lib.GetReferencedFileNames (configSelector)) {
					switch (lib.ReferenceType) {
					case ReferenceType.Gac:
						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:", 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:", fileName);
						break;
					}
				}
			}
			
			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.DebugMode) {
				sb.AppendLine ("/debug:+");
				sb.AppendLine ("/debug:full");
			}
			
			switch (compilerParameters.LangVersion) {
			case LangVersion.Default:
				break;
			case LangVersion.ISO_1:
				sb.AppendLine ("/langversion:ISO-1");
				break;
			case LangVersion.ISO_2:
				sb.AppendLine ("/langversion:ISO-2");
				break;
			default:
				string message = "Invalid LangVersion enum value '" + compilerParameters.LangVersion.ToString () + "'";
				monitor.ReportError (message, null);
				LoggingService.LogError (message);
				return null;
			}
			
			// 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);
			}
			
			if (compilerParameters.DefineSymbols.Length > 0) {
				string define_str = string.Join (";", compilerParameters.DefineSymbols.Split (new char [] {',', ' ', ';'}, StringSplitOptions.RemoveEmptyEntries));
				if (define_str.Length > 0) {
					AppendQuoted (sb, "/define:", define_str);
					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", true) == 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.GenerateXmlDocumentation) 
				AppendQuoted (sb, "/doc:", Path.ChangeExtension (outputName, ".xml"));
			
			if (!string.IsNullOrEmpty (compilerParameters.AdditionalArguments)) 
				sb.AppendLine (compilerParameters.AdditionalArguments);
			
			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 ());
			
			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;
			}
			
			monitor.Log.WriteLine (compilerName + " /noconfig " + sb.ToString ().Replace ('\n',' '));
			
			string workingDir = ".";
			if (configuration.ParentItem != null) {
				workingDir = configuration.ParentItem.BaseDirectory;
				if (workingDir == null)
					// Dummy projects created for single files have no filename
					// and so no BaseDirectory.
					// This is a workaround for a bug in 
					// ProcessStartInfo.WorkingDirectory - not able to handle null
					workingDir = ".";
			}

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

			int exitCode = DoCompilation (compilerName, cargs, workingDir, envVars, gacRoots, ref output, ref error);
			
			BuildResult result = ParseOutput (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 BuildResult Compile (ProjectItemCollection items, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, ProgressMonitor monitor)
		{
			VBCompilerParameters compilerparameters = (VBCompilerParameters) configuration.CompilationParameters;
			if (compilerparameters == null)
				compilerparameters = new VBCompilerParameters ();
			
			var projectparameters = (VBProject) configuration.ParentItem;

			string exe = configuration.CompiledOutputName;
			string responseFileName = Path.GetTempFileName();
			StreamWriter writer = new StreamWriter (responseFileName);
			
			writer.WriteLine (GenerateOptions (configuration, compilerparameters, projectparameters, exe));

			// Write references
			foreach (ProjectReference lib in items.GetAll<ProjectReference> ()) {
				foreach (string fileName in lib.GetReferencedFileNames (configSelector)) {
					writer.Write ("\"-r:");
					writer.Write (fileName);
					writer.WriteLine ("\"");
				}
			}
			
			// Write source files and embedded resources
			foreach (ProjectFile finfo in items.GetAll<ProjectFile> ()) {
				if (finfo.Subtype != Subtype.Directory) {
					switch (finfo.BuildAction) {
						case "Compile":
							writer.WriteLine("\"" + finfo.Name + "\"");
						break;
						
						case "EmbeddedResource":
							string fname = finfo.Name;
							if (String.Compare (Path.GetExtension (fname), ".resx", true) == 0)
								fname = Path.ChangeExtension (fname, ".resources");

							writer.WriteLine("\"-resource:{0},{1}\"", fname, finfo.ResourceId);
							break;
						
						default:
							continue;
					}
				}
			}
			
			// Write source files and embedded resources
			foreach (Import import in items.GetAll<Import> ()) {
				writer.WriteLine ("-imports:{0}", import.Include);
			}
			
			TempFileCollection tf = new TempFileCollection ();
			writer.Close();
			
			string output = "";
			string compilerName = configuration.TargetRuntime.GetToolPath (configuration.TargetFramework, "vbc");
			if (compilerName == null) {
				BuildResult res = new BuildResult ();
				res.AddError (string.Format ("Visual Basic .NET compiler not found ({0})", configuration.TargetRuntime.DisplayName));
				return res;
			}
			
			string workingDir = ".";
			if (configuration.ParentItem != null)
				workingDir = configuration.ParentItem.BaseDirectory;
			int exitCode;
			
			var envVars = configuration.TargetRuntime.GetToolsExecutionEnvironment (configuration.TargetFramework);
			
			monitor.Log.WriteLine (Path.GetFileName (compilerName) + " " + string.Join (" ", File.ReadAllLines (responseFileName)));
			exitCode = DoCompilation (compilerName, responseFileName, tf, workingDir, envVars, ref output);
			
			monitor.Log.WriteLine (output);			                                                          
			BuildResult result = ParseOutput (tf, output);
			if (result.Errors.Count == 0 && exitCode != 0) {
				// Compilation failed, but no errors?
				// Show everything the compiler said.
				result.AddError (output);
			}
			
			FileService.DeleteFile (responseFileName);
			if (configuration.CompileTarget != CompileTarget.Library) {
				WriteManifestFile (exe);
			}
			return result;
		}
Пример #10
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);
        }
		// Builds the EmbedAsResource files. If any localized resources are found then builds the satellite assemblies
		// and sets @projectItems to a cloned collection minus such resource files.
		private BuildResult BuildResources (DotNetProjectConfiguration configuration, ref ProjectItemCollection projectItems, IProgressMonitor monitor)
		{
			string resgen = configuration.TargetRuntime.GetToolPath (configuration.TargetFramework, "resgen");
			ExecutionEnvironment env = configuration.TargetRuntime.GetToolsExecutionEnvironment (configuration.TargetFramework);
			
			bool cloned = false;
			Dictionary<string, string> resourcesByCulture = new Dictionary<string, string> ();
			foreach (ProjectFile finfo in projectItems.GetAll<ProjectFile> ()) {
				if (finfo.Subtype == Subtype.Directory || finfo.BuildAction != BuildAction.EmbeddedResource)
					continue;

				string fname = finfo.Name;
				string resourceId;
				CompilerError ce = GetResourceId (env, finfo, ref fname, resgen, out resourceId, monitor);
				if (ce != null) {
					CompilerResults cr = new CompilerResults (new TempFileCollection ());
					cr.Errors.Add (ce);

					return new BuildResult (cr, String.Empty);
				}
				string culture = DotNetProject.GetResourceCulture (finfo.Name);
				if (culture == null)
					continue;

				string cmd = String.Empty;
				if (resourcesByCulture.ContainsKey (culture))
					cmd = resourcesByCulture [culture];

				cmd = String.Format ("{0} \"/embed:{1},{2}\"", cmd, fname, resourceId);
				resourcesByCulture [culture] = cmd;
				if (!cloned) {
					// Clone only if required
					ProjectItemCollection items = new ProjectItemCollection ();
					items.AddRange (projectItems);
					projectItems = items;
					cloned = true;
				}
				projectItems.Remove (finfo);
			}

			string al = configuration.TargetFramework.ClrVersion == ClrVersion.Net_2_0 ? "al2" : "al";
			CompilerError err = GenerateSatelliteAssemblies (resourcesByCulture, configuration.OutputDirectory, al, Path.GetFileName (configuration.OutputAssembly), monitor);
			if (err != null) {
				CompilerResults cr = new CompilerResults (new TempFileCollection ());
				cr.Errors.Add (err);

				return new BuildResult (cr, String.Empty);
			}

			return null;
		}
        public static BuildResult Compile(ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, IProgressMonitor monitor)
        {
            CSharpCompilerParameters compilerParameters = (CSharpCompilerParameters)configuration.CompilationParameters ?? new CSharpCompilerParameters();
            CSharpProjectParameters  projectParameters  = (CSharpProjectParameters)configuration.ProjectParameters ?? new CSharpProjectParameters();

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

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

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

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

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

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

            foreach (ProjectReference lib in projectItems.GetAll <ProjectReference> ())
            {
                if (lib.ReferenceType == ReferenceType.Project && !(lib.OwnerProject.ParentSolution.FindProjectByName(lib.Reference) is DotNetProject))
                {
                    continue;
                }
                foreach (string fileName in lib.GetReferencedFileNames(configSelector))
                {
                    switch (lib.ReferenceType)
                    {
                    case ReferenceType.Gac:
                        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:", 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:", fileName);
                        }
                        break;
                    }
                }
            }

            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.DebugMode)
            {
                sb.AppendLine("/debug:+");
                sb.AppendLine("/debug:full");
            }

            switch (compilerParameters.LangVersion)
            {
            case LangVersion.Default:
                break;

            case LangVersion.ISO_1:
                sb.AppendLine("/langversion:ISO-1");
                break;

            case LangVersion.ISO_2:
                sb.AppendLine("/langversion:ISO-2");
                break;

            default:
                string message = "Invalid LangVersion enum value '" + compilerParameters.LangVersion.ToString() + "'";
                monitor.ReportError(message, null);
                LoggingService.LogError(message);
                return(null);
            }

            // 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);
                }
            }

            if (compilerParameters.DefineSymbols.Length > 0)
            {
                string define_str = string.Join(";", compilerParameters.DefineSymbols.Split(new char [] { ',', ' ', ';' }, StringSplitOptions.RemoveEmptyEntries));
                if (define_str.Length > 0)
                {
                    AppendQuoted(sb, "/define:", define_str);
                    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", true) == 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.GenerateXmlDocumentation)
            {
                AppendQuoted(sb, "/doc:", Path.ChangeExtension(outputName, ".xml"));
            }

            if (!string.IsNullOrEmpty(compilerParameters.AdditionalArguments))
            {
                sb.AppendLine(compilerParameters.AdditionalArguments);
            }

            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());

            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);
            }

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

            string workingDir = ".";

            if (configuration.ParentItem != null)
            {
                workingDir = configuration.ParentItem.BaseDirectory;
                if (workingDir == null)
                {
                    // Dummy projects created for single files have no filename
                    // and so no BaseDirectory.
                    // This is a workaround for a bug in
                    // ProcessStartInfo.WorkingDirectory - not able to handle null
                    workingDir = ".";
                }
            }

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

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

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

            BuildResult result = ParseOutput(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;
		}
		public static BuildResult Compile (ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configSelector, IProgressMonitor monitor)
		{
//			ILAsmCompilerParameters compilerParameters = (ILAsmCompilerParameters)configuration.CompilationParameters ?? new ILAsmCompilerParameters ();
			string outputName       = configuration.CompiledOutputName;
			
			StringBuilder sb = new StringBuilder ();
			sb.AppendFormat ("\"/output:{0}\" ", outputName);
			
			List<string> gacRoots = new List<string> ();
			
			
			switch (configuration.CompileTarget) {
				case CompileTarget.WinExe:
				case CompileTarget.Exe:
					sb.Append ("/exe ");
					break;
				case CompileTarget.Library:
					sb.Append ("/dll ");
					break;
			}
			
			if (configuration.DebugMode)
				sb.Append ("/debug ");
			
			foreach (ProjectFile finfo in projectItems.GetAll<ProjectFile> ()) {
				if (finfo.Subtype == Subtype.Directory)
					continue;

				switch (finfo.BuildAction) {
					case "Compile":
						AppendQuoted (sb, "", finfo.Name);
						break;
					default:
						continue;
				}
			}
			
			string output = "";
			string error  = "";
			
			string ilasm = configuration.TargetRuntime.GetToolPath (configuration.TargetFramework, "ilasm");
			if (ilasm == null) {
				BuildResult res = new BuildResult ();
				res.AddError (GettextCatalog.GetString ("IL compiler (ilasm) not found."));
				if (configuration.TargetRuntime is MsNetTargetRuntime)
					res.AddError (GettextCatalog.GetString ("You may need to install the .NET SDK."));
				return res;
			}
			string outstr = ilasm + " " + sb.ToString ();
			monitor.Log.WriteLine (outstr);
			
			string workingDir = ".";
			if (configuration.ParentItem != null) {
				workingDir = configuration.ParentItem.BaseDirectory;
				if (workingDir == null)
					// Dummy projects created for single files have no filename
					// and so no BaseDirectory.
					// This is a workaround for a bug in 
					// ProcessStartInfo.WorkingDirectory - not able to handle null
					workingDir = ".";
			}

			LoggingService.LogInfo ("ilasm " + sb.ToString ());
			
			Dictionary<string,string> envVars = configuration.TargetRuntime.GetToolsEnvironmentVariables (configuration.TargetFramework);
			int exitCode = DoCompilation (outstr, workingDir, envVars, gacRoots, ref output, ref error);
			
			BuildResult result = ParseOutput (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) {
				if (!string.IsNullOrEmpty (error))
					result.AddError (error);
				else
					result.AddError ("The compiler appears to have crashed without any error output.");
			}
			
			FileService.DeleteFile (output);
			FileService.DeleteFile (error);
			return result;
		}
Пример #15
0
        public static BuildResult Compile(ProjectItemCollection projectItems, LuaConfiguration configuration, ConfigurationSelector configselector, IProgressMonitor monitor)
        {
//			LuaCompilerParameters compilerParameters = (LuaCompilerParameters)configuration.CompilationParameters ?? new LuaCompilerParameters ();


            var sb = new StringBuilder();

            sb.Append("-p ");

            var gacRoots = new List <string>();

            if (configuration.DebugMode)
            {
                // TODO: This
            }

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

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

                default:
                    continue;
                }
            }

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

            /*
             * string luac = configuration.TargetRuntime.GetToolPath (configuration.TargetFramework, "luac");
             * if (luac == null) {
             *      BuildResult res = new BuildResult ();
             *      res.AddError(GettextCatalog.GetString ("Lua compiler (luac) not found."));
             *      return res;
             * }
             */

            string outstr = sb.ToString();

            monitor.Log.WriteLine(outstr);

            string working_dir = ".";

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

            LoggingService.LogInfo("luac " + sb);

            var envVars  = configuration.EnvironmentVariables;
            int exitCode = DoCompilation(outstr, working_dir, envVars, gacRoots, ref output, ref error, monitor);

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

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

            //if compiler crashes, output entire error string
            if (result.ErrorCount == 0 && exitCode != 0)
            {
                if (!string.IsNullOrEmpty(error))
                {
                    result.AddError(error);
                }
                else
                {
                    result.AddError("The compiler appears to have crashed without any error output.");
                }
            }

            FileService.DeleteFile(output);
            FileService.DeleteFile(error);
            return(result);
        }
Пример #16
0
        static BuildResult ParseOutput(string stdout, string stderr, ProjectItemCollection projectItems)
        {
            var result = new BuildResult();

            var compilerOutput = new StringBuilder();

            foreach (string s in new [] { stdout, stderr })
            {
                StreamReader sr = File.OpenText(s);
                while (true)
                {
                    string curLine = sr.ReadLine();
                    compilerOutput.AppendLine(curLine);

                    if (curLine == null)
                    {
                        break;
                    }

                    curLine = curLine.Trim();
                    if (curLine.Length == 0)
                    {
                        continue;
                    }

                    BuildError error = CreateErrorFromString(curLine);

                    if (error != null)
                    {
                        string path = error.FileName;
                        if (path.StartsWith("...", StringComparison.Ordinal))                           // F**k whomever made the choice to do this... (Cory Here... Indeed!)
                        {
                            string      known = path.Substring(3);
                            ProjectFile found = null;

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

                                switch (finfo.BuildAction)
                                {
                                case "Compile":
                                    if (finfo.Name.EndsWith(known, StringComparison.Ordinal))
                                    {
                                        found = finfo;
                                    }
                                    break;

                                default:
                                    continue;
                                }
                                if (found != null)
                                {
                                    break;
                                }
                            }

                            if (found != null)
                            {
                                error.FileName = found.Project.GetAbsoluteChildPath(found.FilePath);
                            }
                        }

                        result.Append(error);
                    }
                }
                sr.Close();
            }

            result.CompilerOutput = compilerOutput.ToString();
            return(result);
        }
Пример #17
0
		static string GenerateReferenceStubs (IProgressMonitor monitor, ConfigurationSelector configurationSelector, DotNetProjectConfiguration configuration, JavaCompilerParameters compilerparameters, ProjectItemCollection projectItems)
		{
			StringBuilder result = new StringBuilder ();
			foreach (ProjectReference reference in projectItems.GetAll<ProjectReference> ()) {
				AppendClasspath (result, GenerateReferenceStub (monitor, configurationSelector, configuration, reference));
			}
			return result.ToString ();
		}
Пример #18
0
		static void CompileToAssembly (IProgressMonitor monitor, DotNetProjectConfiguration configuration, JavaCompilerParameters compilerparameters, ProjectItemCollection projectItems, TextWriter output, TextWriter error)
		{
			monitor.Log.WriteLine (GettextCatalog.GetString ("Generating assembly ..."));
			
			LogTextWriter chainedError = new LogTextWriter ();
			chainedError.ChainWriter (monitor.Log);
			chainedError.ChainWriter (error);
			
			LogTextWriter chainedOutput = new LogTextWriter ();
			chainedOutput.ChainWriter (monitor.Log);
			chainedOutput.ChainWriter (output);
			
			string outdir = configuration.OutputDirectory;
			string outclass = Path.Combine (outdir, configuration.OutputAssembly + ".class");
			string asm = Path.GetFileNameWithoutExtension (outclass);
			
			StringBuilder args = new StringBuilder ("-recurse:*.class ");
			
			args.Append ("-assembly:"); args.Append (asm);
			args.Append (" -target:"); args.Append (TargetToString (configuration.CompileTarget));
			if (configuration.DebugMode)
				args.Append (" -debug");
			args.Append (" -srcpath:"); args.Append (configuration.ParentItem.BaseDirectory);
			
			foreach (ProjectReference lib in projectItems.GetAll<ProjectReference> ()) {
				foreach (string fileName in lib.GetReferencedFileNames (configuration.Selector)) {
					args.Append (" -r:"); args.Append (fileName);
				}
			}
			
			foreach (string fileName in new ProjectReference(ReferenceType.Gac, "mscorlib").GetReferencedFileNames (configuration.Selector)) {
				args.Append (" -r:"); args.Append (fileName);
			}
			
			monitor.Log.WriteLine ("ikvmc " + args);
			Process process = Runtime.ProcessService.StartProcess ("ikvmc", args.ToString (), configuration.OutputDirectory, chainedOutput, chainedError, null);
			process.WaitForExit ();
		}
        // Builds the EmbedAsResource files. If any localized resources are found then builds the satellite assemblies
        // and sets @projectItems to a cloned collection minus such resource files.
        private BuildResult BuildResources(DotNetProjectConfiguration configuration, ref ProjectItemCollection projectItems, IProgressMonitor monitor)
        {
            string resgen            = configuration.TargetRuntime.GetToolPath(configuration.TargetFramework, "resgen");
            ExecutionEnvironment env = configuration.TargetRuntime.GetToolsExecutionEnvironment(configuration.TargetFramework);

            bool cloned = false;
            Dictionary <string, string> resourcesByCulture = new Dictionary <string, string> ();

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

                string        fname = finfo.Name;
                string        resourceId;
                CompilerError ce = GetResourceId(configuration.IntermediateOutputDirectory.Combine(finfo.ResourceId), env, finfo, ref fname, resgen, out resourceId, monitor);
                if (ce != null)
                {
                    CompilerResults cr = new CompilerResults(new TempFileCollection());
                    cr.Errors.Add(ce);

                    return(new BuildResult(cr, String.Empty));
                }
                string culture = DotNetProject.GetResourceCulture(finfo.Name);
                if (culture == null)
                {
                    continue;
                }

                string cmd = String.Empty;
                if (resourcesByCulture.ContainsKey(culture))
                {
                    cmd = resourcesByCulture [culture];
                }

                cmd = String.Format("{0} \"/embed:{1},{2}\"", cmd, fname, resourceId);
                resourcesByCulture [culture] = cmd;
                if (!cloned)
                {
                    // Clone only if required
                    ProjectItemCollection items = new ProjectItemCollection();
                    items.AddRange(projectItems);
                    projectItems = items;
                    cloned       = true;
                }
                projectItems.Remove(finfo);
            }

            string        al  = configuration.TargetRuntime.GetToolPath(configuration.TargetFramework, "al");
            CompilerError err = GenerateSatelliteAssemblies(resourcesByCulture, configuration.OutputDirectory, al, Path.GetFileName(configuration.OutputAssembly), monitor);

            if (err != null)
            {
                CompilerResults cr = new CompilerResults(new TempFileCollection());
                cr.Errors.Add(err);

                return(new BuildResult(cr, String.Empty));
            }

            return(null);
        }
        public static BuildResult Compile(ProjectItemCollection projectItems, DotNetProjectConfiguration configuration, ConfigurationSelector configurationSelector, IProgressMonitor monitor)
        {
            JavaCompilerParameters parameters = (configuration.CompilationParameters as JavaCompilerParameters) ?? new JavaCompilerParameters();
            string outdir   = configuration.OutputDirectory;
            string options  = GenerateOptionString(configuration);
            string compiler = parameters.CompilerPath;

            if (String.IsNullOrEmpty(compiler))
            {
                compiler = "javac";
            }

            StringBuilder files = new StringBuilder();

            foreach (ProjectFile finfo in projectItems.GetAll <ProjectFile> ())
            {
                if (finfo.Subtype != Subtype.Directory && finfo.BuildAction == BuildAction.Compile)
                {
                    files.Append(" \"");
                    files.Append(finfo.Name);
                    files.Append("\"");
                }
            }

            StringBuilder classpath = new StringBuilder(parameters.ClassPath);

            AppendClasspath(classpath, GenerateReferenceStubs(monitor, configurationSelector, configuration, parameters, projectItems));
            AppendClasspath(classpath, GenerateReferenceStub(monitor, configurationSelector, configuration, new ProjectReference(ReferenceType.Gac, "mscorlib")));

            StringBuilder args = new StringBuilder();

            args.Append(options.ToString());
            if (parameters.Compiler == JavaCompiler.Gcj)
            {
                args.Append("-C ");
            }
            if (classpath.Length != 0)
            {
                args.Append(" -classpath ");
                args.Append(classpath.ToString());
            }
            args.Append(files.ToString());
            args.Append(" -d ");
            args.Append(outdir);

            CompilerResults results = new CompilerResults(new TempFileCollection());
            StringWriter    output  = new StringWriter();
            StringWriter    error   = new StringWriter();

            bool success;

            try {
                success = Compile(monitor, compiler, args.ToString(), configuration, parameters, output, error);
                ParseJavaOutput(parameters.Compiler, error.ToString(), results);
            } catch (Exception ex) {
                string errorMsg = AddinManager.CurrentLocalizer.GetString("Execution on '{0}' failed. Make sure the Java compiler is properly installed", compiler);
                monitor.ReportError(errorMsg, ex);
                success = false;
                results.Errors.Add(new CompilerError("", 0, 0, "", errorMsg));
            }

            if (success)
            {
                output = new StringWriter();
                error  = new StringWriter();
                CompileToAssembly(monitor, configuration, parameters, projectItems, output, error);
                ParseIkvmOutput(parameters.Compiler, error.ToString(), results);
            }

            return(new BuildResult(results, ""));
        }