Пример #1
0
        public static int Run(InvocationContext context)
        {
            string sourceDirectory             = context.ParseResult.ValueForOption <string>("sourceDir");
            string interopFileName             = context.ParseResult.ValueForOption <string>("interopFileName");
            string outputFileName              = context.ParseResult.ValueForOption <string>("outputFileName");
            string version                     = context.ParseResult.ValueForOption <string>("version");
            var    remappedNameValuePairs      = context.ParseResult.ValueForOption <string[]>("remap");
            var    typeImportValuePairs        = context.ParseResult.ValueForOption <string[]>("typeImport");
            var    requiredNamespaceValuePairs = context.ParseResult.ValueForOption <string[]>("requiredNamespaceForName");
            var    autoTypes                   = context.ParseResult.ValueForOption <string[]>("autoTypes");

            var remaps             = ConvertValuePairsToDictionary(remappedNameValuePairs);
            var typeImports        = ConvertValuePairsToDictionary(typeImportValuePairs);
            var requiredNamespaces = ConvertValuePairsToDictionary(requiredNamespaceValuePairs);

            string  rawVersion      = version.Split('-')[0];
            Version assemblyVersion = Version.Parse(rawVersion);

            NativeTypedefStructsCreator.CreateNativeTypedefsSourceFile(autoTypes, Path.Combine(sourceDirectory, "generated\\autotypes.cs"));

            Console.Write($"Compiling source files...");
            System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();

            ClangSharpSourceCompilation clangSharpCompliation =
                ClangSharpSourceCompilation.Create(
                    sourceDirectory, interopFileName, remaps, typeImports, requiredNamespaces);

            Console.Write("looking for errors...");
            var diags = clangSharpCompliation.GetDiagnostics();

            watch.Stop();

            int       errors          = 0;
            const int MaxErrorsToShow = 10000;

            foreach (var diag in diags)
            {
                if (errors == 0)
                {
                    Console.WriteLine("errors were found.");
                }

                errors++;
                Console.WriteLine(diag.ToString());
                if (errors >= MaxErrorsToShow)
                {
                    Console.WriteLine($"Only showing the first {MaxErrorsToShow} errors.");
                    break;
                }
            }

            if (errors > 0)
            {
                return(-1);
            }

            string timeTaken = watch.Elapsed.ToString("c");

            Console.WriteLine($"took {timeTaken}");

            Console.WriteLine($"Emitting {outputFileName}...");
            var generator = ClangSharpSourceWinmdGenerator.GenerateWindmdForCompilation(clangSharpCompliation, typeImports, assemblyVersion, outputFileName);

            foreach (var diag in generator.GetDiagnostics())
            {
                Console.WriteLine($"{diag.Severity}: {diag.Message}");
            }

            return(generator.WroteWinmd ? 0 : -1);
        }
