Exemple #1
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;
        }
Exemple #2
0
        public DriverOptions()
        {
            OutputDir = Directory.GetCurrentDirectory();

            SystemModule = new Module { OutputNamespace = string.Empty, LibraryName = "Std" };
            Modules = new List<Module> { SystemModule };

            GeneratorKind = GeneratorKind.CSharp;
            OutputInteropIncludes = true;
            CommentPrefix = "///";

            Encoding = Encoding.ASCII;

            StripLibPrefix = true;

            ExplicitlyPatchedVirtualFunctions = new HashSet<string>();
        }
        public override void Setup(Driver driver)
        {
            base.Setup(driver);
            driver.Options.GenerateDefaultValuesForArguments = true;
            driver.Options.GeneratePropertiesAdvanced = true;

            driver.Options.Modules[0].IncludeDirs.Add(GetTestsDirectory("NamespacesDerived"));
            var @base = "NamespacesBase";
            var module = new Module();
            module.IncludeDirs.Add(Path.GetFullPath(GetTestsDirectory(@base)));
            module.Headers.Add(string.Format("{0}.h", @base));
            module.OutputNamespace = @base;
            module.SharedLibraryName = string.Format("{0}.Native", @base);
            // Workaround for CLR which does not check for .dll if the name already has a dot
            if (System.Type.GetType("Mono.Runtime") == null)
                module.SharedLibraryName += ".dll";
            module.LibraryName = string.Format("{0}.CSharp", @base);
            driver.Options.Modules.Insert(0, module);
        }
Exemple #4
0
        public DriverOptions()
        {
            Abi = IsUnixPlatform ? CppAbi.Itanium : CppAbi.Microsoft;
            MicrosoftMode = !IsUnixPlatform;

            OutputDir = Directory.GetCurrentDirectory();

            SystemModule = new Module { OutputNamespace = string.Empty, LibraryName = "Std" };
            Modules = new List<Module> { SystemModule };

            GeneratorKind = GeneratorKind.CSharp;
            GeneratePartialClasses = true;
            GenerateClassMarshals = false;
            OutputInteropIncludes = true;
            MaxIndent = 80;
            CommentPrefix = "///";

            Encoding = Encoding.ASCII;

            StripLibPrefix = true;

            ExplicitlyPatchedVirtualFunctions = new HashSet<string>();
        }
Exemple #5
0
        public void CompileCode(AST.Module module)
        {
            var assemblyFile = Path.Combine(Options.OutputDir, module.LibraryName + ".dll");

            var docFile = Path.ChangeExtension(assemblyFile, ".xml");

            var compilerOptions = new StringBuilder();

            compilerOptions.Append($" /doc:\"{docFile}\"");
            compilerOptions.Append(" /debug:pdbonly");
            compilerOptions.Append(" /unsafe");

            var compilerParameters = new CompilerParameters
            {
                GenerateExecutable    = false,
                TreatWarningsAsErrors = false,
                OutputAssembly        = assemblyFile,
                GenerateInMemory      = false,
                CompilerOptions       = compilerOptions.ToString()
            };

            if (module != Options.SystemModule)
            {
                compilerParameters.ReferencedAssemblies.Add(
                    Path.Combine(Options.OutputDir, $"{Options.SystemModule.LibraryName}.dll"));
            }
            // add a reference to System.Core
            compilerParameters.ReferencedAssemblies.Add(typeof(Enumerable).Assembly.Location);

            var location        = Assembly.GetExecutingAssembly().Location;
            var outputDir       = Path.GetDirectoryName(location);
            var locationRuntime = Path.Combine(outputDir, "CppSharp.Runtime.dll");

            compilerParameters.ReferencedAssemblies.Add(locationRuntime);

            compilerParameters.ReferencedAssemblies.AddRange(Context.Symbols.Libraries.SelectMany(
                                                                 lib => lib.Dependencies.Where(
                                                                     d => libraryMappings.ContainsKey(d) &&
                                                                     !compilerParameters.ReferencedAssemblies.Contains(libraryMappings[d]))
                                                                 .Select(l => libraryMappings[l])).ToArray());

            Diagnostics.Message($"Compiling {module.LibraryName}...");
            CompilerResults compilerResults;

            using (var codeProvider = new CSharpCodeProvider(
                       new Dictionary <string, string> {
                { "CompilerDirectoryPath", ManagedToolchain.FindCSharpCompilerDir() }
            }))
            {
                compilerResults = codeProvider.CompileAssemblyFromFile(
                    compilerParameters, module.CodeFiles.ToArray());
            }

            var errors = compilerResults.Errors.Cast <CompilerError>().Where(e => !e.IsWarning &&
                                                                             // HACK: auto-compiling on OS X produces "errors" which do not affect compilation so we ignore them
                                                                             (!Platform.IsMacOS || !e.ErrorText.EndsWith("(Location of the symbol related to previous warning)", StringComparison.Ordinal))).ToList();

            foreach (var error in errors)
            {
                Diagnostics.Error(error.ToString());
            }

            HasCompilationErrors = errors.Count > 0;
            if (!HasCompilationErrors)
            {
                Diagnostics.Message("Compilation succeeded.");
                var wrapper = Path.Combine(outputDir, assemblyFile);
                foreach (var library in module.Libraries)
                {
                    libraryMappings[library] = wrapper;
                }
            }
        }
