diff --git a/source/MetadataProcessor.Core/MetadataProcessor.Core.csproj b/source/MetadataProcessor.Core/MetadataProcessor.Core.csproj
index fc052c9a..3d0591a8 100644
--- a/source/MetadataProcessor.Core/MetadataProcessor.Core.csproj
+++ b/source/MetadataProcessor.Core/MetadataProcessor.Core.csproj
@@ -90,6 +90,7 @@
+
diff --git a/source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClassStubs.cs b/source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClassStubs.cs
index a4e89e6b..2666227b 100644
--- a/source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClassStubs.cs
+++ b/source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClassStubs.cs
@@ -21,6 +21,8 @@ public class AssemblyClassStubs
public string ProjectName;
+ public string AssemblyName;
+
public List Functions = new List();
}
}
diff --git a/source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClassTable.cs b/source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClassTable.cs
new file mode 100644
index 00000000..483edd34
--- /dev/null
+++ b/source/MetadataProcessor.Core/SkeletonGenerator/AssemblyClassTable.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) 2019 The nanoFramework project contributors
+// See LICENSE file in the project root for full license information.
+//
+
+using System.Collections.Generic;
+
+namespace nanoFramework.Tools.MetadataProcessor.Core
+{
+ public class AssemblyClassTable
+ {
+ public string AssemblyName;
+ public string HeaderFileName;
+ public string ProjectName;
+
+ public List Classes = new List();
+ }
+}
diff --git a/source/MetadataProcessor.Core/SkeletonGenerator/SkeletonTemplates.cs b/source/MetadataProcessor.Core/SkeletonGenerator/SkeletonTemplates.cs
index 8a6172af..da36581d 100644
--- a/source/MetadataProcessor.Core/SkeletonGenerator/SkeletonTemplates.cs
+++ b/source/MetadataProcessor.Core/SkeletonGenerator/SkeletonTemplates.cs
@@ -235,5 +235,56 @@ struct {{ClassName}}
NANOCLR_NOCLEANUP();
}
{{/each}}";
+
+ internal const string CMakeModuleTemplate =
+@"#
+# Copyright(c) 2018 The nanoFramework project contributors
+# See LICENSE file in the project root for full license information.
+#
+
+#################################################################################################
+# make sure that a valid path is set bellow #
+# if this is for a class library it's OK to leave it as it is #
+# if this is an Interop module the path has to be set where the build can find the source files #
+#################################################################################################
+
+# native code directory
+set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/{{AssemblyName}})
+
+
+# set include directories
+list(APPEND {{AssemblyName}}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core)
+list(APPEND {{AssemblyName}}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include)
+list(APPEND {{AssemblyName}}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include)
+list(APPEND {{AssemblyName}}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include)
+list(APPEND {{AssemblyName}}_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE})
+
+# source files
+set({{AssemblyName}}_SRCS
+ {{HeaderFileName}}.cpp
+{{#each Classes}}
+ {{HeaderFileName}}_{{Name}}_mshl.cpp
+ {{HeaderFileName}}_{{Name}}.cpp{{/each}}
+
+)
+
+foreach(SRC_FILE ${{{AssemblyName}}_SRCS})
+
+ set({{AssemblyName}}_SRC_FILE SRC_FILE-NOTFOUND)
+ find_file({{AssemblyName}}_SRC_FILE ${ SRC_FILE}
+ PATHS
+ ""${BASE_PATH_FOR_THIS_MODULE}""
+ ""${TARGET_BASE_LOCATION}""
+
+ CMAKE_FIND_ROOT_PATH_BOTH
+ )
+# message(""${SRC_FILE} >> ${{{AssemblyName}}_SRC_FILE}"") # debug helper
+list(APPEND {{AssemblyName}}_SOURCES ${{{AssemblyName}}_SRC_FILE})
+endforeach()
+
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS({{AssemblyName}} DEFAULT_MSG {{AssemblyName}}_INCLUDE_DIRS {{AssemblyName}}_SOURCES)
+";
}
}
diff --git a/source/MetadataProcessor.Core/nanoSkeletonGenerator.cs b/source/MetadataProcessor.Core/nanoSkeletonGenerator.cs
index ef02542c..75b04466 100644
--- a/source/MetadataProcessor.Core/nanoSkeletonGenerator.cs
+++ b/source/MetadataProcessor.Core/nanoSkeletonGenerator.cs
@@ -24,7 +24,9 @@ public sealed class nanoSkeletonGenerator
private readonly string _project;
private readonly bool _withoutInteropCode;
private readonly bool _isCoreLib;
- private string _assemblyName;
+ private readonly string _assemblyName;
+
+ private string _safeProjectName => _project.Replace('.', '_');
public nanoSkeletonGenerator(
nanoTablesContext tablesContext,
@@ -40,13 +42,13 @@ public nanoSkeletonGenerator(
_project = project;
_withoutInteropCode = withoutInteropCode;
_isCoreLib = isCoreLib;
- }
- public void GenerateSkeleton()
- {
// replaces "." with "_" so the assembly name can be part of C++ identifier name
_assemblyName = _name.Replace('.', '_');
+ }
+ public void GenerateSkeleton()
+ {
// create .h with the structs declarations
GenerateAssemblyHeader();
@@ -59,6 +61,12 @@ public void GenerateSkeleton()
private void GenerateStubs()
{
+ var classList = new AssemblyClassTable
+ {
+ AssemblyName = _tablesContext.AssemblyDefinition.Name.Name,
+ ProjectName = _safeProjectName
+ };
+
foreach (var c in _tablesContext.TypeDefinitionTable.TypeDefinitions)
{
if (c.IncludeInStub() &&
@@ -66,31 +74,35 @@ private void GenerateStubs()
{
var className = NativeMethodsCrc.GetClassName(c);
- var classStubs = new AssemblyClassStubs();
+ var classStubs = new AssemblyClassStubs
+ {
+ AssemblyName = _name,
+ ClassHeaderFileName = className,
+ ClassName = c.Name,
+ ShortNameUpper = $"{_assemblyName}_{_safeProjectName}_{className}".ToUpper(),
+ RootNamespace = _assemblyName,
+ ProjectName = _safeProjectName
+ };
if (!_withoutInteropCode)
{
// Interop code needs to use the root namespace
- classStubs.HeaderFileName = $"{_assemblyName}_{_project}";
- classStubs.ClassHeaderFileName = className;
- classStubs.ClassName = c.Name;
- classStubs.ShortNameUpper = $"{_assemblyName}_{_project}_{className}".ToUpper();
- classStubs.RootNamespace = _assemblyName;
- classStubs.ProjectName = _project;
+ classStubs.HeaderFileName = $"{_assemblyName}_{_safeProjectName}";
}
else
{
// projects with Interop can use a simplified naming
- classStubs.HeaderFileName = _project;
- classStubs.ClassHeaderFileName = className;
- classStubs.ClassName = c.Name;
- classStubs.ShortNameUpper = $"{_assemblyName}_{_project}_{className}".ToUpper();
- classStubs.RootNamespace = _assemblyName;
- classStubs.ProjectName = _project;
+ classStubs.HeaderFileName = _safeProjectName;
}
+ classList.Classes.Add(new Class()
+ {
+ Name = className
+ });
+ classList.HeaderFileName = classStubs.HeaderFileName;
+
foreach (var m in nanoTablesContext.GetOrderedMethods(c.Methods))
{
var rva = _tablesContext.ByteCodeTable.GetMethodRva(m);
@@ -101,7 +113,7 @@ private void GenerateStubs()
{
var newMethod = new MethodStub()
{
- Declaration = $"Library_{_project}_{className}::{NativeMethodsCrc.GetMethodName(m)}"
+ Declaration = $"Library_{_safeProjectName}_{className}::{NativeMethodsCrc.GetMethodName(m)}"
};
if(!_withoutInteropCode)
@@ -213,7 +225,7 @@ private void GenerateStubs()
};
Generator generator = compiler.Compile(SkeletonTemplates.ClassWithoutInteropStubTemplate);
- using (var headerFile = File.CreateText(Path.Combine(_path, $"{_project}_{className}.cpp")))
+ using (var headerFile = File.CreateText(Path.Combine(_path, $"{_safeProjectName}_{className}.cpp")))
{
var output = generator.Render(classStubs);
headerFile.Write(output);
@@ -229,7 +241,7 @@ private void GenerateStubs()
// user code stub
Generator generator = compiler.Compile(SkeletonTemplates.ClassStubTemplate);
- using (var headerFile = File.CreateText(Path.Combine(_path, $"{_assemblyName}_{_project}_{className}.cpp")))
+ using (var headerFile = File.CreateText(Path.Combine(_path, $"{_assemblyName}_{_safeProjectName}_{className}.cpp")))
{
var output = generator.Render(classStubs);
headerFile.Write(output);
@@ -238,7 +250,7 @@ private void GenerateStubs()
// marshal code
generator = compiler.Compile(SkeletonTemplates.ClassMarshallingCodeTemplate);
- using (var headerFile = File.CreateText(Path.Combine(_path, $"{_assemblyName}_{_project}_{className}_mrsh.cpp")))
+ using (var headerFile = File.CreateText(Path.Combine(_path, $"{_assemblyName}_{_safeProjectName}_{className}_mshl.cpp")))
{
var output = generator.Render(classStubs);
headerFile.Write(output);
@@ -247,7 +259,7 @@ private void GenerateStubs()
// class header
generator = compiler.Compile(SkeletonTemplates.ClassHeaderTemplate);
- using (var headerFile = File.CreateText(Path.Combine(_path, $"{_assemblyName}_{_project}_{className}.h")))
+ using (var headerFile = File.CreateText(Path.Combine(_path, $"{_assemblyName}_{_safeProjectName}_{className}.h")))
{
var output = generator.Render(classStubs);
headerFile.Write(output);
@@ -256,6 +268,25 @@ private void GenerateStubs()
}
}
}
+
+ if (!_withoutInteropCode &&
+ classList.Classes.Count > 0)
+ {
+ FormatCompiler compiler = new FormatCompiler
+ {
+ RemoveNewLines = false
+ };
+
+ // CMake module
+ Generator generator = compiler.Compile(SkeletonTemplates.CMakeModuleTemplate);
+
+ // FindINTEROP-NF.AwesomeLib
+ using (var headerFile = File.CreateText(Path.Combine(_path, $"FindINTEROP-{_safeProjectName}.cmake")))
+ {
+ var output = generator.Render(classList);
+ headerFile.Write(output);
+ }
+ }
}
private void GenerateAssemblyLookup()
@@ -269,7 +300,7 @@ private void GenerateAssemblyLookup()
IsCoreLib = _isCoreLib,
Name = _name,
AssemblyName = _assemblyName,
- HeaderFileName = _project,
+ HeaderFileName = _safeProjectName,
NativeVersion = nativeVersion,
NativeCRC32 = "0x" + _tablesContext.NativeMethodsCrc.Current.ToString("X")
};
@@ -298,7 +329,7 @@ private void GenerateAssemblyLookup()
{
assemblyLookup.LookupTable.Add(new MethodStub()
{
- Declaration = $"Library_{_project}_{className}::{NativeMethodsCrc.GetMethodName(m)}"
+ Declaration = $"Library_{_safeProjectName}_{className}::{NativeMethodsCrc.GetMethodName(m)}"
});
}
else
@@ -312,7 +343,7 @@ private void GenerateAssemblyLookup()
assemblyLookup.LookupTable.Add(new MethodStub()
{
Declaration = "NULL"
- //Declaration = $"**Library_{_project}_{NativeMethodsCrc.GetClassName(c)}::{NativeMethodsCrc.GetMethodName(m)}"
+ //Declaration = $"**Library_{_safeProjectName}_{NativeMethodsCrc.GetClassName(c)}::{NativeMethodsCrc.GetMethodName(m)}"
});
}
}
@@ -332,7 +363,7 @@ private void GenerateAssemblyLookup()
assemblyLookup.LookupTable.Add(new MethodStub()
{
Declaration = "NULL"
- //Declaration = $"**Library_{_project}_{NativeMethodsCrc.GetClassName(c)}::{NativeMethodsCrc.GetMethodName(m)}"
+ //Declaration = $"**Library_{_safeProjectName}_{NativeMethodsCrc.GetClassName(c)}::{NativeMethodsCrc.GetMethodName(m)}"
});
}
}
@@ -347,12 +378,12 @@ private void GenerateAssemblyLookup()
if (!_withoutInteropCode)
{
// Interop code needs to use the root namespace
- filePath = Path.Combine(_path, $"{_assemblyName}_{_project}.cpp");
+ filePath = Path.Combine(_path, $"{_assemblyName}_{_safeProjectName}.cpp");
}
else
{
// projects with Interop can use a simplified naming
- filePath = Path.Combine(_path, $"{_project}.cpp");
+ filePath = Path.Combine(_path, $"{_safeProjectName}.cpp");
}
using (var headerFile = File.CreateText(filePath))
@@ -368,9 +399,9 @@ private void GenerateAssemblyHeader()
var assemblyData = new AssemblyDeclaration()
{
- Name = _name.Replace('.', '_'),
- ShortName = _project,
- ShortNameUpper = _project.ToUpperInvariant(),
+ Name = _assemblyName,
+ ShortName = _safeProjectName,
+ ShortNameUpper = _safeProjectName.ToUpperInvariant(),
IsCoreLib = _isCoreLib
};
@@ -381,7 +412,7 @@ private void GenerateAssemblyHeader()
{
var classData = new Class()
{
- AssemblyName = _project,
+ AssemblyName = _safeProjectName,
Name = NativeMethodsCrc.GetClassName(c)
};
@@ -480,12 +511,12 @@ private void GenerateAssemblyHeader()
if (!_withoutInteropCode)
{
// Interop code needs to use the root namespace
- filePath = Path.Combine(_path, $"{_assemblyName}_{_project}.h");
+ filePath = Path.Combine(_path, $"{_assemblyName}_{_safeProjectName}.h");
}
else
{
// projects with Interop can use a simplified naming
- filePath = Path.Combine(_path, $"{_project}.h");
+ filePath = Path.Combine(_path, $"{_safeProjectName}.h");
}
using (var headerFile = File.CreateText(filePath))