Example #1
0
        private void Compile(IList <string> sourceFiles, string assemblyName, string assemblyPath)
        {
            var parseOptions = CSharpParseOptions.Default;

            parseOptions = parseOptions.WithPreprocessorSymbols("NETCORE");

            var syntaxTrees = sourceFiles
                              .Select(path => CSharpSyntaxTree.ParseText(
                                          File.ReadAllText(path), parseOptions, path, Encoding.UTF8))
                              .ToList();

            LoadAssembliesFromUsings(syntaxTrees);
            var references = LoadedAssemblies.Select(assembly => assembly.Location)
                             .Select(path => MetadataReference.CreateFromFile(path))
                             .ToList();
            var compilationOptions = new CSharpCompilationOptions(
                OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release);
            var withTopLevelBinderFlagsMethod = compilationOptions.GetType()
                                                .GetMethod("WithTopLevelBinderFlags", BindingFlags.Instance | BindingFlags.NonPublic);
            var binderFlagsType = withTopLevelBinderFlagsMethod.GetParameters()[0].ParameterType;

            compilationOptions = (CSharpCompilationOptions)withTopLevelBinderFlagsMethod.Invoke(
                compilationOptions,
                new object[] { binderFlagsType.GetField("IgnoreCorLibraryDuplicatedTypes").GetValue(binderFlagsType) });

            var compilation = CSharpCompilation.Create(assemblyName)
                              .WithOptions(compilationOptions)
                              .AddReferences(references)
                              .AddSyntaxTrees(syntaxTrees);
            var emitResult = compilation.Emit(assemblyPath, null);

            if (!emitResult.Success)
            {
                throw new Exception(string.Join("\r\n",
                                                emitResult.Diagnostics.Where(d => d.WarningLevel == 0)));
            }
        }
Example #2
0
        /// <summary>
        /// Compile source files to assembly<br/>
        /// 编译源代码到程序集<br/>
        /// </summary>
        public void Compile(IList <string> sourceFiles,
                            string assemblyName, string assemblyPath, CompilationOptions options)
        {
            // Use default options if `options` is null
            options = options ?? new CompilationOptions();
            // Parse source files into syntax trees
            // Also define NETCORE for .Net Core
            var parseOptions = CSharpParseOptions.Default;

#if NETCORE
            parseOptions = parseOptions.WithPreprocessorSymbols("NETCORE");
#endif
            var syntaxTrees = sourceFiles
                              .Select(path => CSharpSyntaxTree.ParseText(
                                          File.ReadAllText(path), parseOptions, path, Encoding.UTF8))
                              .ToList();
            // Find all using directive and load the namespace as assembly
            // It's for resolve assembly dependencies of plugin
            LoadAssembliesFromUsings(syntaxTrees);
            // Add loaded assemblies to compile references
            var assemblyLoader = Application.Ioc.Resolve <IAssemblyLoader>();
            var references     = assemblyLoader.GetLoadedAssemblies()
                                 .Select(assembly => assembly.Location)
                                 .Select(path => MetadataReference.CreateFromFile(path))
                                 .ToList();
            // Set roslyn compilation options
            // Generate pdb file only supported on windows,
            // because Microsoft.DiaSymReader.Native only have windows runtimes
            if (!PlatformUtils.RunningOnWindows())
            {
                options.GeneratePdbFile = false;
            }
            var optimizationLevel = (options.Release ?
                                     OptimizationLevel.Release : OptimizationLevel.Debug);
            var pdbPath = ((!options.GeneratePdbFile) ? null : Path.Combine(
                               Path.GetDirectoryName(assemblyPath),
                               Path.GetFileNameWithoutExtension(assemblyPath) + ".pdb"));
            // Create compilation options and set IgnoreCorLibraryDuplicatedTypes flag
            // To avoid error like The type 'Path' exists in both
            // 'System.Runtime.Extensions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
            // and
            // 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'
            var compilationOptions = new CSharpCompilationOptions(
                OutputKind.DynamicallyLinkedLibrary,
                optimizationLevel: optimizationLevel);
            var withTopLevelBinderFlagsMethod = compilationOptions.GetType()
                                                .FastGetMethod("WithTopLevelBinderFlags", BindingFlags.Instance | BindingFlags.NonPublic);
            var binderFlagsType = withTopLevelBinderFlagsMethod.GetParameters()[0].ParameterType;
            compilationOptions = (CSharpCompilationOptions)withTopLevelBinderFlagsMethod.FastInvoke(
                compilationOptions,
                binderFlagsType.GetField("IgnoreCorLibraryDuplicatedTypes").GetValue(binderFlagsType));
            // Compile to assembly, throw exception if error occurred
            var compilation = CSharpCompilation.Create(assemblyName)
                              .WithOptions(compilationOptions)
                              .AddReferences(references)
                              .AddSyntaxTrees(syntaxTrees);
            var emitResult = compilation.Emit(assemblyPath, pdbPath);
            if (!emitResult.Success)
            {
                throw new CompilationException(string.Join("\r\n",
                                                           emitResult.Diagnostics.Where(d => d.WarningLevel == 0)));
            }
        }