Exemple #6
0
        public void Setup(Driver driver)
        {
            driver.ParserOptions.MicrosoftMode = false;
            driver.ParserOptions.NoBuiltinIncludes = true;
            driver.ParserOptions.TargetTriple = this.qtInfo.Target;
            driver.ParserOptions.Abi = CppAbi.Itanium;
            driver.ParserOptions.Verbose = true;
            driver.ParserOptions.AddDefines("__float128=void");
            driver.Options.GeneratorKind = GeneratorKind.CSharp;
            driver.Options.UnityBuild = true;
            driver.Options.IgnoreParseWarnings = true;
            driver.Options.CheckSymbols = true;
            driver.Options.CompileCode = true;
            driver.Options.GenerateDefaultValuesForArguments = true;
            driver.Options.MarshalCharAsManagedChar = true;

            string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            const string qt = "Qt";
            foreach (var libFile in this.qtInfo.LibFiles)
            {
                string qtModule = GetModuleNameFromLibFile(libFile);
                var module = new CppSharp.AST.Module();
                module.LibraryName = string.Format("{0}.Sharp", qtModule);
                module.Headers.Add(qtModule);
                var moduleName = qtModule.Substring(qt.Length);
                // some Qt modules have their own name-spaces
                if (moduleName == "Charts" || moduleName == "DataVisualization" ||
                    moduleName.StartsWith("3D", System.StringComparison.Ordinal))
                {
                    module.OutputNamespace = string.Empty;
                    module.InlinesLibraryName = string.Format("{0}-inlines", qtModule);
                    module.TemplatesLibraryName = string.Format("{0}-templates", qtModule);
                }
                else
                {
                    module.OutputNamespace = qtModule;
                }
                if (Platform.IsMacOS)
                {
                    var framework = string.Format("{0}.framework", qtModule);
                    module.IncludeDirs.Add(Path.Combine(this.qtInfo.Libs, framework));
                    module.IncludeDirs.Add(Path.Combine(this.qtInfo.Libs, framework, "Headers"));
                    if (moduleName == "UiPlugin")
                    {
                        var qtUiPlugin = string.Format("Qt{0}.framework", moduleName);
                        module.IncludeDirs.Add(Path.Combine(this.qtInfo.Libs, qtUiPlugin));
                        module.IncludeDirs.Add(Path.Combine(this.qtInfo.Libs, qtUiPlugin, "Headers"));
                    }
                }
                else
                {
                    var moduleInclude = Path.Combine(qtInfo.Headers, qtModule);
                    if (Directory.Exists(moduleInclude))
                        module.IncludeDirs.Add(moduleInclude);
                    if (moduleName == "Designer")
                    {
                        module.IncludeDirs.Add(Path.Combine(qtInfo.Headers, "QtUiPlugin"));
                    }
                }
                if (moduleName == "Designer")
                {
                    foreach (var header in Directory.EnumerateFiles(module.IncludeDirs.Last(), "*.h"))
                    {
                        module.Headers.Add(Path.GetFileName(header));
                    }
                }
                module.Libraries.Add(libFile);
                if (moduleName == "Core")
                {
                    module.CodeFiles.Add(Path.Combine(dir, "QObject.cs"));
                    module.CodeFiles.Add(Path.Combine(dir, "QChar.cs"));
                    module.CodeFiles.Add(Path.Combine(dir, "QEvent.cs"));
                }

                driver.Options.Modules.Add(module);
            }

            foreach (var systemIncludeDir in this.qtInfo.SystemIncludeDirs)
                driver.ParserOptions.AddSystemIncludeDirs(systemIncludeDir);

            if (Platform.IsMacOS)
            {
                foreach (var frameworkDir in this.qtInfo.FrameworkDirs)
                    driver.ParserOptions.AddArguments(string.Format("-F{0}", frameworkDir));
                driver.ParserOptions.AddArguments(string.Format("-F{0}", qtInfo.Libs));
            }

            driver.ParserOptions.AddIncludeDirs(qtInfo.Headers);

            driver.ParserOptions.AddLibraryDirs(Platform.IsWindows ? qtInfo.Bins : qtInfo.Libs);

            // Qt defines its own GUID with the same header guard as the system GUID, so ensure the system GUID is read first
            driver.Project.AddFile("guiddef.h");
        }
