Mono/C#: Re-structure API solution and GodotTools post-build target
Previously we had a placeholder solution called 'Managed' to benefit from tooling while editing the a part of the C# API. Later the bindings generator would create the final 'GodotSharp' solution including these C# files as well as the auto-generated C# API. Now we replaced the 'Managed' solution with the final 'GodotSharp' solution which is no longer auto-generated, and the bindings generator only takes care of the auto-generated C# API. This has the following benefits: - It's less confusing as there will no longer be two versions of the same file (the original and a generated copy of it). Now there's only one. - We no longer need placeholder for auto-generated API classes, like Node or Resource. We used them for benefiting from tooling. Now we can just use the auto-generated API itself. - Simplifies the build system and bindings generator. Removed lot of code that is not needed anymore. Also added a post-build target to the GodotTools project to copy the output to the data dir. This makes it easy to iterate when doing changes to GodotTools, as SCons doesn't have to be executed anymore just to copy these new files.
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace GodotTools.ProjectEditor
|
||||
{
|
||||
public static class ApiSolutionGenerator
|
||||
{
|
||||
public static void GenerateApiSolution(string solutionDir,
|
||||
string coreProjDir, IEnumerable<string> coreCompileItems,
|
||||
string editorProjDir, IEnumerable<string> editorCompileItems)
|
||||
{
|
||||
var solution = new DotNetSolution(ApiAssemblyNames.SolutionName);
|
||||
|
||||
solution.DirectoryPath = solutionDir;
|
||||
|
||||
// GodotSharp project
|
||||
|
||||
const string coreApiAssemblyName = ApiAssemblyNames.Core;
|
||||
|
||||
string coreGuid = ProjectGenerator.GenCoreApiProject(coreProjDir, coreCompileItems);
|
||||
|
||||
var coreProjInfo = new DotNetSolution.ProjectInfo
|
||||
{
|
||||
Guid = coreGuid,
|
||||
PathRelativeToSolution = Path.Combine(coreApiAssemblyName, $"{coreApiAssemblyName}.csproj")
|
||||
};
|
||||
coreProjInfo.Configs.Add("Debug");
|
||||
coreProjInfo.Configs.Add("Release");
|
||||
|
||||
solution.AddNewProject(coreApiAssemblyName, coreProjInfo);
|
||||
|
||||
// GodotSharpEditor project
|
||||
|
||||
const string editorApiAssemblyName = ApiAssemblyNames.Editor;
|
||||
|
||||
string editorGuid = ProjectGenerator.GenEditorApiProject(editorProjDir,
|
||||
$"../{coreApiAssemblyName}/{coreApiAssemblyName}.csproj", editorCompileItems);
|
||||
|
||||
var editorProjInfo = new DotNetSolution.ProjectInfo();
|
||||
editorProjInfo.Guid = editorGuid;
|
||||
editorProjInfo.PathRelativeToSolution = Path.Combine(editorApiAssemblyName, $"{editorApiAssemblyName}.csproj");
|
||||
editorProjInfo.Configs.Add("Debug");
|
||||
editorProjInfo.Configs.Add("Release");
|
||||
|
||||
solution.AddNewProject(editorApiAssemblyName, editorProjInfo);
|
||||
|
||||
// Save solution
|
||||
|
||||
solution.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-8
@@ -32,18 +32,11 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.Build" />
|
||||
<Reference Include="DotNet.Glob, Version=2.1.1.0, Culture=neutral, PublicKeyToken=b68cc888b4f632d1, processorArchitecture=MSIL">
|
||||
<!--
|
||||
When building Godot with 'mono_glue=no' SCons will build this project alone instead of the
|
||||
entire solution. $(SolutionDir) is not defined in that case, so we need to workaround that.
|
||||
We make SCons restore the NuGet packages in the project directory instead in this case.
|
||||
-->
|
||||
<HintPath Condition=" '$(SolutionDir)' != '' And Exists('$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll') ">$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath>
|
||||
<HintPath Condition=" '$(SolutionDir)' == '' Or !Exists('$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll') ">$(ProjectDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath>
|
||||
<HintPath>packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ApiAssembliesInfo.cs" />
|
||||
<Compile Include="ApiSolutionGenerator.cs" />
|
||||
<Compile Include="DotNetSolution.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="IdentifierUtils.cs" />
|
||||
|
||||
@@ -10,68 +10,13 @@ namespace GodotTools.ProjectEditor
|
||||
{
|
||||
private const string CoreApiProjectName = "GodotSharp";
|
||||
private const string EditorApiProjectName = "GodotSharpEditor";
|
||||
private const string CoreApiProjectGuid = "{AEBF0036-DA76-4341-B651-A3F2856AB2FA}";
|
||||
private const string EditorApiProjectGuid = "{8FBEC238-D944-4074-8548-B3B524305905}";
|
||||
|
||||
public static string GenCoreApiProject(string dir, IEnumerable<string> compileItems)
|
||||
{
|
||||
string path = Path.Combine(dir, CoreApiProjectName + ".csproj");
|
||||
|
||||
ProjectPropertyGroupElement mainGroup;
|
||||
var root = CreateLibraryProject(CoreApiProjectName, out mainGroup);
|
||||
|
||||
mainGroup.AddProperty("DocumentationFile", Path.Combine("$(OutputPath)", "$(AssemblyName).xml"));
|
||||
mainGroup.SetProperty("RootNamespace", "Godot");
|
||||
mainGroup.SetProperty("ProjectGuid", CoreApiProjectGuid);
|
||||
mainGroup.SetProperty("BaseIntermediateOutputPath", "obj");
|
||||
|
||||
GenAssemblyInfoFile(root, dir, CoreApiProjectName,
|
||||
new[] { "[assembly: InternalsVisibleTo(\"" + EditorApiProjectName + "\")]" },
|
||||
new[] { "System.Runtime.CompilerServices" });
|
||||
|
||||
foreach (var item in compileItems)
|
||||
{
|
||||
root.AddItem("Compile", item.RelativeToPath(dir).Replace("/", "\\"));
|
||||
}
|
||||
|
||||
root.Save(path);
|
||||
|
||||
return CoreApiProjectGuid;
|
||||
}
|
||||
|
||||
public static string GenEditorApiProject(string dir, string coreApiProjPath, IEnumerable<string> compileItems)
|
||||
{
|
||||
string path = Path.Combine(dir, EditorApiProjectName + ".csproj");
|
||||
|
||||
ProjectPropertyGroupElement mainGroup;
|
||||
var root = CreateLibraryProject(EditorApiProjectName, out mainGroup);
|
||||
|
||||
mainGroup.AddProperty("DocumentationFile", Path.Combine("$(OutputPath)", "$(AssemblyName).xml"));
|
||||
mainGroup.SetProperty("RootNamespace", "Godot");
|
||||
mainGroup.SetProperty("ProjectGuid", EditorApiProjectGuid);
|
||||
mainGroup.SetProperty("BaseIntermediateOutputPath", "obj");
|
||||
|
||||
GenAssemblyInfoFile(root, dir, EditorApiProjectName);
|
||||
|
||||
foreach (var item in compileItems)
|
||||
{
|
||||
root.AddItem("Compile", item.RelativeToPath(dir).Replace("/", "\\"));
|
||||
}
|
||||
|
||||
var coreApiRef = root.AddItem("ProjectReference", coreApiProjPath.Replace("/", "\\"));
|
||||
coreApiRef.AddMetadata("Private", "False");
|
||||
|
||||
root.Save(path);
|
||||
|
||||
return EditorApiProjectGuid;
|
||||
}
|
||||
|
||||
public static string GenGameProject(string dir, string name, IEnumerable<string> compileItems)
|
||||
{
|
||||
string path = Path.Combine(dir, name + ".csproj");
|
||||
|
||||
ProjectPropertyGroupElement mainGroup;
|
||||
var root = CreateLibraryProject(name, out mainGroup);
|
||||
var root = CreateLibraryProject(name, "Tools", out mainGroup);
|
||||
|
||||
mainGroup.SetProperty("OutputPath", Path.Combine(".mono", "temp", "bin", "$(Configuration)"));
|
||||
mainGroup.SetProperty("BaseIntermediateOutputPath", Path.Combine(".mono", "temp", "obj"));
|
||||
@@ -110,7 +55,7 @@ namespace GodotTools.ProjectEditor
|
||||
return root.GetGuid().ToString().ToUpper();
|
||||
}
|
||||
|
||||
public static void GenAssemblyInfoFile(ProjectRootElement root, string dir, string name, string[] assemblyLines = null, string[] usingDirectives = null)
|
||||
private static void GenAssemblyInfoFile(ProjectRootElement root, string dir, string name, string[] assemblyLines = null, string[] usingDirectives = null)
|
||||
{
|
||||
string propertiesDir = Path.Combine(dir, "Properties");
|
||||
if (!Directory.Exists(propertiesDir))
|
||||
@@ -138,7 +83,7 @@ namespace GodotTools.ProjectEditor
|
||||
root.AddItem("Compile", assemblyInfoFile.RelativeToPath(dir).Replace("/", "\\"));
|
||||
}
|
||||
|
||||
public static ProjectRootElement CreateLibraryProject(string name, out ProjectPropertyGroupElement mainGroup)
|
||||
public static ProjectRootElement CreateLibraryProject(string name, string defaultConfig, out ProjectPropertyGroupElement mainGroup)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ArgumentException($"{nameof(name)} cannot be empty", nameof(name));
|
||||
@@ -147,7 +92,7 @@ namespace GodotTools.ProjectEditor
|
||||
root.DefaultTargets = "Build";
|
||||
|
||||
mainGroup = root.AddPropertyGroup();
|
||||
mainGroup.AddProperty("Configuration", "Debug").Condition = " '$(Configuration)' == '' ";
|
||||
mainGroup.AddProperty("Configuration", defaultConfig).Condition = " '$(Configuration)' == '' ";
|
||||
mainGroup.AddProperty("Platform", "AnyCPU").Condition = " '$(Platform)' == '' ";
|
||||
mainGroup.AddProperty("ProjectGuid", "{" + Guid.NewGuid().ToString().ToUpper() + "}");
|
||||
mainGroup.AddProperty("OutputType", "Library");
|
||||
@@ -184,16 +129,6 @@ namespace GodotTools.ProjectEditor
|
||||
return root;
|
||||
}
|
||||
|
||||
private static void AddItems(ProjectRootElement elem, string groupName, params string[] items)
|
||||
{
|
||||
var group = elem.AddItemGroup();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
group.AddItem(groupName, item);
|
||||
}
|
||||
}
|
||||
|
||||
private const string AssemblyInfoTemplate =
|
||||
@"using System.Reflection;{0}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<AssemblyName>GodotTools</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath>
|
||||
<DataDirToolsOutputPath>$(GodotSourceRootPath)/bin/GodotSharp/Tools</DataDirToolsOutputPath>
|
||||
<GodotApiConfiguration>Debug</GodotApiConfiguration>
|
||||
<LangVersion>7</LangVersion>
|
||||
</PropertyGroup>
|
||||
@@ -41,9 +42,11 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="GodotSharp">
|
||||
<HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharp.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="GodotSharpEditor">
|
||||
<HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharpEditor.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -56,7 +59,6 @@
|
||||
<Compile Include="Ides\MonoDevelop\Instance.cs" />
|
||||
<Compile Include="Ides\Rider\RiderPathLocator.cs" />
|
||||
<Compile Include="Ides\Rider\RiderPathManager.cs" />
|
||||
<Compile Include="Internals\BindingsGenerator.cs" />
|
||||
<Compile Include="Internals\EditorProgress.cs" />
|
||||
<Compile Include="Internals\GodotSharpDirs.cs" />
|
||||
<Compile Include="Internals\Internal.cs" />
|
||||
@@ -99,5 +101,21 @@
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Target Name="CopyToDataDir" AfterTargets="Build">
|
||||
<ItemGroup>
|
||||
<GodotToolsCopy Include="$(OutputPath)\GodotTools*.dll" />
|
||||
<GodotToolsCopy Include="$(OutputPath)\Newtonsoft.Json.dll" />
|
||||
<GodotToolsCopy Include="$(OutputPath)\DotNet.Glob.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<GodotToolsCopy Include="$(OutputPath)\GodotTools*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(GodotToolsCopy)" DestinationFolder="$(DataDirToolsOutputPath)" ContinueOnError="false" />
|
||||
</Target>
|
||||
<Target Name="BuildAlwaysCopyToDataDir">
|
||||
<!-- Custom target run by SCons to make sure the CopyToDataDir target is always executed, without having to use DisableFastUpToDateCheck -->
|
||||
<CallTarget Targets="Build" />
|
||||
<CallTarget Targets="CopyToDataDir" />
|
||||
</Target>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GodotTools.Internals
|
||||
{
|
||||
public class BindingsGenerator : IDisposable
|
||||
{
|
||||
class BindingsGeneratorSafeHandle : SafeHandle
|
||||
{
|
||||
public BindingsGeneratorSafeHandle(IntPtr handle) : base(IntPtr.Zero, true)
|
||||
{
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
public override bool IsInvalid => handle == IntPtr.Zero;
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
internal_Dtor(handle);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private BindingsGeneratorSafeHandle safeHandle;
|
||||
private bool disposed = false;
|
||||
|
||||
public bool LogPrintEnabled
|
||||
{
|
||||
get => internal_LogPrintEnabled(GetPtr());
|
||||
set => internal_SetLogPrintEnabled(GetPtr(), value);
|
||||
}
|
||||
|
||||
public static uint Version => internal_Version();
|
||||
public static uint CsGlueVersion => internal_CsGlueVersion();
|
||||
|
||||
public Godot.Error GenerateCsApi(string outputDir) => internal_GenerateCsApi(GetPtr(), outputDir);
|
||||
|
||||
internal IntPtr GetPtr()
|
||||
{
|
||||
if (disposed)
|
||||
throw new ObjectDisposedException(GetType().FullName);
|
||||
|
||||
return safeHandle.DangerousGetHandle();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
if (safeHandle != null && !safeHandle.IsInvalid)
|
||||
{
|
||||
safeHandle.Dispose();
|
||||
safeHandle = null;
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
public BindingsGenerator()
|
||||
{
|
||||
safeHandle = new BindingsGeneratorSafeHandle(internal_Ctor());
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern IntPtr internal_Ctor();
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern void internal_Dtor(IntPtr handle);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern bool internal_LogPrintEnabled(IntPtr handle);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern void internal_SetLogPrintEnabled(IntPtr handle, bool enabled);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern Godot.Error internal_GenerateCsApi(IntPtr handle, string outputDir);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern uint internal_Version();
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern uint internal_CsGlueVersion();
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "core/os/os.h"
|
||||
#include "core/ucaps.h"
|
||||
|
||||
#include "../glue/cs_compressed.gen.h"
|
||||
#include "../glue/cs_glue_version.gen.h"
|
||||
#include "../godotsharp_defs.h"
|
||||
#include "../mono_gd/gd_mono_marshal.h"
|
||||
@@ -874,7 +873,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
|
||||
p_output.append("\n#pragma warning restore CS1591\n");
|
||||
}
|
||||
|
||||
Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vector<String> &r_compile_items) {
|
||||
Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
|
||||
|
||||
ERR_FAIL_COND_V(!initialized, ERR_UNCONFIGURED);
|
||||
|
||||
@@ -887,22 +886,24 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vect
|
||||
}
|
||||
|
||||
da->change_dir(p_proj_dir);
|
||||
da->make_dir("Core");
|
||||
da->make_dir("ObjectType");
|
||||
da->make_dir("Generated");
|
||||
da->make_dir("Generated/GodotObjects");
|
||||
|
||||
String core_dir = path::join(p_proj_dir, "Core");
|
||||
String obj_type_dir = path::join(p_proj_dir, "ObjectType");
|
||||
String base_gen_dir = path::join(p_proj_dir, "Generated");
|
||||
String godot_objects_gen_dir = path::join(base_gen_dir, "GodotObjects");
|
||||
|
||||
Vector<String> compile_items;
|
||||
|
||||
// Generate source file for global scope constants and enums
|
||||
{
|
||||
StringBuilder constants_source;
|
||||
_generate_global_constants(constants_source);
|
||||
String output_file = path::join(core_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_constants.cs");
|
||||
String output_file = path::join(base_gen_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_constants.cs");
|
||||
Error save_err = _save_file(output_file, constants_source);
|
||||
if (save_err != OK)
|
||||
return save_err;
|
||||
|
||||
r_compile_items.push_back(output_file);
|
||||
compile_items.push_back(output_file);
|
||||
}
|
||||
|
||||
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) {
|
||||
@@ -911,7 +912,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vect
|
||||
if (itype.api_type == ClassDB::API_EDITOR)
|
||||
continue;
|
||||
|
||||
String output_file = path::join(obj_type_dir, itype.proxy_name + ".cs");
|
||||
String output_file = path::join(godot_objects_gen_dir, itype.proxy_name + ".cs");
|
||||
Error err = _generate_cs_type(itype, output_file);
|
||||
|
||||
if (err == ERR_SKIP)
|
||||
@@ -920,39 +921,11 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vect
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
r_compile_items.push_back(output_file);
|
||||
compile_items.push_back(output_file);
|
||||
}
|
||||
|
||||
// Generate sources from compressed files
|
||||
|
||||
Map<String, GodotCsCompressedFile> compressed_files;
|
||||
get_compressed_files(compressed_files);
|
||||
|
||||
for (Map<String, GodotCsCompressedFile>::Element *E = compressed_files.front(); E; E = E->next()) {
|
||||
const String &file_name = E->key();
|
||||
const GodotCsCompressedFile &file_data = E->value();
|
||||
|
||||
String output_file = path::join(core_dir, file_name);
|
||||
|
||||
Vector<uint8_t> data;
|
||||
data.resize(file_data.uncompressed_size);
|
||||
Compression::decompress(data.ptrw(), file_data.uncompressed_size, file_data.data, file_data.compressed_size, Compression::MODE_DEFLATE);
|
||||
|
||||
String output_dir = output_file.get_base_dir();
|
||||
|
||||
if (!DirAccess::exists(output_dir)) {
|
||||
Error err = da->make_dir_recursive(ProjectSettings::get_singleton()->globalize_path(output_dir));
|
||||
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
|
||||
}
|
||||
|
||||
FileAccessRef file = FileAccess::open(output_file, FileAccess::WRITE);
|
||||
ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
|
||||
file->store_buffer(data.ptr(), data.size());
|
||||
file->close();
|
||||
|
||||
r_compile_items.push_back(output_file);
|
||||
}
|
||||
|
||||
StringBuilder cs_icalls_content;
|
||||
|
||||
cs_icalls_content.append("using System;\n"
|
||||
@@ -986,18 +959,36 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vect
|
||||
|
||||
cs_icalls_content.append(INDENT1 CLOSE_BLOCK CLOSE_BLOCK);
|
||||
|
||||
String internal_methods_file = path::join(core_dir, BINDINGS_CLASS_NATIVECALLS ".cs");
|
||||
String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS ".cs");
|
||||
|
||||
Error err = _save_file(internal_methods_file, cs_icalls_content);
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
r_compile_items.push_back(internal_methods_file);
|
||||
compile_items.push_back(internal_methods_file);
|
||||
|
||||
StringBuilder includes_props_content;
|
||||
includes_props_content.append("<Project>\n"
|
||||
" <ItemGroup>\n");
|
||||
|
||||
for (int i = 0; i < compile_items.size(); i++) {
|
||||
String include = path::relative_to(compile_items[i], p_proj_dir).replace("/", "\\");
|
||||
includes_props_content.append(" <Compile Include=\"" + include + "\" />\n");
|
||||
}
|
||||
|
||||
includes_props_content.append(" </ItemGroup>\n"
|
||||
"</Project>\n");
|
||||
|
||||
String includes_props_file = path::join(base_gen_dir, "GeneratedIncludes.props");
|
||||
|
||||
err = _save_file(includes_props_file, includes_props_content);
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Vector<String> &r_compile_items) {
|
||||
Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
|
||||
|
||||
ERR_FAIL_COND_V(!initialized, ERR_UNCONFIGURED);
|
||||
|
||||
@@ -1010,11 +1001,13 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Ve
|
||||
}
|
||||
|
||||
da->change_dir(p_proj_dir);
|
||||
da->make_dir("Core");
|
||||
da->make_dir("ObjectType");
|
||||
da->make_dir("Generated");
|
||||
da->make_dir("Generated/GodotObjects");
|
||||
|
||||
String core_dir = path::join(p_proj_dir, "Core");
|
||||
String obj_type_dir = path::join(p_proj_dir, "ObjectType");
|
||||
String base_gen_dir = path::join(p_proj_dir, "Generated");
|
||||
String godot_objects_gen_dir = path::join(base_gen_dir, "GodotObjects");
|
||||
|
||||
Vector<String> compile_items;
|
||||
|
||||
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) {
|
||||
const TypeInterface &itype = E.get();
|
||||
@@ -1022,7 +1015,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Ve
|
||||
if (itype.api_type != ClassDB::API_EDITOR)
|
||||
continue;
|
||||
|
||||
String output_file = path::join(obj_type_dir, itype.proxy_name + ".cs");
|
||||
String output_file = path::join(godot_objects_gen_dir, itype.proxy_name + ".cs");
|
||||
Error err = _generate_cs_type(itype, output_file);
|
||||
|
||||
if (err == ERR_SKIP)
|
||||
@@ -1031,7 +1024,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Ve
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
r_compile_items.push_back(output_file);
|
||||
compile_items.push_back(output_file);
|
||||
}
|
||||
|
||||
StringBuilder cs_icalls_content;
|
||||
@@ -1068,13 +1061,31 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Ve
|
||||
|
||||
cs_icalls_content.append(INDENT1 CLOSE_BLOCK CLOSE_BLOCK);
|
||||
|
||||
String internal_methods_file = path::join(core_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs");
|
||||
String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs");
|
||||
|
||||
Error err = _save_file(internal_methods_file, cs_icalls_content);
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
r_compile_items.push_back(internal_methods_file);
|
||||
compile_items.push_back(internal_methods_file);
|
||||
|
||||
StringBuilder includes_props_content;
|
||||
includes_props_content.append("<Project>\n"
|
||||
" <ItemGroup>\n");
|
||||
|
||||
for (int i = 0; i < compile_items.size(); i++) {
|
||||
String include = path::relative_to(compile_items[i], p_proj_dir).replace("/", "\\");
|
||||
includes_props_content.append(" <Compile Include=\"" + include + "\" />\n");
|
||||
}
|
||||
|
||||
includes_props_content.append(" </ItemGroup>\n"
|
||||
"</Project>\n");
|
||||
|
||||
String includes_props_file = path::join(base_gen_dir, "GeneratedIncludes.props");
|
||||
|
||||
err = _save_file(includes_props_file, includes_props_content);
|
||||
if (err != OK)
|
||||
return err;
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -1098,9 +1109,8 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
|
||||
// Generate GodotSharp source files
|
||||
|
||||
String core_proj_dir = output_dir.plus_file(CORE_API_ASSEMBLY_NAME);
|
||||
Vector<String> core_compile_items;
|
||||
|
||||
proj_err = generate_cs_core_project(core_proj_dir, core_compile_items);
|
||||
proj_err = generate_cs_core_project(core_proj_dir);
|
||||
if (proj_err != OK) {
|
||||
ERR_PRINT("Generation of the Core API C# project failed.");
|
||||
return proj_err;
|
||||
@@ -1109,22 +1119,14 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
|
||||
// Generate GodotSharpEditor source files
|
||||
|
||||
String editor_proj_dir = output_dir.plus_file(EDITOR_API_ASSEMBLY_NAME);
|
||||
Vector<String> editor_compile_items;
|
||||
|
||||
proj_err = generate_cs_editor_project(editor_proj_dir, editor_compile_items);
|
||||
proj_err = generate_cs_editor_project(editor_proj_dir);
|
||||
if (proj_err != OK) {
|
||||
ERR_PRINT("Generation of the Editor API C# project failed.");
|
||||
return proj_err;
|
||||
}
|
||||
|
||||
// Generate solution
|
||||
|
||||
if (!CSharpProject::generate_api_solution(output_dir,
|
||||
core_proj_dir, core_compile_items, editor_proj_dir, editor_compile_items)) {
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
_log("The solution for the Godot API was generated successfully\n");
|
||||
_log("The Godot API sources were successfully generated\n");
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -3170,7 +3172,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
|
||||
if (bindings_generator.generate_glue(glue_dir_path) != OK)
|
||||
ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C++ glue.");
|
||||
|
||||
if (bindings_generator.generate_cs_api(glue_dir_path.plus_file("Managed/Generated")) != OK)
|
||||
if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK)
|
||||
ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C# API.");
|
||||
}
|
||||
|
||||
|
||||
@@ -635,8 +635,8 @@ class BindingsGenerator {
|
||||
void _initialize();
|
||||
|
||||
public:
|
||||
Error generate_cs_core_project(const String &p_proj_dir, Vector<String> &r_compile_files);
|
||||
Error generate_cs_editor_project(const String &p_proj_dir, Vector<String> &r_compile_items);
|
||||
Error generate_cs_core_project(const String &p_proj_dir);
|
||||
Error generate_cs_editor_project(const String &p_proj_dir);
|
||||
Error generate_cs_api(const String &p_output_dir);
|
||||
Error generate_glue(const String &p_output_dir);
|
||||
|
||||
|
||||
@@ -44,54 +44,6 @@
|
||||
|
||||
namespace CSharpProject {
|
||||
|
||||
bool generate_api_solution_impl(const String &p_solution_dir, const String &p_core_proj_dir, const Vector<String> &p_core_compile_items,
|
||||
const String &p_editor_proj_dir, const Vector<String> &p_editor_compile_items,
|
||||
GDMonoAssembly *p_tools_project_editor_assembly) {
|
||||
|
||||
GDMonoClass *klass = p_tools_project_editor_assembly->get_class("GodotTools.ProjectEditor", "ApiSolutionGenerator");
|
||||
|
||||
Variant solution_dir = p_solution_dir;
|
||||
Variant core_proj_dir = p_core_proj_dir;
|
||||
Variant core_compile_items = p_core_compile_items;
|
||||
Variant editor_proj_dir = p_editor_proj_dir;
|
||||
Variant editor_compile_items = p_editor_compile_items;
|
||||
const Variant *args[5] = { &solution_dir, &core_proj_dir, &core_compile_items, &editor_proj_dir, &editor_compile_items };
|
||||
MonoException *exc = NULL;
|
||||
klass->get_method("GenerateApiSolution", 5)->invoke(NULL, args, &exc);
|
||||
|
||||
if (exc) {
|
||||
GDMonoUtils::debug_print_unhandled_exception(exc);
|
||||
ERR_FAIL_V(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool generate_api_solution(const String &p_solution_dir, const String &p_core_proj_dir, const Vector<String> &p_core_compile_items,
|
||||
const String &p_editor_proj_dir, const Vector<String> &p_editor_compile_items) {
|
||||
|
||||
if (GDMono::get_singleton()->get_tools_project_editor_assembly()) {
|
||||
return generate_api_solution_impl(p_solution_dir, p_core_proj_dir, p_core_compile_items,
|
||||
p_editor_proj_dir, p_editor_compile_items,
|
||||
GDMono::get_singleton()->get_tools_project_editor_assembly());
|
||||
} else {
|
||||
MonoDomain *temp_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ApiSolutionGeneration");
|
||||
CRASH_COND(temp_domain == NULL);
|
||||
_GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(temp_domain);
|
||||
|
||||
_GDMONO_SCOPE_DOMAIN_(temp_domain);
|
||||
|
||||
GDMonoAssembly *tools_project_editor_asm = NULL;
|
||||
|
||||
bool assembly_loaded = GDMono::get_singleton()->load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_asm);
|
||||
ERR_FAIL_COND_V_MSG(!assembly_loaded, false, "Failed to load assembly: '" TOOLS_PROJECT_EDITOR_ASM_NAME "'.");
|
||||
|
||||
return generate_api_solution_impl(p_solution_dir, p_core_proj_dir, p_core_compile_items,
|
||||
p_editor_proj_dir, p_editor_compile_items,
|
||||
tools_project_editor_asm);
|
||||
}
|
||||
}
|
||||
|
||||
void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) {
|
||||
|
||||
if (!GLOBAL_DEF("mono/project/auto_update_project", true))
|
||||
|
||||
@@ -35,9 +35,6 @@
|
||||
|
||||
namespace CSharpProject {
|
||||
|
||||
bool generate_api_solution(const String &p_solution_dir, const String &p_core_proj_dir, const Vector<String> &p_core_compile_items,
|
||||
const String &p_editor_proj_dir, const Vector<String> &p_editor_compile_items);
|
||||
|
||||
void add_item(const String &p_project_path, const String &p_item_type, const String &p_include);
|
||||
|
||||
} // namespace CSharpProject
|
||||
|
||||
Reference in New Issue
Block a user