From 555c51589ee889e5399e1061b168ec60ae291a03 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Fri, 8 Dec 2017 19:09:38 +0200 Subject: [PATCH 01/16] Consistently declare classes/structs. Fixes issue where compilation error is produced due to file name containing constants matching class marked as value type. --- src/Generator/Generators/CSharp/CSharpSources.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 8da934c8..e0334a1e 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -213,7 +213,9 @@ namespace CppSharp.Generators.CSharp PushBlock(BlockKind.Functions); var parentName = SafeIdentifier(context.TranslationUnit.FileNameWithoutExtension); - WriteLine("public unsafe partial class {0}", parentName); + var @class = context.Classes.Find(c => c.Name == parentName); + var keyword = @class != null && @class.IsValueType ? "struct" : "class"; + WriteLine($"public unsafe partial {keyword} {parentName}"); WriteStartBraceIndent(); PushBlock(BlockKind.InternalsClass); @@ -3233,4 +3235,4 @@ namespace CppSharp.Generators.CSharp public SymbolNotFoundException(string msg) : base(msg) {} } -} \ No newline at end of file +} From 03f7f62e95ea59d1fb30cd21e3400ddcca97dc31 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Fri, 8 Dec 2017 18:49:09 +0200 Subject: [PATCH 02/16] Fix `Delegates` namespace being not generated. In some cases `Delegates` namespace could be attached to a namespace which is not wrapped and as a result of that `Delegates` namespace was also not generated in wrapper code resulting in a wrapper build errors. Change adds extra logic which tries to find the correct library namespace if more than one namespace is present. --- src/Generator/Passes/DelegatesPass.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Generator/Passes/DelegatesPass.cs b/src/Generator/Passes/DelegatesPass.cs index 366ab905..36e37734 100644 --- a/src/Generator/Passes/DelegatesPass.cs +++ b/src/Generator/Passes/DelegatesPass.cs @@ -187,6 +187,15 @@ namespace CppSharp.Passes ).GroupBy(d => d.Name).Where(g => g.Any(d => d.HasDeclarations)).ToList(); if (groups.Count == 1) parent = groups.Last().Last(); + else + { + foreach (var g in groups) + { + parent = g.ToList().Find(ns => ns.Name == module.LibraryName || ns.Name == module.OutputNamespace); + if (parent != null) + break; + } + } } if (parent == null) From 9c64e443f850c37d2d8a88de11eb5a8b2312d056 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Fri, 8 Dec 2017 19:09:19 +0200 Subject: [PATCH 03/16] Always generate formatted code. --- src/Generator/Generators/CodeGenerator.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Generator/Generators/CodeGenerator.cs b/src/Generator/Generators/CodeGenerator.cs index bd93522d..29afbad6 100644 --- a/src/Generator/Generators/CodeGenerator.cs +++ b/src/Generator/Generators/CodeGenerator.cs @@ -61,14 +61,6 @@ namespace CppSharp.Generators public abstract void Process(); - public override string Generate() - { - if (Options.IsCSharpGenerator && Options.CompileCode && !Options.GenerateDebugOutput) - return base.GenerateUnformatted(); - - return base.Generate(); - } - public virtual void GenerateFilePreamble(CommentKind kind, string generatorName = "CppSharp") { var lines = new List From b47ecd59b4eab9922407ad68523c022885d2c1f3 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sat, 9 Dec 2017 11:54:26 +0200 Subject: [PATCH 04/16] CI: x64 builds on msvc and sudo requirement for travis --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 513ef77c..53be47bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: cpp +sudo: required os: - linux diff --git a/appveyor.yml b/appveyor.yml index d2d9275e..f7f3cff8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,6 +25,7 @@ os: Visual Studio 2017 platform: - x86 + - x64 configuration: - Release From e6c63468600e21b8a0c85fef92da5c5707d33ec1 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sat, 9 Dec 2017 15:20:26 +0200 Subject: [PATCH 05/16] Completely remove `GenerateUnformatted()` method. --- src/Generator/Utils/BlockGenerator.cs | 54 --------------------------- 1 file changed, 54 deletions(-) diff --git a/src/Generator/Utils/BlockGenerator.cs b/src/Generator/Utils/BlockGenerator.cs index bf4d0d0d..ee807a18 100644 --- a/src/Generator/Utils/BlockGenerator.cs +++ b/src/Generator/Utils/BlockGenerator.cs @@ -183,55 +183,6 @@ namespace CppSharp return builder.ToString(); } - public StringBuilder GenerateUnformatted() - { - if (CheckGenerate != null && !CheckGenerate()) - return new StringBuilder(0); - - if (Blocks.Count == 0) - return Text.StringBuilder; - - var builder = new StringBuilder(); - Block previousBlock = null; - - var blockIndex = 0; - foreach (var childBlock in Blocks) - { - var childText = childBlock.GenerateUnformatted(); - - var nextBlock = (++blockIndex < Blocks.Count) - ? Blocks[blockIndex] - : null; - - if (nextBlock != null) - { - var nextText = nextBlock.GenerateUnformatted(); - if (nextText.Length == 0 && - childBlock.NewLineKind == NewLineKind.IfNotEmpty) - continue; - } - - if (childText.Length == 0) - continue; - - if (previousBlock != null && - previousBlock.NewLineKind == NewLineKind.BeforeNextBlock) - builder.AppendLine(); - - builder.Append(childText); - - if (childBlock.NewLineKind == NewLineKind.Always) - builder.AppendLine(); - - previousBlock = childBlock; - } - - if (Text.StringBuilder.Length != 0) - builder.Append(Text.StringBuilder); - - return builder; - } - public bool IsEmpty { get @@ -323,11 +274,6 @@ namespace CppSharp return RootBlock.Generate(); } - public string GenerateUnformatted() - { - return RootBlock.GenerateUnformatted().ToString(); - } - #region Block helpers public void AddBlock(Block block) From 1165b3020eeec52041b4f566af5b47d6ad175113 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sat, 9 Dec 2017 15:47:42 +0200 Subject: [PATCH 06/16] Fix debug output breaking generated binding code. --- src/Generator/Generators/CodeGenerator.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Generator/Generators/CodeGenerator.cs b/src/Generator/Generators/CodeGenerator.cs index 29afbad6..d102055f 100644 --- a/src/Generator/Generators/CodeGenerator.cs +++ b/src/Generator/Generators/CodeGenerator.cs @@ -92,7 +92,14 @@ namespace CppSharp.Generators public virtual void GenerateDebug(Declaration decl) { if (Options.GenerateDebugOutput && !string.IsNullOrWhiteSpace(decl.DebugText)) - WriteLine("// DEBUG: " + decl.DebugText); + { + char[] newLineChars = {'\r', '\n'}; + var text = decl.DebugText; + var index = text.IndexOfAny(newLineChars); + if (index >= 0) + text = text.Substring(0, index); + WriteLine("// DEBUG: " + text); + } } #endregion From 0b99682341b367cbdd87691f6c6c1c2998f09240 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sat, 9 Dec 2017 18:23:26 +0200 Subject: [PATCH 07/16] Consistent class/struct keywords fixed for cases where wrapper class would contain members from several different translation units. --- .../Generators/CSharp/CSharpSources.cs | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index e0334a1e..2538d7fb 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -203,6 +203,27 @@ namespace CppSharp.Generators.CSharp return true; } + private IEnumerable EnumerateClasses() + { + foreach (var tu in TranslationUnits) + { + foreach (var cls in EnumerateClasses(tu)) + yield return cls; + } + } + + private IEnumerable EnumerateClasses(DeclarationContext context) + { + foreach (var cls in context.Classes) + yield return cls; + + foreach (var ns in context.Namespaces) + { + foreach (var cls in EnumerateClasses(ns)) + yield return cls; + } + } + void GenerateNamespaceFunctionsAndVariables(DeclarationContext context) { var hasGlobalVariables = !(context is Class) && context.Variables.Any( @@ -213,8 +234,11 @@ namespace CppSharp.Generators.CSharp PushBlock(BlockKind.Functions); var parentName = SafeIdentifier(context.TranslationUnit.FileNameWithoutExtension); - var @class = context.Classes.Find(c => c.Name == parentName); - var keyword = @class != null && @class.IsValueType ? "struct" : "class"; + + var keyword = "class"; + var classes = EnumerateClasses().ToList(); + if (classes.FindAll(cls => cls.IsValueType && cls.Name == parentName && context.QualifiedLogicalName == cls.Namespace.QualifiedLogicalName).Any()) + keyword = "struct"; WriteLine($"public unsafe partial {keyword} {parentName}"); WriteStartBraceIndent(); From 4e735b5b61f7191e2140e39012d5ee517f314574 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sat, 9 Dec 2017 18:25:19 +0200 Subject: [PATCH 08/16] Test for consistent struct/class keywords. Tests for cases where class name matches translation unit name. Tests for cases where global constants/functions from different translation units would end up in the value type. --- tests/CSharp/CSharp.cs | 1 + tests/CSharp/CSharp.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/tests/CSharp/CSharp.cs b/tests/CSharp/CSharp.cs index 57dfa50d..c18e56ed 100644 --- a/tests/CSharp/CSharp.cs +++ b/tests/CSharp/CSharp.cs @@ -36,6 +36,7 @@ namespace CppSharp.Tests ctx.SetClassAsValueType("QPoint"); ctx.SetClassAsValueType("QSize"); ctx.SetClassAsValueType("QRect"); + ctx.SetClassAsValueType("CSharp"); ctx.SetClassAsValueType("StructTestArrayTypeFromTypedef"); ctx.IgnoreClassWithName("IgnoredTypeInheritingNonIgnoredWithNoEmptyCtor"); ctx.IgnoreClassWithName("Ignored"); diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 37756251..ac3d962c 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -1266,3 +1266,9 @@ public: ~HasFixedArrayOfPointers(); Foo* fixedArrayOfPointers[3]; }; + +struct DLL_API CSharp +{ +}; + +static int FOOBAR_CONSTANT = 42; From aa33609d450117d50338637631f1f04a649d2bd9 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sat, 9 Dec 2017 19:53:38 +0200 Subject: [PATCH 09/16] Clean up linux includes setup. Includes setup was moved to ParserOptions.cs and is used just like `SetupMSVC()` and `SetupXcode()`. Native compiler is queried for it's type and version. Correct include paths are set up in cases where system has multiple compilers installed as well. --- src/CLI/Generator.cs | 31 ++-------------- src/CppParser/ParserGen/ParserGen.cs | 29 +-------------- src/Parser/ParserOptions.cs | 55 +++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 56 deletions(-) diff --git a/src/CLI/Generator.cs b/src/CLI/Generator.cs index af07d7cb..dff7de51 100644 --- a/src/CLI/Generator.cs +++ b/src/CLI/Generator.cs @@ -4,9 +4,11 @@ using CppSharp.Parser; using CppSharp.Passes; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using CppAbi = CppSharp.Parser.AST.CppAbi; namespace CppSharp @@ -193,34 +195,7 @@ namespace CppSharp private void SetupLinuxOptions(ParserOptions parserOptions) { - parserOptions.MicrosoftMode = false; - parserOptions.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", "lib", "gcc", "x86_64-pc-linux-gnu", gccVersion, "include"), - Path.Combine("usr", "include", "x86_64-linux-gnu"), - Path.Combine("usr", "include", "x86_64-pc-linux-gnu"), - Path.Combine("usr", "include") - }; - - foreach (var dir in systemIncludeDirs) - parserOptions.AddSystemIncludeDirs(Path.Combine(headersPath, dir)); - + parserOptions.SetupLinux(); parserOptions.AddDefines("_GLIBCXX_USE_CXX11_ABI=" + (options.Cpp11ABI ? "1" : "0")); } diff --git a/src/CppParser/ParserGen/ParserGen.cs b/src/CppParser/ParserGen/ParserGen.cs index 2b16cba8..8a2f6cfd 100644 --- a/src/CppParser/ParserGen/ParserGen.cs +++ b/src/CppParser/ParserGen/ParserGen.cs @@ -98,32 +98,7 @@ namespace CppSharp var headersPath = Platform.IsLinux ? string.Empty : Path.Combine(GetSourceDirectory("build"), "headers", "x86_64-linux-gnu"); - - // 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", "lib", "gcc", "x86_64-pc-linux-gnu", gccVersion, "include"), - Path.Combine("usr", "include", "x86_64-linux-gnu"), - Path.Combine("usr", "include", "x86_64-pc-linux-gnu"), - Path.Combine("usr", "include") - }; - - foreach (var dir in systemIncludeDirs) - options.AddSystemIncludeDirs(Path.Combine(headersPath, dir)); - + options.SetupLinux(headersPath); options.AddDefines("_GLIBCXX_USE_CXX11_ABI=" + (IsGnuCpp11Abi ? "1" : "0")); } @@ -237,4 +212,4 @@ namespace CppSharp } } } -} \ No newline at end of file +} diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs index fb0110cb..7b500225 100644 --- a/src/Parser/ParserOptions.cs +++ b/src/Parser/ParserOptions.cs @@ -1,9 +1,12 @@ -using CppSharp.Parser.AST; +using System; +using CppSharp.Parser.AST; using System.Reflection; using LanguageVersion = CppSharp.Parser.LanguageVersion; using System.Globalization; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; +using System.Text.RegularExpressions; namespace CppSharp.Parser { @@ -218,6 +221,53 @@ namespace CppSharp.Parser AddArguments("-stdlib=libc++"); } + private void GetUnixCompilerInfo(out string compiler, out string version) + { + var info = new ProcessStartInfo(Environment.GetEnvironmentVariable("CXX") ?? "gcc", "-v"); + info.RedirectStandardError = true; + info.CreateNoWindow = true; + info.UseShellExecute = false; + var process = Process.Start(info); + if (process == null) + throw new SystemException("GCC compiler was not found."); + process.WaitForExit(); + + var output = process.StandardError.ReadToEnd(); + var match = Regex.Match(output, "(gcc|clang) version ([0-9\\.]+)"); + if (!match.Success) + throw new SystemException("GCC compiler was not found."); + + compiler = match.Groups[1].ToString(); + version = match.Groups[2].ToString(); + } + + public void SetupLinux(string headersPath="") + { + MicrosoftMode = false; + NoBuiltinIncludes = true; + NoStandardIncludes = true; + Abi = CppAbi.Itanium; + + string compiler, version; + GetUnixCompilerInfo(out compiler, out version); + Console.WriteLine($"Compiler version: {compiler}/{version}"); + AddSystemIncludeDirs($"{headersPath}/usr/include"); + if (compiler == "gcc") + { + AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}"); + AddSystemIncludeDirs($"{headersPath}/usr/include/x86_64-linux-gnu/c++/{version}"); + AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/backward"); + } + string[] tripples = {"x86_64-linux-gnu", "x86_64-pc-linux-gnu"}; + foreach (var tripple in tripples) + { + AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include"); + AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include/c++"); + AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include/c++/{tripple}"); + AddSystemIncludeDirs($"{headersPath}/usr/include/{tripple}"); + } + } + public void Setup() { SetupArguments(); @@ -291,6 +341,9 @@ namespace CppSharp.Parser case TargetPlatform.MacOS: SetupXcode(); break; + case TargetPlatform.Linux: + SetupLinux(); + break; } } } From 7a3adcd401af556c1725d506693c2beb9c164e6a Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sat, 9 Dec 2017 21:03:11 +0200 Subject: [PATCH 10/16] Some linux distributions use `major.minor.patch` and some use `major.minor` for versioning include dirs. Add them all. --- src/Parser/ParserOptions.cs | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs index 7b500225..c05bb0c1 100644 --- a/src/Parser/ParserOptions.cs +++ b/src/Parser/ParserOptions.cs @@ -221,7 +221,7 @@ namespace CppSharp.Parser AddArguments("-stdlib=libc++"); } - private void GetUnixCompilerInfo(out string compiler, out string version) + private void GetUnixCompilerInfo(out string compiler, out string longVersion, out string shortVersion) { var info = new ProcessStartInfo(Environment.GetEnvironmentVariable("CXX") ?? "gcc", "-v"); info.RedirectStandardError = true; @@ -233,12 +233,13 @@ namespace CppSharp.Parser process.WaitForExit(); var output = process.StandardError.ReadToEnd(); - var match = Regex.Match(output, "(gcc|clang) version ([0-9\\.]+)"); + var match = Regex.Match(output, "(gcc|clang) version (([0-9]+\\.[0-9]+)\\.[0-9]+)"); if (!match.Success) throw new SystemException("GCC compiler was not found."); compiler = match.Groups[1].ToString(); - version = match.Groups[2].ToString(); + longVersion = match.Groups[2].ToString(); + shortVersion = match.Groups[3].ToString(); } public void SetupLinux(string headersPath="") @@ -248,22 +249,28 @@ namespace CppSharp.Parser NoStandardIncludes = true; Abi = CppAbi.Itanium; - string compiler, version; - GetUnixCompilerInfo(out compiler, out version); - Console.WriteLine($"Compiler version: {compiler}/{version}"); + string compiler, longVersion, shortVersion; + GetUnixCompilerInfo(out compiler, out longVersion, out shortVersion); + string[] versions = {longVersion, shortVersion}; AddSystemIncludeDirs($"{headersPath}/usr/include"); if (compiler == "gcc") { - AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}"); - AddSystemIncludeDirs($"{headersPath}/usr/include/x86_64-linux-gnu/c++/{version}"); - AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/backward"); + foreach (var version in versions) + { + AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}"); + AddSystemIncludeDirs($"{headersPath}/usr/include/x86_64-linux-gnu/c++/{version}"); + AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/backward"); + } } string[] tripples = {"x86_64-linux-gnu", "x86_64-pc-linux-gnu"}; foreach (var tripple in tripples) { - AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include"); - AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include/c++"); - AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include/c++/{tripple}"); + foreach (var version in versions) + { + AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include"); + AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include/c++"); + AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{tripple}/{version}/include/c++/{tripple}"); + } AddSystemIncludeDirs($"{headersPath}/usr/include/{tripple}"); } } From 86f2c59ec550f3ded142881e24a0fbfbeec2a6b8 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sun, 10 Dec 2017 14:47:59 +0200 Subject: [PATCH 11/16] Tweak linux include dirs, previous change broke GCC7 include dirs on archlinux. --- src/Parser/ParserOptions.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs index c05bb0c1..1d82fc42 100644 --- a/src/Parser/ParserOptions.cs +++ b/src/Parser/ParserOptions.cs @@ -252,17 +252,17 @@ namespace CppSharp.Parser string compiler, longVersion, shortVersion; GetUnixCompilerInfo(out compiler, out longVersion, out shortVersion); string[] versions = {longVersion, shortVersion}; - AddSystemIncludeDirs($"{headersPath}/usr/include"); + string[] tripples = {"x86_64-linux-gnu", "x86_64-pc-linux-gnu"}; if (compiler == "gcc") { foreach (var version in versions) { AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}"); - AddSystemIncludeDirs($"{headersPath}/usr/include/x86_64-linux-gnu/c++/{version}"); AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/backward"); + foreach (var tripple in tripples) + AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/{tripple}"); } } - string[] tripples = {"x86_64-linux-gnu", "x86_64-pc-linux-gnu"}; foreach (var tripple in tripples) { foreach (var version in versions) @@ -273,6 +273,7 @@ namespace CppSharp.Parser } AddSystemIncludeDirs($"{headersPath}/usr/include/{tripple}"); } + AddSystemIncludeDirs($"{headersPath}/usr/include"); } public void Setup() From e5bc151c784da942e03af91799b325d93a335a6d Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sun, 10 Dec 2017 14:50:22 +0200 Subject: [PATCH 12/16] All arguments passed to `build/Compile.sh` are passed to premake. Allows more fine-grained build customization when using this shellscript for compiling. --- build/Compile.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Compile.sh b/build/Compile.sh index d709ee5f..c5699971 100755 --- a/build/Compile.sh +++ b/build/Compile.sh @@ -16,7 +16,7 @@ else BUILD_CONF=release_x86; fi -$PREMAKE --file=$CUR_DIR/premake5.lua gmake +$PREMAKE --file=$CUR_DIR/premake5.lua gmake "$@" config=$BUILD_CONF make -C $CUR_DIR/gmake/ BUILD_CONF_DIR="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_CONF:0:1})${BUILD_CONF:1}" From 5a190bfb1b4d8cbe42433a510f9cd683e1342838 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sun, 10 Dec 2017 14:55:38 +0200 Subject: [PATCH 13/16] Explicitly link to libstdc++ on linux. In some environments using secondary installed compiler version does not link to libstdc++ automatically, which results in `DllNotFoundException`. --- build/Helpers.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/Helpers.lua b/build/Helpers.lua index d80e0649..fd8d3ccb 100644 --- a/build/Helpers.lua +++ b/build/Helpers.lua @@ -84,8 +84,9 @@ function SetupNativeProject() buildoptions { msvc_buildflags } defines { msvc_cpp_defines } - filter { "action:gmake" } + filter { "system:linux" } buildoptions { gcc_buildflags } + links { "stdc++" } filter { "system:macosx", "language:C++" } buildoptions { gcc_buildflags, "-stdlib=libc++" } From 9ea1821cb3d95dea60b1771c82125f7a1618a8e3 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sun, 10 Dec 2017 15:22:20 +0200 Subject: [PATCH 14/16] Fix debug output not being generated when AST element had no comment. Also debug text cleaning moved to CodeGenerator.cs and is done when printing bindings. New lines are not stripped out, instead each line is prepended with "// DEBUG: ". Now debug info is properly formatted, easy to read and full. --- src/Generator/Generators/CodeGenerator.cs | 14 +++++--------- src/Generator/Passes/CleanInvalidDeclNamesPass.cs | 1 - src/Generator/Utils/Utils.cs | 14 -------------- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/src/Generator/Generators/CodeGenerator.cs b/src/Generator/Generators/CodeGenerator.cs index d102055f..61d5cd17 100644 --- a/src/Generator/Generators/CodeGenerator.cs +++ b/src/Generator/Generators/CodeGenerator.cs @@ -83,22 +83,18 @@ namespace CppSharp.Generators public virtual void GenerateDeclarationCommon(Declaration decl) { if (decl.Comment != null) - { GenerateComment(decl.Comment); - GenerateDebug(decl); - } + + GenerateDebug(decl); } public virtual void GenerateDebug(Declaration decl) { if (Options.GenerateDebugOutput && !string.IsNullOrWhiteSpace(decl.DebugText)) { - char[] newLineChars = {'\r', '\n'}; - var text = decl.DebugText; - var index = text.IndexOfAny(newLineChars); - if (index >= 0) - text = text.Substring(0, index); - WriteLine("// DEBUG: " + text); + var debugText = decl.DebugText; + debugText = Regex.Replace(debugText.Trim(), "\r?\n", "\n// DEBUG: "); + WriteLine($"// DEBUG: {debugText}"); } } diff --git a/src/Generator/Passes/CleanInvalidDeclNamesPass.cs b/src/Generator/Passes/CleanInvalidDeclNamesPass.cs index 52462e7f..9851e3c3 100644 --- a/src/Generator/Passes/CleanInvalidDeclNamesPass.cs +++ b/src/Generator/Passes/CleanInvalidDeclNamesPass.cs @@ -53,7 +53,6 @@ namespace CppSharp.Passes (method == null || method.Kind == CXXMethodKind.Normal)) decl.Name = CheckName(decl.Name); - StringHelpers.CleanupText(ref decl.DebugText); return true; } diff --git a/src/Generator/Utils/Utils.cs b/src/Generator/Utils/Utils.cs index c555e2d9..b8f8ed17 100644 --- a/src/Generator/Utils/Utils.cs +++ b/src/Generator/Utils/Utils.cs @@ -43,20 +43,6 @@ namespace CppSharp return ss[0]; // all strings identical } - public static void CleanupText(ref string debugText) - { - // Strip off newlines from the debug text. - if (string.IsNullOrWhiteSpace(debugText)) - { - debugText = string.Empty; - return; - } - - // TODO: Make this transformation in the output. - debugText = Regex.Replace(debugText, " {2,}", " "); - debugText = debugText.Replace("\n", ""); - } - public static string[] SplitCamelCase(string input) { var str = Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled); From 944c9f4f7f30d733160283265ef575dd765aa770 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sun, 10 Dec 2017 15:22:33 +0200 Subject: [PATCH 15/16] Enable debug information generation for all tests. --- src/Generator.Tests/GeneratorTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Generator.Tests/GeneratorTest.cs b/src/Generator.Tests/GeneratorTest.cs index d77bc7ae..f882178f 100644 --- a/src/Generator.Tests/GeneratorTest.cs +++ b/src/Generator.Tests/GeneratorTest.cs @@ -28,6 +28,7 @@ namespace CppSharp.Utils options.GeneratorKind = kind; options.OutputDir = Path.Combine(GetOutputDirectory(), "gen", name); options.Quiet = true; + options.GenerateDebugOutput = true; var testModule = options.AddModule(name); testModule.SharedLibraryName = $"{name}.Native"; From b90fb525251183f78a128de48d6a5061f52745ce Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Sun, 10 Dec 2017 15:36:37 +0200 Subject: [PATCH 16/16] Re-added linux include path that was removed by mistake. --- src/Parser/ParserOptions.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs index 1d82fc42..ad169ec1 100644 --- a/src/Parser/ParserOptions.cs +++ b/src/Parser/ParserOptions.cs @@ -260,7 +260,10 @@ namespace CppSharp.Parser AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}"); AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/backward"); foreach (var tripple in tripples) + { + AddSystemIncludeDirs($"{headersPath}/usr/include/{tripple}/c++/{version}"); AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/{tripple}"); + } } } foreach (var tripple in tripples)