Beispiel #1
0
 public Driver(DriverOptions options, IDiagnostics diagnostics)
 {
     Options = options;
     Diagnostics = diagnostics;
     Project = new Project();
     ParserOptions = new ParserOptions();
 }
Beispiel #2
0
        /// <summary>
        /// Parses the project source files.
        /// </summary>
        public void ParseProject(Project project, ParserOptions options)
        {
            // TODO: Search for cached AST trees on disk
            // TODO: Do multi-threaded parsing of source files

            foreach (var source in project.Sources)
                ParseSourceFile(source, options);
        }
Beispiel #3
0
        /// <summary>
        /// Parses a library file with symbols.
        /// </summary>
        public ParserResult ParseLibrary(string file, ParserOptions options)
        {
            options.FileName = file;

            var result = Parser.ClangParser.ParseLibrary(options);
            LibraryParsed(file, result);

            return result;
        }
Beispiel #4
0
        public BindingContext(IDiagnostics diagnostics, DriverOptions options,
            ParserOptions parserOptions = null)
        {
            Options = options;
            Diagnostics = diagnostics;
            ParserOptions = parserOptions;

            Symbols = new SymbolContext();
            Delegates = new Dictionary<Function, DelegatesPass.DelegateDefinition>();

            TypeMaps = new TypeMapDatabase();
            TypeMaps.SetupTypeMaps(Options.GeneratorKind);

            TranslationUnitPasses = new PassBuilder<TranslationUnitPass>(this);
            GeneratorOutputPasses = new PassBuilder<GeneratorOutputPass>(this);
        }
Beispiel #5
0
 public override bool VisitLibrary(ASTContext library)
 {
     bool result = base.VisitLibrary(library);
     string pro = string.Format("{0}.pro", this.Driver.Options.InlinesLibraryName);
     string path = Path.Combine(this.Driver.Options.OutputDir, pro);
     StringBuilder proBuilder = new StringBuilder();
     proBuilder.Append("QT += widgets\n");
     // HACK: work around https://bugreports.qt.io/browse/QTBUG-47569
     if (this.Driver.Options.InlinesLibraryName.StartsWith("QtWidgets"))
     {
         proBuilder.Append("DEFINES += QT_NO_ACCESSIBILITY\n");
     }
     proBuilder.Append("QMAKE_CXXFLAGS += -fkeep-inline-functions -std=c++0x\n");
     proBuilder.AppendFormat("TARGET = {0}\n", this.Driver.Options.InlinesLibraryName);
     proBuilder.Append("TEMPLATE = lib\n");
     proBuilder.AppendFormat("SOURCES += {0}\n", Path.ChangeExtension(pro, "cpp"));
     if (Environment.OSVersion.Platform == PlatformID.Win32NT)
     {
         proBuilder.Append("LIBS += -loleaut32 -lole32");
     }
     File.WriteAllText(path, proBuilder.ToString());
     string error;
     ProcessHelper.Run(this.qmake, string.Format("\"{0}\"", path), out error);
     if (!string.IsNullOrEmpty(error))
     {
         Console.WriteLine(error);
         return false;
     }
     ProcessHelper.Run(this.make, "-f Makefile.Release", out error, true);
     if (!string.IsNullOrEmpty(error))
     {
         Console.WriteLine(error);
         return false;
     }
     var parserOptions = new ParserOptions();
     parserOptions.addLibraryDirs(Path.Combine(this.Driver.Options.OutputDir, "release"));
     parserOptions.FileName = Path.GetFileName(string.Format("lib{0}.a", Path.GetFileNameWithoutExtension(pro)));
     var parserResult = ClangParser.ParseLibrary(parserOptions);
     if (parserResult.Kind == ParserResultKind.Success)
     {
         var nativeLibrary = CppSharp.ClangParser.ConvertLibrary(parserResult.Library);
         this.Driver.Symbols.Libraries.Add(nativeLibrary);
         this.Driver.Symbols.IndexSymbols();
     }
     return result;
 }
 private static IList<string> GetDependencies(string library)
 {
     var parserOptions = new ParserOptions();
     parserOptions.AddLibraryDirs(GeneratorTest.GetTestsDirectory("Native"));
     var driverOptions = new DriverOptions();
     driverOptions.Libraries.Add(library);
     var driver = new Driver(driverOptions, new TextDiagnosticPrinter())
     {
         ParserOptions = parserOptions
     };
     foreach (var module in driver.Options.Modules)
         module.LibraryName = "Test";
     driver.Setup();
     Assert.IsTrue(driver.ParseLibraries());
     var dependencies = driver.Context.Symbols.Libraries[0].Dependencies;
     return dependencies;
 }
