コード例 #1
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);
        }
コード例 #2
0
        private void CompileMakefile(GenerateSymbolsPass.SymbolsCodeEventArgs e)
        {
            var pro        = $"{e.Module.SymbolsLibraryName}.pro";
            var path       = Path.Combine(e.OutputDir, pro);
            var proBuilder = new StringBuilder();
            var qtModules  = string.Join(" ", from header in e.Module.Headers
                                         where !header.EndsWith(".h", StringComparison.Ordinal)
                                         select header.Substring("Qt".Length).ToLowerInvariant());

            // QtTest is only library which has a "lib" suffix to its module alias for qmake
            if (qtModules == "test")
            {
                qtModules += "lib";
            }

            proBuilder.Append($"QT += {qtModules}\n");
            proBuilder.Append("CONFIG += c++11\n");
            proBuilder.Append($"TARGET = {e.Module.SymbolsLibraryName}\n");
            proBuilder.Append("TEMPLATE = lib\n");
            proBuilder.Append($"SOURCES += {Path.ChangeExtension(pro, "cpp")}\n");
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                proBuilder.Append("LIBS += -loleaut32 -lole32");
            }
            File.WriteAllText(path, proBuilder.ToString());

            int    error;
            string errorMessage;

            ProcessHelper.Run(this.qtInfo.QMake, $"\"{path}\"", out error, out errorMessage);
            if (!string.IsNullOrEmpty(errorMessage))
            {
                Console.WriteLine(errorMessage);
                return;
            }
            var makefile = File.Exists(Path.Combine(e.OutputDir, "Makefile.Release")) ? "Makefile.Release" : "Makefile";

            e.CustomCompiler    = this.qtInfo.Make;
            e.CompilerArguments = $"-f {makefile}";
            e.OutputDir         = Platform.IsMacOS ? e.OutputDir : Path.Combine(e.OutputDir, "release");
        }
コード例 #3
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("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"));
            File.WriteAllText(path, proBuilder.ToString());
            string error;

            ProcessHelper.Run(this.qmake, string.Format("\"{0}\"", path), out error, this.Driver.Options.OutputDir);
            if (!string.IsNullOrEmpty(error))
            {
                Console.WriteLine(error);
                return(false);
            }
            ProcessHelper.Run(this.make, "-f Makefile.Release", out error, this.Driver.Options.OutputDir);
            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);
        }
