mirror of https://github.com/mono/CppSharp.git
Browse Source
Added CppSharp CLI code from CppSharp.CLI repository to add its functionalities to CppSharp.pull/728/head
3 changed files with 512 additions and 0 deletions
@ -0,0 +1,176 @@
@@ -0,0 +1,176 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Security.Policy; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace CppSharp |
||||
{ |
||||
class CLI |
||||
{ |
||||
private static Options _options = new Options(); |
||||
private static List<string> _assemblies; |
||||
|
||||
static void AddIncludeDirs(String dir) |
||||
{ |
||||
_options.IncludeDirs.Add(dir); |
||||
} |
||||
|
||||
static void ParseCommandLineArgs(string[] args) |
||||
{ |
||||
var showHelp = args.Length == 0; |
||||
|
||||
var optionSet = new Mono.Options.OptionSet() |
||||
{ |
||||
{ "h|header=", "the path to an header file to generate source from", h => _options.HeaderFiles.Add(h) }, |
||||
{ "pa|path=", "the path of a folder whose files will generate code (can append a filter at the end like '<path>/*.hpp'", pa => { GetFilesFromPath(pa); } }, |
||||
{ "inc|includedir=", "the path of a folder to search for include files", i => { AddIncludeDirs(i); } }, |
||||
{ "l|library=", "the path of a library that includes the definitions for the generated source code", l => _options.Libraries.Add(l) }, |
||||
{ "ld|librarydir=", "the path of a folder to search for additional libraries", l => _options.LibraryDirs.Add(l) }, |
||||
{ "d|define=", "a define to add for the parse of the given header files", d => _options.Defines.Add(d) }, |
||||
{ "od|outputdir=", "the path for the destination folder that will contain the generated code", od => _options.OutputDir = od }, |
||||
{ "on|outputnamespace=", "the namespace that will be used for the generated code", on => _options.OutputNamespace = on }, |
||||
{ "iln|inputlibraryname=", "the name of the shared library that contains the actual definitions (without extension)", iln => _options.InputLibraryName = iln }, |
||||
{ "isln|inputsharedlibraryname=", "the full name of the shared library that contains the actual definitions (with extension)", isln => _options.InputSharedLibraryName = isln }, |
||||
{ "gen|generator=", "the type of generated code: 'chsarp' or 'cli' ('cli' supported only for Windows)", g => { GetGeneratorKind(g); } }, |
||||
{ "p|platform=", "the platform that the generated code will target: 'win', 'osx', 'linux'", p => { GetDestinationPlatform(p); } }, |
||||
{ "a|arch=", "the architecture that the generated code will target: 'x86', 'x64'", a => { GetDestinationArchitecture(a); } }, |
||||
{ "c++11", "enables GCC C++ 11 compilation (valid only for Linux platform)", cpp11 => { _options.Cpp11ABI = (cpp11 != null); } }, |
||||
{ "cs|checksymbols", "enable the symbol check for the generated code", cs => { _options.CheckSymbols = (cs != null); } }, |
||||
{ "ub|unitybuild", "enable unity build", ub => { _options.UnityBuild = (ub != null); } }, |
||||
{ "help", "shows the help", hl => { showHelp = (hl != null); } } |
||||
}; |
||||
|
||||
try |
||||
{ |
||||
_assemblies = optionSet.Parse(args); |
||||
} |
||||
catch (Mono.Options.OptionException e) |
||||
{ |
||||
Console.WriteLine(e.Message); |
||||
Environment.Exit(0); |
||||
} |
||||
|
||||
if (showHelp) |
||||
{ |
||||
// Print usage and exit.
|
||||
Console.WriteLine("{0} [options]+", AppDomain.CurrentDomain.FriendlyName); |
||||
Console.WriteLine("Generates target language bindings for interop with unmanaged code."); |
||||
Console.WriteLine(); |
||||
optionSet.WriteOptionDescriptions(Console.Out); |
||||
Environment.Exit(0); |
||||
} |
||||
|
||||
if (_assemblies == null) |
||||
{ |
||||
Console.WriteLine("Invalid arguments."); |
||||
Environment.Exit(0); |
||||
} |
||||
} |
||||
|
||||
static void GetFilesFromPath(String path) |
||||
{ |
||||
path = path.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); |
||||
|
||||
String searchPattern = String.Empty; |
||||
int lastSeparatorPosition = path.LastIndexOf(System.IO.Path.AltDirectorySeparatorChar); |
||||
|
||||
if (lastSeparatorPosition >= 0) |
||||
{ |
||||
if (path.IndexOf('*', lastSeparatorPosition) >= lastSeparatorPosition || path.IndexOf('?', lastSeparatorPosition) >= lastSeparatorPosition) |
||||
{ |
||||
searchPattern = path.Substring(lastSeparatorPosition + 1); |
||||
path = path.Substring(0, lastSeparatorPosition); |
||||
} |
||||
} |
||||
|
||||
try |
||||
{ |
||||
if (searchPattern != String.Empty) |
||||
{ |
||||
String[] files = System.IO.Directory.GetFiles(path, searchPattern); |
||||
|
||||
foreach (String s in files) |
||||
_options.HeaderFiles.Add(s); |
||||
} |
||||
else |
||||
{ |
||||
String[] files = System.IO.Directory.GetFiles(path); |
||||
|
||||
foreach (String s in files) |
||||
_options.HeaderFiles.Add(s); |
||||
} |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
Console.WriteLine("Source files path error: " + ex.Message); |
||||
Environment.Exit(0); |
||||
} |
||||
} |
||||
|
||||
static void GetGeneratorKind(String generator) |
||||
{ |
||||
switch (generator.ToLower()) |
||||
{ |
||||
case "csharp": |
||||
_options.Kind = CppSharp.Generators.GeneratorKind.CSharp; |
||||
break; |
||||
case "cli": |
||||
_options.Kind = CppSharp.Generators.GeneratorKind.CLI; |
||||
break; |
||||
} |
||||
|
||||
throw new NotSupportedException("Unknown generator kind: " + generator); |
||||
} |
||||
|
||||
static void GetDestinationPlatform(String platform) |
||||
{ |
||||
switch (platform.ToLower()) |
||||
{ |
||||
case "win": |
||||
_options.Platform = TargetPlatform.Windows; |
||||
break; |
||||
case "osx": |
||||
_options.Platform = TargetPlatform.MacOS; |
||||
break; |
||||
case "linux": |
||||
_options.Platform = TargetPlatform.Linux; |
||||
break; |
||||
} |
||||
|
||||
throw new NotSupportedException("Unknown target platform: " + platform); |
||||
} |
||||
|
||||
static void GetDestinationArchitecture(String architecture) |
||||
{ |
||||
switch (architecture.ToLower()) |
||||
{ |
||||
case "x86": |
||||
_options.Architecture = TargetArchitecture.x86; |
||||
break; |
||||
case "x64": |
||||
_options.Architecture = TargetArchitecture.x64; |
||||
break; |
||||
} |
||||
|
||||
throw new NotSupportedException("Unknown target architecture: " + architecture); |
||||
} |
||||
|
||||
static void Main(string[] args) |
||||
{ |
||||
ParseCommandLineArgs(args); |
||||
|
||||
Generator gen = new Generator(_options); |
||||
|
||||
try |
||||
{ |
||||
gen.Run(); |
||||
} |
||||
catch (Exception ex) |
||||
{ |
||||
Console.WriteLine("Error: " + ex.ToString()); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,259 @@
@@ -0,0 +1,259 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using CppSharp.AST; |
||||
using CppSharp.Generators; |
||||
using CppSharp.Passes; |
||||
using CppSharp.Types; |
||||
using CppAbi = CppSharp.Parser.AST.CppAbi; |
||||
using CppSharp.Parser; |
||||
using CppSharp; |
||||
|
||||
namespace CppSharp |
||||
{ |
||||
class Generator : ILibrary |
||||
{ |
||||
private Options _options; |
||||
|
||||
private String _triple = ""; |
||||
private CppAbi _abi = CppAbi.Microsoft; |
||||
|
||||
public Generator(Options options) |
||||
{ |
||||
if (options == null) |
||||
throw new ArgumentNullException("options"); |
||||
|
||||
_options = options; |
||||
} |
||||
|
||||
public void ValidateOptions() |
||||
{ |
||||
if (Platform.IsWindows && _options.Platform != TargetPlatform.Windows) |
||||
throw new NotSupportedException("Cannot create bindings for a platform other that Windows from a Windows running machine"); |
||||
else if (Platform.IsMacOS && _options.Platform != TargetPlatform.MacOS) |
||||
throw new NotSupportedException("Cannot create bindings for a platform other that MacOS from a MacOS running machine"); |
||||
else if (Platform.IsUnixPlatform && _options.Platform != TargetPlatform.Linux) |
||||
throw new NotSupportedException("Cannot create bindings for a platform other that Linux from a Linux running machine"); |
||||
|
||||
if(_options.Platform != TargetPlatform.Windows && _options.Kind != GeneratorKind.CSharp) |
||||
throw new NotSupportedException("Cannot create bindings for languages other than C# from a non Windows machine"); |
||||
|
||||
if(_options.Platform == TargetPlatform.Linux && _options.Architecture != TargetArchitecture.x64) |
||||
throw new NotSupportedException("Cannot create bindings for architectures other than x64 for Linux machines"); |
||||
|
||||
if(_options.HeaderFiles.Count == 0) |
||||
throw new NotSupportedException("No source header file has been given"); |
||||
|
||||
if (_options.OutputNamespace == String.Empty) |
||||
throw new NotSupportedException("Output namespace is empty"); |
||||
|
||||
if (_options.InputLibraryName == String.Empty) |
||||
throw new NotSupportedException("Input library name is empty"); |
||||
|
||||
if (_options.Architecture == TargetArchitecture.x64) |
||||
_triple = "x86_64-"; |
||||
else if(_options.Architecture == TargetArchitecture.x86) |
||||
_triple = "i686-"; |
||||
|
||||
if (_options.Platform == TargetPlatform.Windows) |
||||
{ |
||||
_triple += "pc-win32-msvc"; |
||||
_abi = CppAbi.Microsoft; |
||||
} |
||||
else if (_options.Platform == TargetPlatform.MacOS) |
||||
{ |
||||
_triple += "apple-darwin12.4.0"; |
||||
_abi = CppAbi.Itanium; |
||||
} |
||||
else if (_options.Platform == TargetPlatform.Linux) |
||||
{ |
||||
_triple += "linux-gnu"; |
||||
_abi = CppAbi.Itanium; |
||||
|
||||
if(_options.Cpp11ABI) |
||||
_triple += "-cxx11abi"; |
||||
} |
||||
} |
||||
|
||||
public void Setup(Driver driver) |
||||
{ |
||||
var parserOptions = driver.ParserOptions; |
||||
parserOptions.TargetTriple = _triple; |
||||
parserOptions.Abi = _abi; |
||||
|
||||
var options = driver.Options; |
||||
options.LibraryName = _options.InputLibraryName; |
||||
|
||||
if(_options.InputSharedLibraryName != String.Empty) |
||||
options.SharedLibraryName = _options.InputSharedLibraryName; |
||||
|
||||
options.GeneratorKind = _options.Kind; |
||||
options.Headers.AddRange(_options.HeaderFiles); |
||||
options.Libraries.AddRange(_options.Libraries); |
||||
|
||||
if (_abi == CppAbi.Microsoft) |
||||
parserOptions.MicrosoftMode = true; |
||||
|
||||
if (_triple.Contains("apple")) |
||||
SetupMacOptions(parserOptions); |
||||
|
||||
if (_triple.Contains("linux")) |
||||
SetupLinuxOptions(parserOptions); |
||||
|
||||
Console.WriteLine("\n\nAdding " + (_options.IncludeDirs.Count) + " include dirs\n\n"); |
||||
|
||||
foreach (String s in _options.IncludeDirs) |
||||
{ |
||||
parserOptions.AddIncludeDirs(s); |
||||
Console.WriteLine("Add include: " + s); |
||||
} |
||||
|
||||
foreach (String s in _options.LibraryDirs) |
||||
parserOptions.AddLibraryDirs(s); |
||||
|
||||
foreach (String s in _options.Defines) |
||||
parserOptions.AddDefines(s); |
||||
|
||||
options.OutputDir = _options.OutputDir; |
||||
options.OutputNamespace = _options.OutputNamespace; |
||||
options.CheckSymbols = _options.CheckSymbols; |
||||
options.UnityBuild = _options.UnityBuild; |
||||
} |
||||
|
||||
private void SetupLinuxOptions(ParserOptions options) |
||||
{ |
||||
options.MicrosoftMode = false; |
||||
options.NoBuiltinIncludes = true; |
||||
|
||||
var headersPath = string.Empty; |
||||
|
||||
// Search for the available GCC versions on the provided headers.
|
||||
var versions = Directory.EnumerateDirectories(Path.Combine(headersPath, "usr/include/c++")); |
||||
|
||||
if (versions.Count() == 0) |
||||
throw new Exception("No valid GCC version found on system include paths"); |
||||
|
||||
string gccVersionPath = versions.First(); |
||||
string gccVersion = gccVersionPath.Substring(gccVersionPath.LastIndexOf(Path.DirectorySeparatorChar) + 1); |
||||
|
||||
string[] systemIncludeDirs = { |
||||
Path.Combine("usr", "include", "c++", gccVersion), |
||||
Path.Combine("usr", "include", "x86_64-linux-gnu", "c++", gccVersion), |
||||
Path.Combine("usr", "include", "c++", gccVersion, "backward"), |
||||
Path.Combine("usr", "lib", "gcc", "x86_64-linux-gnu", gccVersion, "include"), |
||||
Path.Combine("usr", "include", "x86_64-linux-gnu"), |
||||
Path.Combine("usr", "include") |
||||
}; |
||||
|
||||
foreach (var dir in systemIncludeDirs) |
||||
options.AddSystemIncludeDirs(Path.Combine(headersPath, dir)); |
||||
|
||||
options.AddDefines("_GLIBCXX_USE_CXX11_ABI=" + (_options.Cpp11ABI ? "1" : "0")); |
||||
} |
||||
|
||||
private static void SetupMacOptions(ParserOptions options) |
||||
{ |
||||
options.MicrosoftMode = false; |
||||
options.NoBuiltinIncludes = true; |
||||
|
||||
if (Platform.IsMacOS) |
||||
{ |
||||
var headersPaths = new List<string> { |
||||
// Path.Combine(GetSourceDirectory("deps"), "llvm/tools/clang/lib/Headers"),
|
||||
// Path.Combine(GetSourceDirectory("deps"), "libcxx", "include"),
|
||||
"/usr/include" |
||||
}; |
||||
|
||||
foreach (var header in headersPaths) |
||||
Console.WriteLine(header); |
||||
|
||||
foreach (var header in headersPaths) |
||||
options.AddSystemIncludeDirs(header); |
||||
} |
||||
|
||||
// var headersPath = Path.Combine(GetSourceDirectory("build"), "headers", "osx");
|
||||
|
||||
// options.AddSystemIncludeDirs(Path.Combine(headersPath, "include"));
|
||||
// options.AddSystemIncludeDirs(Path.Combine(headersPath, "clang", "4.2", "include"));
|
||||
// options.AddSystemIncludeDirs(Path.Combine(headersPath, "libcxx", "include"));
|
||||
options.AddArguments("-stdlib=libc++"); |
||||
} |
||||
|
||||
public void SetupPasses(Driver driver) |
||||
{ |
||||
driver.AddTranslationUnitPass(new CheckMacroPass()); |
||||
|
||||
driver.Context.TranslationUnitPasses.RenameDeclsUpperCase(RenameTargets.Any); |
||||
driver.Context.TranslationUnitPasses.AddPass(new FunctionToInstanceMethodPass()); |
||||
driver.Context.TranslationUnitPasses.AddPass(new MarshalPrimitivePointersAsRefTypePass()); |
||||
} |
||||
|
||||
public void Preprocess(Driver driver, ASTContext ctx) |
||||
{ |
||||
} |
||||
|
||||
public void Postprocess(Driver driver, ASTContext ctx) |
||||
{ |
||||
new CaseRenamePass( |
||||
RenameTargets.Function | RenameTargets.Method | RenameTargets.Property | RenameTargets.Delegate | |
||||
RenameTargets.Field | RenameTargets.Variable, |
||||
RenameCasePattern.UpperCamelCase).VisitASTContext(driver.Context.ASTContext); |
||||
} |
||||
|
||||
public void Run() |
||||
{ |
||||
ValidateOptions(); |
||||
|
||||
String message = "Generating the "; |
||||
|
||||
switch(_options.Kind) |
||||
{ |
||||
case GeneratorKind.CLI: |
||||
message += "C++/CLI"; |
||||
break; |
||||
case GeneratorKind.CSharp: |
||||
message += "C#"; |
||||
break; |
||||
} |
||||
|
||||
message += " parser bindings for "; |
||||
|
||||
switch (_options.Platform) |
||||
{ |
||||
case TargetPlatform.Linux: |
||||
message += "Linux"; |
||||
break; |
||||
case TargetPlatform.MacOS: |
||||
message += "OSX"; |
||||
break; |
||||
case TargetPlatform.Windows: |
||||
message += "Windows"; |
||||
break; |
||||
} |
||||
|
||||
message += " "; |
||||
|
||||
switch (_options.Architecture) |
||||
{ |
||||
case TargetArchitecture.x86: |
||||
message += "x86"; |
||||
break; |
||||
case TargetArchitecture.x64: |
||||
message += "x64"; |
||||
break; |
||||
} |
||||
|
||||
if(_options.Cpp11ABI) |
||||
message += " (GCC C++11 ABI)"; |
||||
|
||||
message += "..."; |
||||
|
||||
Console.WriteLine(message); |
||||
|
||||
ConsoleDriver.Run(this); |
||||
|
||||
Console.WriteLine(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
|
||||
using CppSharp.Generators; |
||||
|
||||
namespace CppSharp |
||||
{ |
||||
enum TargetPlatform |
||||
{ |
||||
Windows, |
||||
MacOS, |
||||
Linux |
||||
} |
||||
|
||||
enum TargetArchitecture |
||||
{ |
||||
x86, |
||||
x64 |
||||
} |
||||
|
||||
class Options |
||||
{ |
||||
private List<String> _headerFiles = new List<string>(); |
||||
public List<String> HeaderFiles { get { return _headerFiles; } set { _headerFiles = value; } } |
||||
|
||||
private List<String> _includeDirs = new List<string>(); |
||||
public List<String> IncludeDirs { get { return _includeDirs; } set { _includeDirs = value; } } |
||||
|
||||
private List<String> _libraryDirs = new List<string>(); |
||||
public List<String> LibraryDirs { get { return _libraryDirs; } set { _libraryDirs = value; } } |
||||
|
||||
private List<String> _libraries = new List<string>(); |
||||
public List<String> Libraries { get { return _libraries; } set { _libraries = value; } } |
||||
|
||||
private List<String> _defines = new List<string>(); |
||||
public List<String> Defines { get { return _defines; } set { _defines = value; } } |
||||
|
||||
private String _outputDir = ""; |
||||
public String OutputDir { get { return _outputDir; } set { _outputDir = value; } } |
||||
|
||||
private String _outputNamespace = ""; |
||||
public String OutputNamespace { get { return _outputNamespace; } set { _outputNamespace = value; } } |
||||
|
||||
private String _inputLibraryName = ""; |
||||
public String InputLibraryName { get { return _inputLibraryName; } set { _inputLibraryName = value; } } |
||||
|
||||
private String _inputSharedLibraryName = ""; |
||||
public String InputSharedLibraryName { get { return _inputSharedLibraryName; } set { _inputSharedLibraryName = value; } } |
||||
|
||||
private String _triple = ""; |
||||
public String Triple { get { return _triple; } set { _triple = value; } } |
||||
|
||||
private TargetPlatform _platform = TargetPlatform.Windows; |
||||
public TargetPlatform Platform { get { return _platform; } set { _platform = value; } } |
||||
|
||||
private TargetArchitecture _architecture = TargetArchitecture.x86; |
||||
public TargetArchitecture Architecture { get { return _architecture; } set { _architecture = value; } } |
||||
|
||||
private GeneratorKind _kind = GeneratorKind.CSharp; |
||||
public GeneratorKind Kind { get { return _kind; } set { _kind = value; } } |
||||
|
||||
//private bool _verbose = false;
|
||||
//public bool Verbose { get { return _verbose; } set { _verbose = value; } }
|
||||
|
||||
private bool _checkSymbols = false; |
||||
public bool CheckSymbols { get { return _checkSymbols; } set { _checkSymbols = value; } } |
||||
|
||||
private bool _unityBuild = false; |
||||
public bool UnityBuild { get { return _unityBuild; } set { _unityBuild = value; } } |
||||
|
||||
private bool _cpp11ABI = false; |
||||
public bool Cpp11ABI { get { return _cpp11ABI; } set { _cpp11ABI = value; } } |
||||
} |
||||
} |
Loading…
Reference in new issue