Beispiel #7
0
 public override bool VisitASTContext(ASTContext context)
 {
     string error;
     const string qtVersionVariable = "QT_VERSION";
     var qtVersion = ProcessHelper.Run(this.qmake, string.Format("-query {0}", qtVersionVariable), out error);
     var qtVersionFile = Path.Combine(this.Context.Options.OutputDir, qtVersionVariable);
     var qtVersionFileInfo = new FileInfo(qtVersionFile);
     var text = string.Empty;
     if (!qtVersionFileInfo.Exists || (text = File.ReadAllText(qtVersionFile)) != qtVersion)
     {
         File.WriteAllText(qtVersionFile, qtVersion);
         qtVersionFileInfo = new FileInfo(qtVersionFile);
     }
     var dir = Platform.IsMacOS ? this.Context.Options.OutputDir : Path.Combine(this.Context.Options.OutputDir, "release");
     foreach (var module in this.Context.Options.Modules)
     {
         var inlines = Path.GetFileName(string.Format("{0}{1}.{2}", Platform.IsWindows ? string.Empty : "lib",
             module.InlinesLibraryName, Platform.IsMacOS ? "dylib" : "dll"));
         var libFile = Path.Combine(dir, inlines);
         var inlinesFileInfo = new FileInfo(libFile);
         if (!inlinesFileInfo.Exists || qtVersionFileInfo.LastWriteTimeUtc > inlinesFileInfo.LastWriteTimeUtc)
         {
             if (!this.CompileInlines(module))
             {
                 continue;
             }
         }
         var parserOptions = new ParserOptions();
         parserOptions.AddLibraryDirs(dir);
         parserOptions.LibraryFile = inlines;
         using (var parserResult = CppSharp.Parser.ClangParser.ParseLibrary(parserOptions))
         {
             if (parserResult.Kind == ParserResultKind.Success)
             {
                 var nativeLibrary = CppSharp.ClangParser.ConvertLibrary(parserResult.Library);
                 this.Context.Symbols.Libraries.Add(nativeLibrary);
                 this.Context.Symbols.IndexSymbols();
                 parserResult.Library.Dispose();
             }
         }
     }
     return true;
 }
Beispiel #8
0
 public override bool VisitLibrary(ASTContext library)
 {
     string error;
     const string qtVersionVariable = "QT_VERSION";
     var qtVersion = ProcessHelper.Run(this.qmake, string.Format("-query {0}", qtVersionVariable), out error);
     var qtVersionFile = Path.Combine(this.Driver.Options.OutputDir, qtVersionVariable);
     var dir = Path.Combine(this.Driver.Options.OutputDir, "release");
     var inlines = Path.GetFileName(string.Format("lib{0}.a", this.Driver.Options.InlinesLibraryName));
     var libFile = Path.Combine(dir, inlines);
     var qtVersionFileInfo = new FileInfo(qtVersionFile);
     var inlinesFileInfo = new FileInfo(libFile);
     string text = string.Empty;
     if (!qtVersionFileInfo.Exists || (text = File.ReadAllText(qtVersionFile)) != qtVersion ||
         !inlinesFileInfo.Exists || qtVersionFileInfo.CreationTimeUtc > inlinesFileInfo.CreationTimeUtc ||
         qtVersionFileInfo.LastWriteTimeUtc > inlinesFileInfo.LastWriteTimeUtc)
     {
         if (text != qtVersion)
         {
             File.WriteAllText(qtVersionFile, qtVersion);
         }
         if (!this.CompileInlines())
         {
             return false;
         }
     }
     var parserOptions = new ParserOptions();
     parserOptions.addLibraryDirs(dir);
     parserOptions.FileName = inlines;
     var parserResult = ClangParser.ParseLibrary(parserOptions);
     if (parserResult.Kind == ParserResultKind.Success)
     {
         var nativeLibrary = CppSharp.ClangParser.ConvertLibrary(parserResult.Library);
         this.Driver.Symbols.Libraries.Add(nativeLibrary);
         this.Driver.Symbols.IndexSymbols();
     }
     return true;
 }
