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; }
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); }
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>(); }
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; } } }
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"); }
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"); }
public static bool IsTypeExternal(Module module, Type type) { var typeModule = type.GetModule(); return(typeModule != null && typeModule.Dependencies.Contains(module)); }