public static InterfaceReflector FromCSharpSource(List <string> sourceFiles, List <string> referenceSourceFiles, List <string> referenceDllFiles, bool referenceBindGem) { var ir = new InterfaceReflector(); ir.CompileCSharpSource(sourceFiles, referenceSourceFiles, referenceDllFiles, referenceBindGem); return(ir); }
public static InterfaceReflector FromAssembly(string assembly, List <string> referenceAssemblies) { var ir = new InterfaceReflector(); ir.LoadFromAssembly(assembly, referenceAssemblies); return(ir); }
public static void WrappedMain(string[] args) { bool referenceBindGem = false; var opts = new OptionSet() { { "r|ref=", "Reference metadata from specified built file", v => ReferenceDLLFiles.Add(v) }, { "R|srcref=", "Reference source file, but don't generate code for them", v => ReferenceSourceFiles.Add(Path.GetFullPath(v)) }, { "include=", "Reference source file, but don't generate code for them", v => ReferenceSourceFiles.Add(Path.GetFullPath(v)) }, { "o|out=", "Output base file, without extensions", v => OutFile = v }, { "cppInclude=", "Cpp #include statement to generate in the header", v => CppIncludes.Add(v) }, { "cppSrcInclude=", "Cpp #include statement to generate in the source", v => CppSrcIncludes.Add(v) }, { "j|pure-js", "Generate pure JS bindings for components and structs only", v => PureJS = (v != null) }, { "v|verbose", "Verbose output, including compilation errors", v => Verbose = true }, { "internal", "Reference BindGem.exe for bindings attributes", v => referenceBindGem = true }, { "d|devel", "Enable development build", v => Development = true }, { "dots", "Enable DOTS mode", v => DOTS = true }, { "define_guard=", "Define guard to use", v => DefineGuard = v }, }; try { SourceFiles = opts.Parse(args); } catch (OptionException e) { Console.Write("bindgen: "); Console.WriteLine(e.Message); opts.WriteOptionDescriptions(Console.Out); return; } if (OutFile == null) { opts.WriteOptionDescriptions(Console.Out); FatalError($"output must be specified with -o"); } if (DOTS && PureJS) { opts.WriteOptionDescriptions(Console.Out); FatalError("Can't specify both DOTS mode and PureJS mode"); } if (DefineGuard == null) { DefineGuard = $"BINDGEM_BIND_{BindGem.BaseOutputName}_IMPL"; } // C# compiler fails on Windows on paths that are delimited with forward slashes, so normalize all inputs with forward // slashes to use backslashes instead. if (Path.DirectorySeparatorChar == '\\') { for (int i = 0; i < ReferenceDLLFiles.Count; ++i) { ReferenceDLLFiles[i] = ReferenceDLLFiles[i].Replace('/', Path.DirectorySeparatorChar); } for (int i = 0; i < ReferenceSourceFiles.Count; ++i) { ReferenceSourceFiles[i] = ReferenceSourceFiles[i].Replace('/', Path.DirectorySeparatorChar); } OutFile = OutFile.Replace('/', Path.DirectorySeparatorChar); for (int i = 0; i < CppIncludes.Count; ++i) { CppIncludes[i] = CppIncludes[i].Replace('/', Path.DirectorySeparatorChar); } for (int i = 0; i < SourceFiles.Count; ++i) { SourceFiles[i] = SourceFiles[i].Replace('/', Path.DirectorySeparatorChar); } } // Collapse duplicate input entries ReferenceSourceFiles = ReferenceSourceFiles.Distinct().ToList(); CppIncludes = CppIncludes.Distinct().ToList(); CppSrcIncludes = CppSrcIncludes.Distinct().ToList(); InterfaceReflector reflector; if (DOTS) { if (SourceFiles.Count != 1 || ReferenceSourceFiles.Count != 0 || referenceBindGem) { FatalError($"DOTS mode requires exactly one assembly as input source, and no -R srcrefs (only -r assembly refs allowed). --internal is also not allowed."); } reflector = InterfaceReflector.FromAssembly(SourceFiles[0], ReferenceDLLFiles); } else { reflector = InterfaceReflector.FromCSharpSource(SourceFiles, ReferenceSourceFiles, ReferenceDLLFiles, referenceBindGem); } // Validate that the types we loaded are something we can support foreach (var s in reflector.Structs) { TypeUtils.ValidateAllowedObjectType(s); } foreach (var s in reflector.Interfaces) { TypeUtils.ValidateAllowedObjectType(s); } foreach (var s in reflector.Classes) { TypeUtils.ValidateAllowedObjectType(s); } foreach (var s in reflector.Structs) { TypeUtils.PreprocessTypeFields(s, 32); TypeUtils.PreprocessTypeFields(s, 64); } var languagesToGenerate = (SourceLanguage[])Enum.GetValues(typeof(SourceLanguage)); if (DOTS) { languagesToGenerate = new[] { SourceLanguage.CPlusPlus, SourceLanguage.CPlusPlusHeader }; } else if (PureJS) { languagesToGenerate = new[] { SourceLanguage.JavaScript, SourceLanguage.TypeScriptDefinition, SourceLanguage.JSDoc, SourceLanguage.CSharp }; } var generators = new List <ILanguageHandler>(); if (DOTS) { generators.Add(new CppBindingsGenerator()); } else { generators.Add(new EmscriptenGenerator()); if (!PureJS) { generators.Add(new CppBindingsGenerator()); } generators.Add(new TypeScriptDefinitionGenerator()); generators.Add(new JSDocGenerator()); generators.Add(new CGenerator()); generators.Add(new CsBindingsGenerator()); } foreach (var generator in generators) { reflector.ExportedEnums.ForEach(t => generator.HandleEnumType(t)); reflector.ExportedStructs.Where(t => !t.IsComponentType()).ToList().ForEach(t => generator.HandleStructType(t)); reflector.ExportedStructs.Where(t => t.IsComponentType()).ToList().ForEach(t => generator.HandleComponentType(t)); reflector.ExportedDelegates.ForEach(t => generator.HandleCallbackType(t)); reflector.ExportedInterfaces.Where(t => t.HasAttribute("NonSharedPtr") || t.HasAttribute("SharedPtr") || t.HasAttribute("Service")).ToList().ForEach(t => generator.HandleInterfaceType(t)); reflector.ExportedClasses.Where(t => t.IsSystemType() || t.IsSystemFenceType()).ToList().ForEach(t => generator.HandleSystemType(t)); } foreach (var sourceLang in languagesToGenerate) { var lh = new List <ILanguageHandler>(generators); lh.Sort(Comparer <ILanguageHandler> .Create((l1, l2) => l2.GeneratedSourceWeight(sourceLang).CompareTo(l1.GeneratedSourceWeight(sourceLang)))); var src = new StringBuilder(); foreach (var gen in lh) { var langSrc = gen.GetGeneratedSource(sourceLang); if (langSrc == null) { continue; } src.AppendLine(langSrc); } if (src.Length == 0) { continue; } var fileName = OutFile + ExtensionForLanguage(sourceLang); var f = new StreamWriter(fileName); src.Insert(0, PreambleForLanguage(sourceLang)); src.Append(PostambleForLanguage(sourceLang)); // sanitize line endings src = src.Replace("\r\n", "\n"); f.Write(src); f.Close(); } }