Beispiel #9
0
        protected void ParseLibrary(params string[] files)
        {
            Options = new DriverOptions();
            ParserOptions = new ParserOptions();

            var testsPath = GeneratorTest.GetTestsDirectory("Native");
            ParserOptions.AddIncludeDirs(testsPath);

            Options.Headers.AddRange(files);

            Driver = new Driver(Options, new TextDiagnosticPrinter())
            {
                ParserOptions = this.ParserOptions
            };

            foreach (var module in Driver.Options.Modules)
                module.LibraryName = "Test";
            Driver.Setup();
            Driver.BuildParseOptions();
            if (!Driver.ParseCode())
                throw new Exception("Error parsing the code");

            AstContext = Driver.Context.ASTContext;
        }
Beispiel #10
0
        private static void SetupMacOptions(ParserOptions options)
        {
            options.MicrosoftMode = false;
            options.NoBuiltinIncludes = true;

            if (Platform.IsMacOS)
            {
                var headersPaths = new List<string> {
                    Path.Combine(GetSourceDirectory("deps"), "llvm/tools/clang/lib/Headers"),
                    Path.Combine(GetSourceDirectory("deps"), "libcxx", "include"),
                    "/usr/include",
                };

                foreach (var header in headersPaths)
                    Console.WriteLine(header);

                foreach (var header in headersPaths)
                    options.AddSystemIncludeDirs(header);
            }

            var headersPath = Path.Combine(GetSourceDirectory("build"), "headers",
                "osx");

            options.AddSystemIncludeDirs(Path.Combine(headersPath, "include"));
            options.AddSystemIncludeDirs(Path.Combine(headersPath, "clang", "4.2", "include"));
            options.AddSystemIncludeDirs(Path.Combine(headersPath, "libcxx", "include"));
            options.AddArguments("-stdlib=libc++");
        }
Beispiel #11
0
        private void SetupLinuxOptions(ParserOptions options)
        {
            options.MicrosoftMode = false;
            options.NoBuiltinIncludes = true;

            var headersPath = Platform.IsLinux ? string.Empty :
                Path.Combine(GetSourceDirectory("build"), "headers", "x86_64-linux-gnu");

            // Search for the available GCC versions on the provided headers.
            var versions = Directory.EnumerateDirectories(Path.Combine(headersPath,
                "usr/include/c++"));

            if (versions.Count() == 0)
                throw new Exception("No valid GCC version found on system include paths");

            string gccVersionPath = versions.First();
            string gccVersion = gccVersionPath.Substring(
                gccVersionPath.LastIndexOf(Path.DirectorySeparatorChar) + 1);

            string[] systemIncludeDirs = {
                Path.Combine("usr", "include", "c++", gccVersion),
                Path.Combine("usr", "include", "x86_64-linux-gnu", "c++", gccVersion),
                Path.Combine("usr", "include", "c++", gccVersion, "backward"),
                Path.Combine("usr", "lib", "gcc", "x86_64-linux-gnu", gccVersion, "include"),
                Path.Combine("usr", "include", "x86_64-linux-gnu"),
                Path.Combine("usr", "include")
            };

            foreach (var dir in systemIncludeDirs)
                options.AddSystemIncludeDirs(Path.Combine(headersPath, dir));

            options.AddDefines("_GLIBCXX_USE_CXX11_ABI=" + (IsGnuCpp11Abi ? "1" : "0"));
        }
Beispiel #12
0
        /// <summary>
        /// Parses a C++ source file to a translation unit.
        /// </summary>
        public ParserResult ParseSourceFile(SourceFile file, ParserOptions options)
        {
            options.ASTContext = ASTContext;
            options.FileName = file.Path;

            var result = Parser.ClangParser.ParseHeader(options);
            SourceParsed(file, result);

            return result;
        }