コード例 #4
0
        private bool CompileInlines(Module module)
        {
            var pro        = string.Format("{0}.pro", module.InlinesLibraryName);
            var path       = Path.Combine(this.Context.Options.OutputDir, pro);
            var proBuilder = new StringBuilder();
            var qtModules  = string.Join(" ", from header in module.Headers
                                         where !header.EndsWith(".h", StringComparison.Ordinal)
                                         select header.Substring("Qt".Length).ToLowerInvariant());

            switch (qtModules)
            {
            // QtTest is only library which has a "lib" suffix to its module alias for qmake
            case "test":
                qtModules += "lib";
                break;

            // HACK: work around https://bugreports.qt.io/browse/QTBUG-54030
            case "bluetooth":
                qtModules += " network";
                break;
            }

            proBuilder.AppendFormat("QT += {0}\n", qtModules);
            proBuilder.Append("CONFIG += c++11\n");
            proBuilder.Append("QMAKE_CXXFLAGS += -fkeep-inline-functions\n");
            proBuilder.AppendFormat("TARGET = {0}\n", module.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;

            // HACK: Clang does not support -fkeep-inline-functions so force compilation with (the real) GCC on OS X
            ProcessHelper.Run(this.qmake, string.Format("{0}\"{1}\"", Platform.IsMacOS ? "-spec macx-g++ " : string.Empty, path), out error);
            if (!string.IsNullOrEmpty(error))
            {
                Console.WriteLine(error);
                return(false);
            }
            var makefile = File.Exists(Path.Combine(this.Context.Options.OutputDir, "Makefile.Release")) ? "Makefile.Release" : "Makefile";

            if (Platform.IsMacOS)
            {
                // HACK: Clang does not support -fkeep-inline-functions so force compilation with (the real) GCC on OS X
                var makefilePath = Path.Combine(this.Context.Options.OutputDir, makefile);
                var script       = new StringBuilder(File.ReadAllText(makefilePath));
                var xcodePath    = XcodeToolchain.GetXcodePath();
                script.Replace(Path.Combine(xcodePath, "Contents", "Developer", "usr", "bin", "gcc"), "/usr/local/bin/gcc");
                script.Replace(Path.Combine(xcodePath, "Contents", "Developer", "usr", "bin", "g++"), "/usr/local/bin/g++");
                File.WriteAllText(makefilePath, script.ToString());
            }
            ProcessHelper.Run(this.make, string.Format("-j{0} -f {1}", Environment.ProcessorCount + 1, makefile), out error, true);
            if (!string.IsNullOrEmpty(error))
            {
                Console.WriteLine(error);
                return(false);
            }
            return(true);
        }
コード例 #5
0
        private void CompileMakefile(GenerateInlinesPass.InlinesCodeEventArgs e)
        {
            var pro        = $"{e.Module.InlinesLibraryName}.pro";
            var path       = Path.Combine(e.OutputDir, pro);
            var proBuilder = new StringBuilder();
            var qtModules  = string.Join(" ", from header in e.Module.Headers
                                         where !header.EndsWith(".h", StringComparison.Ordinal)
                                         select header.Substring("Qt".Length).ToLowerInvariant());

            // QtTest is only library which has a "lib" suffix to its module alias for qmake
            if (qtModules == "test")
            {
                qtModules += "lib";
            }

            proBuilder.Append($"QT += {qtModules}\n");
            proBuilder.Append("CONFIG += c++11\n");
            proBuilder.Append($"TARGET = {e.Module.InlinesLibraryName}\n");
            proBuilder.Append("TEMPLATE = lib\n");
            proBuilder.Append($"SOURCES += {Path.ChangeExtension(pro, "cpp")}\n");
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                proBuilder.Append("LIBS += -loleaut32 -lole32");
            }
            File.WriteAllText(path, proBuilder.ToString());
            // HACK: work around https://bugreports.qt.io/browse/QTBUG-55952
            if (e.Module.LibraryName == "Qt3DRender.Sharp")
            {
                var cpp        = Path.ChangeExtension(pro, "cpp");
                var unlinkable = new[]
                {
                    "&Qt3DRender::QSortCriterion::tr;",
                    "&Qt3DRender::QSortCriterion::trUtf8;",
                    "&Qt3DRender::qt_getEnumMetaObject;"
                };
                var linkable = (from line in File.ReadLines(cpp)
                                where unlinkable.All(ul => !line.EndsWith(ul, StringComparison.Ordinal))
                                select line).ToList();
                File.WriteAllLines(cpp, linkable);
            }

            if (e.Module.LibraryName == "QtGui.Sharp")
            {
                var cpp        = Path.ChangeExtension(pro, "cpp");
                var unlinkable = new[]
                {
                    "_CoreBackend",
                    "_DeprecatedBackend",
                };

                var linkable = (from line in File.ReadLines(cpp)
                                where unlinkable.All(ul => !line.Contains(ul))
                                select line).ToList();
                File.WriteAllLines(cpp, linkable);
            }

            int    error;
            string errorMessage;

            ProcessHelper.Run(this.qtInfo.QMake, $"\"{path}\"", out error, out errorMessage);
            if (!string.IsNullOrEmpty(errorMessage))
            {
                Console.WriteLine(errorMessage);
                return;
            }
            var makefile = File.Exists(Path.Combine(e.OutputDir, "Makefile.Release")) ? "Makefile.Release" : "Makefile";

            e.CustomCompiler    = this.qtInfo.Make;
            e.CompilerArguments = $"-f {makefile}";
            e.OutputDir         = Platform.IsMacOS ? e.OutputDir : Path.Combine(e.OutputDir, "release");
        }