Пример #2
0
        public static int Run(InvocationContext context)
        {
            string sourceDirectory             = context.ParseResult.ValueForOption <string>("--sourceDir");
            string arch                        = context.ParseResult.ValueForOption <string>("--arch");
            string interopFileName             = context.ParseResult.ValueForOption <string>("--interopFileName");
            string outputFileName              = context.ParseResult.ValueForOption <string>("--outputFileName");
            string version                     = context.ParseResult.ValueForOption <string>("--version");
            var    remappedNameValuePairs      = context.ParseResult.ValueForOption <string[]>("--memberRemap");
            var    enumAdditionsNameValuePairs = context.ParseResult.ValueForOption <string[]>("--enumAddition");
            var    enumMakeFlags               = context.ParseResult.ValueForOption <string[]>("--enumMakeFlags");
            var    reducePointerLevelPairs     = context.ParseResult.ValueForOption <string[]>("--reducePointerLevel");
            var    typeImportValuePairs        = context.ParseResult.ValueForOption <string[]>("--typeImport");
            var    requiredNamespaceValuePairs = context.ParseResult.ValueForOption <string[]>("--requiredNamespaceForName");
            var    autoTypeFiles               = context.ParseResult.ValueForOption <string[]>("--autoTypes");
            var    refs                        = context.ParseResult.ValueForOption <string[]>("--ref");
            var    staticLibValuePairs         = context.ParseResult.ValueForOption <string[]>("--staticLibs");

            Dictionary <string, string> remaps = ConvertValuePairsToDictionary(remappedNameValuePairs);
            Dictionary <string, Dictionary <string, string> > enumAdditions = ConvertValuePairsToEnumAdditions(enumAdditionsNameValuePairs);
            var reducePointerLevels = new HashSet <string>(reducePointerLevelPairs ?? (Array.Empty <string>()));
            Dictionary <string, string> typeImports        = ConvertValuePairsToDictionary(typeImportValuePairs);
            Dictionary <string, string> requiredNamespaces = ConvertValuePairsToDictionary(requiredNamespaceValuePairs);
            Dictionary <string, string> staticLibs         = ConvertValuePairsToDictionary(staticLibValuePairs);

            string  rawVersion      = version.Split('-')[0];
            Version assemblyVersion = Version.Parse(rawVersion);

            string archForAutoTypes = arch == "crossarch" ? "common" : arch;
            string archSourceDir    = Path.Combine(sourceDirectory, archForAutoTypes);

            Dictionary <string, string> methodNamesToNamespaces = MetadataUtils.ScraperUtils.GetNameToNamespaceMap(sourceDirectory, MetadataUtils.ScraperUtils.NameOptions.Methods);

            if (requiredNamespaceValuePairs != null)
            {
                // Merge the requiredNamespaceForName entries into what we found the scraped source files
                foreach (KeyValuePair <string, string> requiredItem in requiredNamespaces)
                {
                    if (methodNamesToNamespaces.ContainsKey(requiredItem.Key))
                    {
                        methodNamesToNamespaces[requiredItem.Key] = requiredItem.Value;
                    }
                }
            }

            try
            {
                var autoTypes = AutoTypeHelpers.GetAutoTypesFromFiles(autoTypeFiles);
                if (autoTypes != null && autoTypes.Any())
                {
                    var outputFilePath = Path.Combine(archSourceDir, "autotypes.cs");
                    if (!Directory.Exists(Path.GetDirectoryName(outputFilePath)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(outputFilePath));
                    }

                    using var fileStream = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write, FileShare.Read);
                    NativeTypedefStructsCreator.WriteToStream(methodNamesToNamespaces, autoTypes, fileStream);
                }
            }
            catch (Exception e)
            {
                var error = new GeneratorDiagnostic($"Failed to create source for auto types: {e.Message}", Microsoft.CodeAnalysis.DiagnosticSeverity.Error);
                Console.WriteLine(error.ToString());

                return(-1);
            }

            Console.WriteLine($"Preparing and compiling source files...");
            System.Diagnostics.Stopwatch mainWatch = System.Diagnostics.Stopwatch.StartNew();

            ClangSharpSourceCompilation clangSharpCompliation =
                ClangSharpSourceCompilation.Create(
                    sourceDirectory, arch, interopFileName, remaps, enumAdditions, enumMakeFlags, typeImports, requiredNamespaces, reducePointerLevels, refs, staticLibs);

            System.Diagnostics.Stopwatch errorsWatch = System.Diagnostics.Stopwatch.StartNew();
            Console.WriteLine("  Looking for compilation errors...");
            System.Collections.ObjectModel.ReadOnlyCollection <Microsoft.CodeAnalysis.Diagnostic> diags = clangSharpCompliation.GetDiagnostics();

            int       errors          = 0;
            const int MaxErrorsToShow = 10000;

            foreach (Microsoft.CodeAnalysis.Diagnostic diag in diags)
            {
                if (errors == 0)
                {
                    Console.WriteLine("  errors were found.");
                }

                errors++;
                Console.WriteLine(diag.ToString());
                if (errors >= MaxErrorsToShow)
                {
                    Console.WriteLine($"Only showing the first {MaxErrorsToShow} errors.");
                    break;
                }
            }

            if (errors > 0)
            {
                return(-1);
            }

            Console.WriteLine($"  {OutputUtils.FormatTimespan(errorsWatch.Elapsed)}");

            Console.WriteLine($"{OutputUtils.FormatTimespan(mainWatch.Elapsed)}");
            ClangSharpSourceCompilation.ShowMemory();

            mainWatch.Restart();

            Console.WriteLine($"\r\nEmitting {outputFileName}...");
            var generator =
                ClangSharpSourceWinmdGenerator.GenerateWindmdForCompilation(
                    clangSharpCompliation,
                    typeImports,
                    reducePointerLevels,
                    assemblyVersion,
                    outputFileName);

            mainWatch.Stop();

            foreach (GeneratorDiagnostic diag in generator.GetDiagnostics())
            {
                Console.WriteLine(diag.ToString());
            }

            Console.WriteLine($"{OutputUtils.FormatTimespan(mainWatch.Elapsed)}");
            ClangSharpSourceCompilation.ShowMemory();

            return(generator.WroteWinmd ? 0 : -1);
        }