Beispiel #13
0
        /// <summary>
        /// Get info about that target
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public ParserTargetInfo GetTargetInfo(ParserOptions options)
        {
            options.ASTContext = ASTContext;

            return Parser.ClangParser.GetTargetInfo(options);
        }
Beispiel #14
0
        public ParserOptions BuildParseOptions(SourceFile file)
        {
            var options = new ParserOptions
            {
                FileName = file.Path,
                Abi = Options.Abi,
                ToolSetToUse = Options.ToolSetToUse,
                TargetTriple = Options.TargetTriple,
                NoStandardIncludes = Options.NoStandardIncludes,
                NoBuiltinIncludes = Options.NoBuiltinIncludes,
                MicrosoftMode = Options.MicrosoftMode,
                Verbose = Options.Verbose,
                LanguageVersion = Options.LanguageVersion
            };

            for (uint i = 0; i < Options.ArgumentsCount; ++i)
            {
                var arg = Options.getArguments(i);
                options.addArguments(arg);
            }

            for (uint i = 0; i < Options.IncludeDirsCount; ++i)
            {
                var include = Options.getIncludeDirs(i);
                options.addIncludeDirs(include);
            }

            for (uint i = 0; i < Options.SystemIncludeDirsCount; ++i)
            {
                var include = Options.getSystemIncludeDirs(i);
                options.addSystemIncludeDirs(include);
            }

            for (uint i = 0; i < Options.DefinesCount; ++i)
            {
                var define = Options.getDefines(i);
                options.addDefines(define);
            }

            for (uint i = 0; i < Options.LibraryDirsCount; ++i)
            {
                var lib = Options.getLibraryDirs(i);
                options.addLibraryDirs(lib);
            }

            return options;
        }
Beispiel #15
0
 public Driver(DriverOptions options)
 {
     Options       = options;
     ParserOptions = new CppSharp.Parser.ParserOptions();
 }
Beispiel #16
0
        ParserOptions BuildParseOptions(SourceFile file)
        {
            var options = new ParserOptions
            {
                FileName = file.Path,
            #if OLD_PARSER
                IncludeDirs = Options.IncludeDirs,
                SystemIncludeDirs = Options.SystemIncludeDirs,
                Defines = Options.Defines,
                LibraryDirs = Options.LibraryDirs,
            #endif
                Abi = Options.Abi,
                ToolSetToUse = Options.ToolSetToUse,
                TargetTriple = Options.TargetTriple,
                NoStandardIncludes = Options.NoStandardIncludes,
                NoBuiltinIncludes = Options.NoBuiltinIncludes,
                MicrosoftMode = Options.MicrosoftMode,
                Verbose = Options.Verbose,
            };

            return options;
        }
Beispiel #17
0
 protected ParserOptions(ParserOptions.Internal* native, bool skipVTables = false)
 {
     if (native == null)
         return;
     __Instance = new global::System.IntPtr(native);
 }
Beispiel #18
0
 private static ParserOptions.Internal* __CopyValue(ParserOptions.Internal native)
 {
     var ret = Marshal.AllocHGlobal(248);
     CppSharp.Parser.ParserOptions.Internal.cctor_2(ret, new global::System.IntPtr(&native));
     return (ParserOptions.Internal*) ret;
 }
Beispiel #19
0
 private static void* __CopyValue(ParserOptions.Internal native)
 {
     var ret = Marshal.AllocHGlobal(272);
     global::CppSharp.Parser.ParserOptions.Internal.cctor_2(ret, new global::System.IntPtr(&native));
     return ret.ToPointer();
 }
