Пример #1
0
        private static Assembly CompileAssembly(FileReference OutputAssemblyPath, List <FileReference> SourceFileNames, List <string> ReferencedAssembies, List <string> PreprocessorDefines = null, bool TreatWarningsAsErrors = false)
        {
            CSharpParseOptions ParseOptions = new CSharpParseOptions(
                languageVersion: LanguageVersion.Latest,
                kind: SourceCodeKind.Regular,
                preprocessorSymbols: PreprocessorDefines
                );

            List <SyntaxTree> SyntaxTrees = new List <SyntaxTree>();

            foreach (FileReference SourceFileName in SourceFileNames)
            {
                SourceText Source = SourceText.From(File.ReadAllText(SourceFileName.FullName));
                SyntaxTree Tree   = CSharpSyntaxTree.ParseText(Source, ParseOptions, SourceFileName.FullName);

                IEnumerable <Diagnostic> Diagnostics = Tree.GetDiagnostics();
                if (Diagnostics.Count() > 0)
                {
                    Log.TraceWarning($"Errors generated while parsing '{SourceFileName.FullName}'");
                    LogDiagnostics(Tree.GetDiagnostics());
                    return(null);
                }

                SyntaxTrees.Add(Tree);
            }

            // Create the output directory if it doesn't exist already
            DirectoryInfo DirInfo = new DirectoryInfo(OutputAssemblyPath.Directory.FullName);

            if (!DirInfo.Exists)
            {
                try
                {
                    DirInfo.Create();
                }
                catch (Exception Ex)
                {
                    throw new BuildException(Ex, "Unable to create directory '{0}' for intermediate assemblies (Exception: {1})", OutputAssemblyPath, Ex.Message);
                }
            }

            List <MetadataReference> MetadataReferences = new List <MetadataReference>();

            if (ReferencedAssembies != null)
            {
                foreach (string Reference in ReferencedAssembies)
                {
                    MetadataReferences.Add(MetadataReference.CreateFromFile(Reference));
                }
            }

            MetadataReferences.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Collections").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.IO").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.IO.FileSystem").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Console").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Runtime.Extensions").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("Microsoft.Win32.Registry").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(typeof(UnrealBuildTool).Assembly.Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(typeof(FileReference).Assembly.Location));

            CSharpCompilationOptions CompilationOptions = new CSharpCompilationOptions(
                outputKind: OutputKind.DynamicallyLinkedLibrary,
                optimizationLevel: OptimizationLevel.Release,
                warningLevel: 4,
                assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default,
                reportSuppressedDiagnostics: true
                );

            CSharpCompilation Compilation = CSharpCompilation.Create(
                assemblyName: OutputAssemblyPath.GetFileNameWithoutAnyExtensions(),
                syntaxTrees: SyntaxTrees,
                references: MetadataReferences,
                options: CompilationOptions
                );

            using (FileStream AssemblyStream = FileReference.Open(OutputAssemblyPath, FileMode.Create))
            {
                EmitOptions EmitOptions = new EmitOptions(
                    includePrivateMembers: true
                    );

                EmitResult Result = Compilation.Emit(
                    peStream: AssemblyStream,
                    options: EmitOptions);

                if (!Result.Success)
                {
                    LogDiagnostics(Result.Diagnostics);
                    return(null);
                }
            }

            return(Assembly.LoadFile(OutputAssemblyPath.FullName));
        }