Пример #3
0
        public static int Run(InvocationContext context)
        {
            string sourceDirectory             = context.ParseResult.ValueForOption <string>("--sourceDir");
            string arch                        = context.ParseResult.ValueForOption <string>("--arch");
            string interopFileName             = context.ParseResult.ValueForOption <string>("--interopFileName");
            string outputFileName              = context.ParseResult.ValueForOption <string>("--outputFileName");
            string version                     = context.ParseResult.ValueForOption <string>("--version");
            var    remappedNameValuePairs      = context.ParseResult.ValueForOption <string[]>("--remap");
            var    enumAdditionsNameValuePairs = context.ParseResult.ValueForOption <string[]>("--enum-Addition");
            var    enumMakeFlags               = context.ParseResult.ValueForOption <string[]>("--enum-Make-Flags");
            var    reducePointerLevelPairs     = context.ParseResult.ValueForOption <string[]>("--reducePointerLevel");
            var    typeImportValuePairs        = context.ParseResult.ValueForOption <string[]>("--typeImport");
            var    requiredNamespaceValuePairs = context.ParseResult.ValueForOption <string[]>("--requiredNamespaceForName");
            var    autoTypes                   = context.ParseResult.ValueForOption <string[]>("--autoTypes");
            var    refs                        = context.ParseResult.ValueForOption <string[]>("--ref");

            var remaps              = ConvertValuePairsToDictionary(remappedNameValuePairs);
            var enumAdditions       = ConvertValuePairsToEnumAdditions(enumAdditionsNameValuePairs);
            var reducePointerLevels = new HashSet <string>(reducePointerLevelPairs ?? (new string[0]));
            var typeImports         = ConvertValuePairsToDictionary(typeImportValuePairs);
            var requiredNamespaces  = ConvertValuePairsToDictionary(requiredNamespaceValuePairs);

            string  rawVersion      = version.Split('-')[0];
            Version assemblyVersion = Version.Parse(rawVersion);

            string archForAutoTypes        = arch == "crossarch" ? "x64" : arch;
            string archSourceDir           = Path.Combine(sourceDirectory, $"generated\\{archForAutoTypes}");
            var    methodNamesToNamespaces = MetadataUtils.ScraperUtils.GetNameToNamespaceMap(archSourceDir, MetadataUtils.ScraperUtils.NameOptions.Methods);

            if (requiredNamespaceValuePairs != null)
            {
                // Merge the requiredNamespaceForName entries into what we found the scraped source files
                foreach (var requiredItem in requiredNamespaces)
                {
                    if (methodNamesToNamespaces.ContainsKey(requiredItem.Key))
                    {
                        methodNamesToNamespaces[requiredItem.Key] = requiredItem.Value;
                    }
                }
            }

            NativeTypedefStructsCreator.CreateNativeTypedefsSourceFile(methodNamesToNamespaces, autoTypes, Path.Combine(archSourceDir, "autotypes.cs"));

            Console.WriteLine($"Compiling source files...");
            System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();

            ClangSharpSourceCompilation clangSharpCompliation =
                ClangSharpSourceCompilation.Create(
                    sourceDirectory, arch, interopFileName, remaps, enumAdditions, enumMakeFlags, typeImports, requiredNamespaces, reducePointerLevels, refs);

            Console.WriteLine("Looking for compilation errors...");
            var diags = clangSharpCompliation.GetDiagnostics();

            watch.Stop();

            int       errors          = 0;
            const int MaxErrorsToShow = 10000;

            foreach (var diag in diags)
            {
                if (errors == 0)
                {
                    Console.WriteLine("errors were found.");
                }

                errors++;
                Console.WriteLine(diag.ToString());
                if (errors >= MaxErrorsToShow)
                {
                    Console.WriteLine($"Only showing the first {MaxErrorsToShow} errors.");
                    break;
                }
            }

            if (errors > 0)
            {
                return(-1);
            }

            string timeTaken = watch.Elapsed.ToString("c");

            watch.Reset();
            watch.Start();

            Console.WriteLine($"Compilation stage took {timeTaken}");

            Console.WriteLine($"\r\nEmitting {outputFileName}...");
            var generator =
                ClangSharpSourceWinmdGenerator.GenerateWindmdForCompilation(
                    clangSharpCompliation,
                    typeImports,
                    reducePointerLevels,
                    assemblyVersion,
                    outputFileName);

            watch.Stop();

            foreach (var diag in generator.GetDiagnostics())
            {
                Console.WriteLine($"{diag.Severity}: {diag.Message}");
            }

            timeTaken = watch.Elapsed.ToString("c");
            Console.WriteLine($"Emit stage took {timeTaken}");

            return(generator.WroteWinmd ? 0 : -1);
        }