Exemple #7
0
        public void Setup(Driver driver)
        {
            driver.ParserOptions.MicrosoftMode     = false;
            driver.ParserOptions.NoBuiltinIncludes = true;
            driver.ParserOptions.TargetTriple      = this.qtInfo.Target;
            driver.ParserOptions.Abi     = CppAbi.Itanium;
            driver.ParserOptions.Verbose = true;
            driver.ParserOptions.AddDefines("__float128=void");
            driver.Options.GeneratorKind       = GeneratorKind.CSharp;
            driver.Options.UnityBuild          = true;
            driver.Options.IgnoreParseWarnings = true;
            driver.Options.CheckSymbols        = true;
            driver.Options.CompileCode         = true;
            driver.Options.GenerateDefaultValuesForArguments = true;
            driver.Options.MarshalCharAsManagedChar          = true;

            string       dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            const string qt  = "Qt";

            foreach (var libFile in this.qtInfo.LibFiles)
            {
                string qtModule = GetModuleNameFromLibFile(libFile);
                var    module   = new CppSharp.AST.Module();
                module.LibraryName = string.Format("{0}.Sharp", qtModule);
                module.Headers.Add(qtModule);
                var moduleName = qtModule.Substring(qt.Length);
                // some Qt modules have their own name-spaces
                if (moduleName == "Charts" || moduleName == "DataVisualization" ||
                    moduleName.StartsWith("3D", System.StringComparison.Ordinal))
                {
                    module.OutputNamespace      = string.Empty;
                    module.InlinesLibraryName   = string.Format("{0}-inlines", qtModule);
                    module.TemplatesLibraryName = string.Format("{0}-templates", qtModule);
                }
                else
                {
                    module.OutputNamespace = qtModule;
                }
                if (Platform.IsMacOS)
                {
                    var framework = string.Format("{0}.framework", qtModule);
                    module.IncludeDirs.Add(Path.Combine(this.qtInfo.Libs, framework));
                    module.IncludeDirs.Add(Path.Combine(this.qtInfo.Libs, framework, "Headers"));
                    if (moduleName == "UiPlugin")
                    {
                        var qtUiPlugin = string.Format("Qt{0}.framework", moduleName);
                        module.IncludeDirs.Add(Path.Combine(this.qtInfo.Libs, qtUiPlugin));
                        module.IncludeDirs.Add(Path.Combine(this.qtInfo.Libs, qtUiPlugin, "Headers"));
                    }
                }
                else
                {
                    var moduleInclude = Path.Combine(qtInfo.Headers, qtModule);
                    if (Directory.Exists(moduleInclude))
                    {
                        module.IncludeDirs.Add(moduleInclude);
                    }
                    if (moduleName == "Designer")
                    {
                        module.IncludeDirs.Add(Path.Combine(qtInfo.Headers, "QtUiPlugin"));
                    }
                }
                if (moduleName == "Designer")
                {
                    foreach (var header in Directory.EnumerateFiles(module.IncludeDirs.Last(), "*.h"))
                    {
                        module.Headers.Add(Path.GetFileName(header));
                    }
                }
                module.Libraries.Add(libFile);
                if (moduleName == "Core")
                {
                    module.CodeFiles.Add(Path.Combine(dir, "QObject.cs"));
                    module.CodeFiles.Add(Path.Combine(dir, "QChar.cs"));
                    module.CodeFiles.Add(Path.Combine(dir, "QEvent.cs"));
                }

                driver.Options.Modules.Add(module);
            }

            foreach (var systemIncludeDir in this.qtInfo.SystemIncludeDirs)
            {
                driver.ParserOptions.AddSystemIncludeDirs(systemIncludeDir);
            }

            if (Platform.IsMacOS)
            {
                foreach (var frameworkDir in this.qtInfo.FrameworkDirs)
                {
                    driver.ParserOptions.AddArguments(string.Format("-F{0}", frameworkDir));
                }
                driver.ParserOptions.AddArguments(string.Format("-F{0}", qtInfo.Libs));
            }

            driver.ParserOptions.AddIncludeDirs(qtInfo.Headers);

            driver.ParserOptions.AddLibraryDirs(Platform.IsWindows ? qtInfo.Bins : qtInfo.Libs);

            // Qt defines its own GUID with the same header guard as the system GUID, so ensure the system GUID is read first
            driver.Project.AddFile("guiddef.h");
        }
Exemple #8
0
        public static bool IsTypeExternal(Module module, Type type)
        {
            var typeModule = type.GetModule();

            return(typeModule != null && typeModule.Dependencies.Contains(module));
        }