Beispiel #20
0
        public static int Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Please enter the paths to qmake and make.");
                return 0;
            }
            string qmake = args[0];
            if (!File.Exists(qmake))
            {
                Console.WriteLine("The specified qmake does not exist.");
                return -1;
            }
            string make = args[1];
            if (!File.Exists(make))
            {
                Console.WriteLine("The specified make does not exist.");
                return -1;
            }

            string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
            path = Path.GetDirectoryName(make) + Path.PathSeparator + path;
            Environment.SetEnvironmentVariable("Path", path, EnvironmentVariableTarget.Process);

            string error;
            string libs = ProcessHelper.Run(qmake, "-query QT_INSTALL_BINS", out error);
            if (!string.IsNullOrEmpty(error))
            {
                Console.WriteLine(error);
                return -1;
            }
            DirectoryInfo libsInfo = new DirectoryInfo(libs);
            if (!libsInfo.Exists)
            {
                Console.WriteLine(
                    "The directory \"{0}\" that qmake returned as the lib direcory of the Qt installation, does not exist.",
                    libsInfo.Name);
                return -1;
            }
            ICollection<string> libFiles = GetLibFiles(libsInfo);
            string headers = ProcessHelper.Run(qmake, "-query QT_INSTALL_HEADERS", out error);
            if (!string.IsNullOrEmpty(error))
            {
                Console.WriteLine(error);
                return -1;
            }
            DirectoryInfo headersInfo = new DirectoryInfo(headers);
            if (!headersInfo.Exists)
            {
                Console.WriteLine(
                    "The directory \"{0}\" that qmake returned as the header direcory of the Qt installation, does not exist.",
                    headersInfo.Name);
                return -1;
            }
            string docs = ProcessHelper.Run(qmake, "-query QT_INSTALL_DOCS", out error);
            string emptyFile = Environment.OSVersion.Platform == PlatformID.Win32NT ? "NUL" : "/dev/null";
            string output;
            ProcessHelper.Run("gcc", string.Format("-v -E -x c++ {0}", emptyFile), out output);
            string target = Regex.Match(output, @"Target:\s*(?<target>[^\r\n]+)").Groups["target"].Value;
            const string includeDirsRegex = @"#include <\.\.\.> search starts here:(?<includes>.+)End of search list";
            string allIncludes = Regex.Match(output, includeDirsRegex, RegexOptions.Singleline).Groups["includes"].Value;
            var systemIncludeDirs = allIncludes.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Select(Path.GetFullPath);
            Dictionary<string, IEnumerable<string>> dependencies = new Dictionary<string, IEnumerable<string>>();
            var parserOptions = new ParserOptions();
            parserOptions.addLibraryDirs(libs);
            foreach (var libFile in libFiles)
            {
                parserOptions.FileName = libFile;
                var parserResult = ClangParser.ParseLibrary(parserOptions);
                if (parserResult.Kind == ParserResultKind.Success)
                {
                    dependencies[libFile] = CppSharp.ClangParser.ConvertLibrary(parserResult.Library).Dependencies;
                }
                else
                {
                    dependencies[libFile] = Enumerable.Empty<string>();
                }
            }
            var wrappedModules = new List<string> { "Qt5Core.dll", "Qt5Gui.dll", "Qt5Widgets.dll" };
            libFiles = libFiles.TopologicalSort(l => dependencies.ContainsKey(l) ? dependencies[l] : Enumerable.Empty<string>());
            foreach (var libFile in libFiles.Where(libFile => wrappedModules.Contains(libFile)))
            {
                ConsoleDriver.Run(new QtSharp(qmake, make, headers, libs, libFile, target, systemIncludeDirs, docs));
            }

            #if DEBUG
            if (File.Exists("../../../QtSharp.Tests/bin/Debug/QtCore-inlines.dll"))
            {
                File.Delete("../../../QtSharp.Tests/bin/Debug/QtCore-inlines.dll");
            }
            File.Copy("release/QtCore-inlines.dll", "../../../QtSharp.Tests/bin/Debug/QtCore-inlines.dll");
            #else
            if (File.Exists("../../../QtSharp.Tests/bin/Release/QtCore-inlines.dll"))
            {
                File.Delete("../../../QtSharp.Tests/bin/Release/QtCore-inlines.dll");
            }
            System.IO.File.Copy("release/QtCore-inlines.dll", "../../../QtSharp.Tests/bin/Release/QtCore-inlines.dll");
            #endif
            return 0;
        }
Beispiel #21
0
 public static ParserOptions __CreateInstance(ParserOptions.Internal native, bool skipVTables = false)
 {
     return new ParserOptions(native, skipVTables);
 }
