private bool CreateAssembly(string fileName, string assemblyLocation, string assemblyNamespace) { if (NeedsCompilation(fileName, assemblyLocation)) { Assembly self = Assembly.GetExecutingAssembly(); CompileData compileData = new CompileData(); Compiler compiler = new Compiler(); if (string.Empty != assemblyNamespace) { string tempFile = Path.Combine(Cache.CacheTmpDir, assemblyNamespace + Solution.ExpectedFileName + ".cs"); string readFile = File.ReadAllText(fileName); readFile = "namespace " + assemblyNamespace + "{" + readFile + "}"; File.WriteAllText(tempFile, readFile); fileName = tempFile; } // Build a dynamic library that can be loaded at runtime. compileData.isLibrary = true; // Allow debug info to be included so user can test for errors // in their project. They will have some at some point. compileData.includeDebugInfo = true; // Where the heck does it go? Oh yeah, it'll get saved to // assemblyLocation! Brilliant. compileData.name = assemblyLocation; // The source files? Just one: fileName. compileData.sourceFiles = new List <string>(); compileData.sourceFiles.Add(fileName); // To care about the users or not to, that is the question. // Treating warnings as errors = not caring. In this case, // I don't care. compileData.warningsAreErrors = true; // Warning level? TO THE MAX! compileData.warningLevel = WarningLevel.Level4; // Add this assembly to the list of referenced assemblies. compileData.referencedAssemblies = new List <string>(); compileData.referencedAssemblies.Add(self.Location); if (!compiler.Compile(compileData)) { // Couldn't build it, how am I supposed to load it? return(false); } } return(true); }
/// <summary> /// Compile files into a binary. /// </summary> /// <param name="compileData"> /// The data to be used in compilation. /// </param> /// <returns> /// Returns `true` on successful compilation, `false` on error. /// </returns> /// <see cref="CompileData" /> public bool Compile(CompileData compileData) { CompilerParameters parameters = new CompilerParameters(); CompilerResults compileResult; List <string> compileOptions = new List <string>(); string[] sourceFiles = new string[0]; if (null != compileData.sourceFiles && 0 < compileData.sourceFiles.Count) { sourceFiles = compileData.sourceFiles.ToArray(); } // Where to build the assembly parameters.OutputAssembly = compileData.name; // Library or executable? parameters.GenerateExecutable = !compileData.isLibrary; // Actually build a file. parameters.GenerateInMemory = false; // What warning level? parameters.WarningLevel = ( int )compileData.warningLevel; // Treat warnings as errors parameters.TreatWarningsAsErrors = compileData.warningsAreErrors; // Temporary files. parameters.TempFiles = tempFiles; // Build with debug info? parameters.IncludeDebugInformation = compileData.includeDebugInfo; // Defines, e.g. -define:DEBUG if (null != compileData.defines && 0 < compileData.defines.Count) { compileOptions.Add("-define:" + string.Join(",", compileData.defines.ToArray())); } // Referenced assemblies. Default: System.dll parameters.ReferencedAssemblies.Add("System.dll"); if (null != compileData.referencedAssemblies && 0 < compileData.referencedAssemblies.Count) { // string[] var assemblies = compileData.referencedAssemblies.ToArray(); parameters.ReferencedAssemblies.AddRange(assemblies); } // CompilerOptions expects each option to be space separated. parameters.CompilerOptions = string.Join(" ", compileOptions.ToArray()); compileResult = provider.CompileAssemblyFromFile(parameters, sourceFiles); if (0 < compileResult.Errors.Count) { Console.WriteLine(); Console.WriteLine("Failed to build {0} due to errors:", compileData.name); foreach (CompilerError error in compileResult.Errors) { Console.WriteLine(" {0}", error.ToString()); Console.WriteLine(); } } return(0 == compileResult.Errors.Count); }