public void SaveCode(IEnumerable <GeneratorOutput> outputs) { var outputPath = Path.GetFullPath(Options.OutputDir); if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } foreach (var output in outputs.Where(o => o.TranslationUnit.IsValid)) { var fileBase = output.TranslationUnit.FileNameWithoutExtension; if (Options.UseHeaderDirectories) { var dir = Path.Combine(outputPath, output.TranslationUnit.FileRelativeDirectory); Directory.CreateDirectory(dir); fileBase = Path.Combine(output.TranslationUnit.FileRelativeDirectory, fileBase); } if (Options.GenerateName != null) { fileBase = Options.GenerateName(output.TranslationUnit); } foreach (var template in output.Templates) { var fileRelativePath = string.Format("{0}.{1}", fileBase, template.FileExtension); var file = Path.Combine(outputPath, fileRelativePath); File.WriteAllText(file, template.Generate()); output.TranslationUnit.Module.CodeFiles.Add(file); Diagnostics.Message("Generated '{0}'", fileRelativePath); } } }
void OnFileParsed(string file, ParserResult result) { switch (result.Kind) { case ParserResultKind.Success: Diagnostics.Message("Parsed '{0}'", file); break; case ParserResultKind.Error: Diagnostics.Error("Error parsing '{0}'", file); break; case ParserResultKind.FileNotFound: Diagnostics.Error("File '{0}' was not found", file); break; } for (uint i = 0; i < result.DiagnosticsCount; ++i) { var diag = result.getDiagnostics(i); if (Options.IgnoreParseWarnings && diag.Level == ParserDiagnosticLevel.Warning) { continue; } if (diag.Level == ParserDiagnosticLevel.Note) { continue; } Diagnostics.Message("{0}({1},{2}): {3}: {4}", diag.FileName, diag.LineNumber, diag.ColumnNumber, diag.Level.ToString().ToLower(), diag.Message); } }
public static void Run(ILibrary library) { var options = new DriverOptions(); var driver = new Driver(options); library.Setup(driver); driver.Setup(); if (driver.ParserOptions.Verbose) { Diagnostics.Level = DiagnosticKind.Debug; } if (!options.Quiet) { Diagnostics.Message("Parsing libraries..."); } if (!driver.ParseLibraries()) { return; } if (!options.Quiet) { Diagnostics.Message("Parsing code..."); } driver.BuildParseOptions(); if (!driver.ParseCode()) { Diagnostics.Error("CppSharp has encountered an error while parsing code."); return; } new CleanUnitPass { Context = driver.Context }.VisitASTContext(driver.Context.ASTContext); options.Modules.RemoveAll(m => m != options.SystemModule && !m.Units.GetGenerated().Any()); if (!options.Quiet) { Diagnostics.Message("Processing code..."); } driver.SetupPasses(library); library.Preprocess(driver, driver.Context.ASTContext); driver.ProcessCode(); library.Postprocess(driver, driver.Context.ASTContext); if (!options.Quiet) { Diagnostics.Message("Generating code..."); } var outputs = driver.GenerateCode(); foreach (var output in outputs) { foreach (var pass in driver.Context.GeneratorOutputPasses.Passes) { pass.VisitGeneratorOutput(output); } } if (!driver.Options.DryRun) { driver.SaveCode(outputs); if (driver.Options.IsCSharpGenerator && driver.Options.CompileCode) { foreach (var module in driver.Options.Modules) { driver.CompileCode(module); if (driver.HasCompilationErrors) { break; } } } } driver.Generator.Dispose(); driver.Context.TargetInfo.Dispose(); driver.ParserOptions.Dispose(); }
public void CompileCode(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 = System.Reflection.Assembly.GetExecutingAssembly().Location; var outputDir = Path.GetDirectoryName(location); var locationRuntime = Path.Combine(outputDir, "CppSharp.Runtime.dll"); compilerParameters.ReferencedAssemblies.Add(locationRuntime); compilerParameters.ReferencedAssemblies.AddRange( (from dependency in module.Dependencies where libraryMappings.ContainsKey(dependency) select libraryMappings[dependency]).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) { libraryMappings[module] = Path.Combine(outputDir, assemblyFile); Diagnostics.Message("Compilation succeeded."); } }
public void CompileCode(AST.Module module) { var assemblyFile = string.IsNullOrEmpty(module.LibraryName) ? "out.dll" : module.LibraryName + ".dll"; var docFile = Path.ChangeExtension(Path.GetFileName(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( string.Format("{0}.dll", Options.SystemModule.LibraryName)); } // 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 {0}...", module.LibraryName); CompilerResults compilerResults; using (var codeProvider = new CSharpCodeProvider( new Dictionary <string, string> { { "CompilerVersion", "v4.0" } })) { 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 CompileCode() { var assemblyFile = string.IsNullOrEmpty(Options.LibraryName) ? "out.dll" : Options.LibraryName + ".dll"; var docFile = Path.ChangeExtension(Path.GetFileName(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() }; // 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(Symbols.Libraries.SelectMany( lib => lib.Dependencies.Where( d => libraryMappings.ContainsKey(d) && !compilerParameters.ReferencedAssemblies.Contains(libraryMappings[d])) .Select(l => libraryMappings[l])).ToArray()); Diagnostics.Message("Compiling generated code..."); CompilerResults compilerResults; using (var codeProvider = new CSharpCodeProvider( new Dictionary <string, string> { { "CompilerVersion", "v4.0" } })) { compilerResults = codeProvider.CompileAssemblyFromDom( compilerParameters, compileUnits.ToArray()); } var errors = compilerResults.Errors.Cast <CompilerError>().Where(e => !e.IsWarning).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 Options.Libraries) { libraryMappings[library] = wrapper; } } }