Beispiel #22
0
        public ParserOptions BuildForSourceFile(
            IEnumerable <CppSharp.AST.Module> modules, string file = null)
        {
            var options = new ParserOptions(this);

            // This eventually gets passed to Clang's MSCompatibilityVersion, which
            // is in turn used to derive the value of the built-in define _MSC_VER.
            // It used to receive a 4-digit based identifier but now expects a full
            // version MSVC digit, so check if we still have the old version and
            // convert to the right format.

            if (ToolSetToUse.ToString(CultureInfo.InvariantCulture).Length == 4)
            {
                ToolSetToUse *= 100000;
            }

            for (uint i = 0; i < ArgumentsCount; ++i)
            {
                var arg = GetArguments(i);
                options.AddArguments(arg);
            }

            for (uint i = 0; i < IncludeDirsCount; ++i)
            {
                var include = GetIncludeDirs(i);
                options.AddIncludeDirs(include);
            }

            for (uint i = 0; i < SystemIncludeDirsCount; ++i)
            {
                var include = GetSystemIncludeDirs(i);
                options.AddSystemIncludeDirs(include);
            }

            for (uint i = 0; i < DefinesCount; ++i)
            {
                var define = GetDefines(i);
                options.AddDefines(define);
            }

            for (uint i = 0; i < UndefinesCount; ++i)
            {
                var define = GetUndefines(i);
                options.AddUndefines(define);
            }

            for (uint i = 0; i < LibraryDirsCount; ++i)
            {
                var lib = GetLibraryDirs(i);
                options.AddLibraryDirs(lib);
            }

            foreach (var module in modules.Where(
                         m => file == null || m.Headers.Contains(file)))
            {
                foreach (var include in module.IncludeDirs)
                {
                    options.AddIncludeDirs(include);
                }

                foreach (var define in module.Defines)
                {
                    options.AddDefines(define);
                }

                foreach (var undefine in module.Undefines)
                {
                    options.AddUndefines(undefine);
                }

                foreach (var libraryDir in module.LibraryDirs)
                {
                    options.AddLibraryDirs(libraryDir);
                }
            }

            return(options);
        }
Beispiel #23
0
 private ParserOptions(ParserOptions.Internal native, bool skipVTables = false)
     : this(__CopyValue(native), skipVTables)
 {
     __ownsNativeInstance = true;
     NativeToManagedMap[__Instance] = this;
 }
Beispiel #24
0
        ParserOptions BuildParseOptions(SourceFile file)
        {
            var options = new ParserOptions
            {
                FileName = file.Path,
            #if OLD_PARSER
                Arguments = Options.Arguments,
                IncludeDirs = Options.IncludeDirs,
                SystemIncludeDirs = Options.SystemIncludeDirs,
                Defines = Options.Defines,
                LibraryDirs = Options.LibraryDirs,
            #endif
                Abi = Options.Abi,
                ToolSetToUse = Options.ToolSetToUse,
                TargetTriple = Options.TargetTriple,
                NoStandardIncludes = Options.NoStandardIncludes,
                NoBuiltinIncludes = Options.NoBuiltinIncludes,
                MicrosoftMode = Options.MicrosoftMode,
                Verbose = Options.Verbose,
            };

            #if !OLD_PARSER
            for (uint i = 0; i < Options.ArgumentsCount; ++i)
            {
                var arg = Options.getArguments(i);
                options.addArguments(arg);
            }

            for (uint i = 0; i < Options.IncludeDirsCount; ++i)
            {
                var include = Options.getIncludeDirs(i);
                options.addIncludeDirs(include);
            }

            for (uint i = 0; i < Options.SystemIncludeDirsCount; ++i)
            {
                var include = Options.getSystemIncludeDirs(i);
                options.addSystemIncludeDirs(include);
            }

            for (uint i = 0; i < Options.DefinesCount; ++i)
            {
                var define = Options.getDefines(i);
                options.addDefines(define);
            }

            for (uint i = 0; i < Options.LibraryDirsCount; ++i)
            {
                var lib = Options.getLibraryDirs(i);
                options.addLibraryDirs(lib);
            }
            #endif

            return options;
        }
