예제 #1
0
        static int Main()
        {
            SetupPath();

            string includeRoot =
                Path.Combine(
                    Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                    "include");

            var config = new PInvokeGeneratorConfiguration(
                libraryPath: "openxr_loader",
                namespaceName: "OpenXR.PInvoke",
                options: PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles,
                outputLocation: "gen",
                methodClassName: "XR",
                methodPrefixToStrip: "xr"
                );

            string[] files = new[] { "openxr/openxr.h" }
            .Select(name => Path.Combine(includeRoot, name))
            .ToArray();
            int exitCode = 0;

            var translationFlags = CXTranslationUnit_Flags.CXTranslationUnit_None;

            translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes;               // Include attributed types in CXType
            translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes;              // Implicit attributes should be visited

            var clangCommandLineArgs = new List <string> {
                "--include-directory=" + includeRoot,
                "--include-directory=" + Path.Combine(NugetPackagesRoot,
                                                      "cppsharp", "0.10.1", "output", "lib", "clang", "9.0.0", "include"),
                "--language=c++",
            };

            using (var generator = new PInvokeGenerator(config)) {
                foreach (string file in files)
                {
                    var translationUnitError = CXTranslationUnit.TryParse(generator.IndexHandle,
                                                                          file,
                                                                          clangCommandLineArgs.ToArray().AsSpan(),
                                                                          Array.Empty <CXUnsavedFile>(),
                                                                          translationFlags,
                                                                          out CXTranslationUnit handle);
                    bool skipProcessing = false;

                    if (translationUnitError != CXErrorCode.CXError_Success)
                    {
                        Console.WriteLine($"Error: Parsing failed for '{file}' due to '{translationUnitError}'.");
                        skipProcessing = true;
                    }
                    else if (handle.NumDiagnostics != 0)
                    {
                        Console.WriteLine($"Diagnostics for '{file}':");

                        for (uint i = 0; i < handle.NumDiagnostics; ++i)
                        {
                            using var diagnostic = handle.GetDiagnostic(i);

                            Console.Write("    ");
                            Console.WriteLine(diagnostic.Format(CXDiagnostic.DefaultDisplayOptions).ToString());

                            skipProcessing |= (diagnostic.Severity == CXDiagnosticSeverity.CXDiagnostic_Error);
                            skipProcessing |= (diagnostic.Severity == CXDiagnosticSeverity.CXDiagnostic_Fatal);
                        }
                    }

                    if (skipProcessing)
                    {
                        Console.WriteLine($"Skipping '{file}' due to one or more errors listed above.");
                        Console.WriteLine();

                        exitCode = -1;
                        continue;
                    }

                    using var translationUnit = TranslationUnit.GetOrCreate(handle);

                    Console.WriteLine($"Processing '{file}'");
                    generator.GenerateBindings(translationUnit);
                }

                if (generator.Diagnostics.Count != 0)
                {
                    Console.WriteLine("Diagnostics for binding generation:");

                    foreach (var diagnostic in generator.Diagnostics)
                    {
                        Console.Write("    ");
                        Console.WriteLine(diagnostic);

                        if (diagnostic.Level == DiagnosticLevel.Warning)
                        {
                            if (exitCode >= 0)
                            {
                                exitCode++;
                            }
                        }
                        else if (diagnostic.Level == DiagnosticLevel.Error)
                        {
                            if (exitCode >= 0)
                            {
                                exitCode = -1;
                            }
                            else
                            {
                                exitCode--;
                            }
                        }
                    }
                }
            }

            return(exitCode);
        }
예제 #2
0
파일: Clang.cs 프로젝트: thfabian/Bifrost
        /// <summary>
        /// Build the Clang AST
        /// </summary>
        private TranslationUnit BuildClangAST(Configuration config, CXIndex index)
        {
            CXTranslationUnit tu = null;

            using (var section = CreateSection("Building Clang AST"))
            {
                // Assemble the arguments
                var clangArgs = new List <string>()
                {
                    "-Wno-pragma-once-outside-header"
                };

                switch (config.Clang.Language)
                {
                case LanguageEnum.C99:
                    clangArgs.Add("-xc");
                    clangArgs.Add("-std=c99");
                    break;

                case LanguageEnum.Cpp11:
                    clangArgs.Add("-xc++");
                    clangArgs.Add("-std=c++11");
                    break;

                case LanguageEnum.Cpp14:
                    clangArgs.Add("-xc++");
                    clangArgs.Add("-std=c++14");
                    break;

                case LanguageEnum.Cpp17:
                    clangArgs.Add("-xc++");
                    clangArgs.Add("-std=c++17");
                    break;

                default:
                    throw new Exception($"unknown language {config.Clang.Language}");
                }

                clangArgs.AddRange(GetWinSDKDIncludeArgs(config));
                clangArgs.AddRange(GetCxxSTLIncludeArgs(config));

                clangArgs.AddRange(config.Clang.Includes.Select(i => MakeIncludeArg(i)));
                clangArgs.AddRange(config.Clang.Defines.Select((m, v) => $"-D{m}=\"{v}\""));
                clangArgs.AddRange(config.Clang.Arguments.Split(" "));

                var tuFlags = CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies;

                // Create the TU source file
                var sourceFiles = new HashSet <string>();
                config.Hook.Descriptions.Values.ToList().ForEach(hook => hook.Input.ForEach(source => sourceFiles.Add(source)));

                var tuFilename = Path.GetFileNameWithoutExtension(string.IsNullOrEmpty(config.Plugin.Name) ? Path.GetTempFileName() : config.Plugin.Name) + ".cpp";
                Logger.Debug($"Clang TU filename: {tuFilename}");

                var tuSource = "#include <" + string.Join(">\n#include <", sourceFiles) + ">";

                Logger.Debug($"Clang TU source:\n  {tuSource.Replace("\n", "\n  ")}");
                using (var tuSourceFile = CXUnsavedFile.Create(tuFilename, tuSource))
                {
                    // Invoke clang to get the TU
                    Logger.Debug($"Clang args: {string.Join(" ", clangArgs)}");
                    var tuError = CXTranslationUnit.TryParse(index, tuSourceFile.FilenameString, clangArgs.ToArray(), new CXUnsavedFile[] { tuSourceFile }, tuFlags, out tu);
                    if (tuError != CXErrorCode.CXError_Success)
                    {
                        throw new Exception($"clang error: failed to generate tanslation unit: {tuError}");
                    }
                }
                section.Done();
            }
            if (tu == null)
            {
                return(null);
            }
            return(TranslationUnit.GetOrCreate(tu));
        }