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; }
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; }
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; }
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; }
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; }
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; }
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; }