Beispiel #25
0
        public ParserOptions BuildParseOptions(SourceFile file)
        {
            var options = new ParserOptions
            {
                FileName = file.Path,
                Abi = Options.Abi,
                ToolSetToUse = Options.ToolSetToUse,
                TargetTriple = Options.TargetTriple,
                NoStandardIncludes = Options.NoStandardIncludes,
                NoBuiltinIncludes = Options.NoBuiltinIncludes,
                MicrosoftMode = Options.MicrosoftMode,
                Verbose = Options.Verbose,
                LanguageVersion = Options.LanguageVersion
            };

            // This eventually gets passed to Clang's MSCompatibilityVersion, which
            // is in turn used to derive the value of the built-in define _MSC_VER.
            // It used to receive a 4-digit based identifier but now expects a full
            // version MSVC digit, so check if we still have the old version and
            // convert to the right format.

            if (Options.ToolSetToUse.ToString(CultureInfo.InvariantCulture).Length == 4)
                Options.ToolSetToUse *= 100000;

            for (uint i = 0; i < Options.ArgumentsCount; ++i)
            {
                var arg = Options.getArguments(i);
                options.addArguments(arg);
            }

            for (uint i = 0; i < Options.IncludeDirsCount; ++i)
            {
                var include = Options.getIncludeDirs(i);
                options.addIncludeDirs(include);
            }

            for (uint i = 0; i < Options.SystemIncludeDirsCount; ++i)
            {
                var include = Options.getSystemIncludeDirs(i);
                options.addSystemIncludeDirs(include);
            }

            for (uint i = 0; i < Options.DefinesCount; ++i)
            {
                var define = Options.getDefines(i);
                options.addDefines(define);
            }

            for (uint i = 0; i < Options.UndefinesCount; ++i)
            {
                var define = Options.getUndefines(i);
                options.addUndefines(define);
            }

            for (uint i = 0; i < Options.LibraryDirsCount; ++i)
            {
                var lib = Options.getLibraryDirs(i);
                options.addLibraryDirs(lib);
            }

            return options;
        }
Beispiel #26
0
        public static int Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Please enter the paths to qmake and make.");
                return 0;
            }
            string qmake = args[0];
            if (!File.Exists(qmake))
            {
                Console.WriteLine("The specified qmake does not exist.");
                return 1;
            }
            string make = args[1];
            if (!File.Exists(make))
            {
                Console.WriteLine("The specified make does not exist.");
                return 1;
            }
            var debug = args.Length > 2 && (args[2] == "d" || args[2] == "debug");

            ConsoleLogger logredirect = new ConsoleLogger();
            logredirect.CreateLogDirectory();

            string path = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
            path = Path.GetDirectoryName(make) + Path.PathSeparator + path;
            Environment.SetEnvironmentVariable("Path", path, EnvironmentVariableTarget.Process);

            string error;
            string libs = ProcessHelper.Run(qmake, "-query QT_INSTALL_BINS", out error);
            if (!string.IsNullOrEmpty(error))
            {
                Console.WriteLine(error);
                return 1;
            }
            DirectoryInfo libsInfo = new DirectoryInfo(libs);
            if (!libsInfo.Exists)
            {
                Console.WriteLine(
                    "The directory \"{0}\" that qmake returned as the lib direcory of the Qt installation, does not exist.",
                    libsInfo.Name);
                return 1;
            }
            ICollection<string> libFiles = GetLibFiles(libsInfo, debug);
            string headers = ProcessHelper.Run(qmake, "-query QT_INSTALL_HEADERS", out error);
            if (!string.IsNullOrEmpty(error))
            {
                Console.WriteLine(error);
                return 1;
            }
            DirectoryInfo headersInfo = new DirectoryInfo(headers);
            if (!headersInfo.Exists)
            {
                Console.WriteLine(
                    "The directory \"{0}\" that qmake returned as the header direcory of the Qt installation, does not exist.",
                    headersInfo.Name);
                return 1;
            }
            string docs = ProcessHelper.Run(qmake, "-query QT_INSTALL_DOCS", out error);
            string emptyFile = Environment.OSVersion.Platform == PlatformID.Win32NT ? "NUL" : "/dev/null";
            string output;
            ProcessHelper.Run("gcc", string.Format("-v -E -x c++ {0}", emptyFile), out output);
            string target = Regex.Match(output, @"Target:\s*(?<target>[^\r\n]+)").Groups["target"].Value;
            const string includeDirsRegex = @"#include <\.\.\.> search starts here:(?<includes>.+)End of search list";
            string allIncludes = Regex.Match(output, includeDirsRegex, RegexOptions.Singleline).Groups["includes"].Value;
            var systemIncludeDirs = allIncludes.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Select(Path.GetFullPath);
            Dictionary<string, IEnumerable<string>> dependencies = new Dictionary<string, IEnumerable<string>>();
            var parserOptions = new ParserOptions();
            parserOptions.addLibraryDirs(libs);
            foreach (var libFile in libFiles)
            {
                parserOptions.FileName = libFile;
                var parserResult = ClangParser.ParseLibrary(parserOptions);
                if (parserResult.Kind == ParserResultKind.Success)
                {
                    dependencies[libFile] = CppSharp.ClangParser.ConvertLibrary(parserResult.Library).Dependencies;
                }
                else
                {
                    dependencies[libFile] = Enumerable.Empty<string>();
                }
            }
            var modules = new List<string> { "Qt5Core", "Qt5Gui", "Qt5Widgets", "Qt5Xml", "Qt5Designer" };
            if (debug)
            {
                for (var i = 0; i < modules.Count; i++)
                {
                    modules[i] += "d";
                }
            }
            libFiles = libFiles.TopologicalSort(l => dependencies.ContainsKey(l) ? dependencies[l] : Enumerable.Empty<string>());
            var wrappedModules = new List<KeyValuePair<string, string>>(modules.Count);
            var astContexts = new List<ASTContext>(libFiles.Count);
            foreach (var libFile in libFiles.Where(l => modules.Any(m => m == Path.GetFileNameWithoutExtension(l))))
            {
                logredirect.SetLogFile(libFile.Replace(".dll", "") + "Log.txt");
                logredirect.Start();

                var qtSharp = new QtSharp(new QtModuleInfo(qmake, make, headers, libs, libFile, target, systemIncludeDirs, docs),
                                          astContexts);
                ConsoleDriver.Run(qtSharp);
                astContexts.Add(qtSharp.AST);
                if (File.Exists(qtSharp.LibraryName) && File.Exists(Path.Combine("release", qtSharp.InlinesLibraryName)))
                {
                    wrappedModules.Add(new KeyValuePair<string, string>(qtSharp.LibraryName, qtSharp.InlinesLibraryName));
                }
                logredirect.Stop();
            }

            #if DEBUG
            if (File.Exists("../../../QtSharp.Tests/bin/Debug/QtCore-inlines.dll"))
            {
                File.Delete("../../../QtSharp.Tests/bin/Debug/QtCore-inlines.dll");
            }
            File.Copy("release/QtCore-inlines.dll", "../../../QtSharp.Tests/bin/Debug/QtCore-inlines.dll");
            #else
            if (File.Exists("../../../QtSharp.Tests/bin/Release/QtCore-inlines.dll"))
            {
                File.Delete("../../../QtSharp.Tests/bin/Release/QtCore-inlines.dll");
            }
            System.IO.File.Copy("release/QtCore-inlines.dll", "../../../QtSharp.Tests/bin/Release/QtCore-inlines.dll");
            #endif
            if (wrappedModules.Count == 0)
            {
                Console.WriteLine("Generation failed.");
                return 1;
            }

            var qtSharpZip = "QtSharp.zip";
            if (File.Exists(qtSharpZip))
            {
                File.Delete(qtSharpZip);
            }
            using (var zip = File.Create(qtSharpZip))
            {
                using (var zipArchive = new ZipArchive(zip, ZipArchiveMode.Create))
                {
                    foreach (var wrappedModule in wrappedModules)
                    {
                        zipArchive.CreateEntryFromFile(wrappedModule.Key, wrappedModule.Key);
                        var documentation = Path.ChangeExtension(wrappedModule.Key, "xml");
                        zipArchive.CreateEntryFromFile(documentation, documentation);
                        zipArchive.CreateEntryFromFile(Path.Combine("release", wrappedModule.Value), wrappedModule.Value);
                    }
                    zipArchive.CreateEntryFromFile("CppSharp.Runtime.dll", "CppSharp.Runtime.dll");
                }
            }

            return 0;
        }