Add ExternalModules to game modules for custom scripting binaries linking

This commit is contained in:
Wojtek Figat
2022-07-18 18:08:09 +02:00
parent 5c6b5ad948
commit b67649dfbd
4 changed files with 125 additions and 33 deletions

View File

@@ -1,5 +1,6 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.IO;
@@ -188,6 +189,59 @@ namespace Flax.Build.NativeCpp
FileReferences = new HashSet<string>(),
};
/// <summary>
/// The external module linking options.
/// </summary>
public struct ExternalModule : IEquatable<ExternalModule>
{
public enum Types
{
Native,
CSharp,
Custom,
}
public string Name;
public string Path;
public Types Type;
public ExternalModule(Types type, string path, string name = null)
{
Name = name ?? System.IO.Path.GetFileNameWithoutExtension(path);
Type = type;
Path = path;
}
/// <inheritdoc />
public bool Equals(ExternalModule other)
{
return Name == other.Name;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is ExternalModule other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return Name.GetHashCode();
}
/// <inheritdoc />
public override string ToString()
{
return Name;
}
}
/// <summary>
/// The custom external binary modules to referenced by this module. Can be used to extern the custom C# or C++ library with scripts to be used at runtime.
/// </summary>
public HashSet<ExternalModule> ExternalModules = new HashSet<ExternalModule>();
/// <summary>
/// Merges the files from input source paths into source files and clears the source paths list.
/// </summary>

View File

@@ -75,6 +75,56 @@ namespace Flax.Build
public BuildTargetBinaryModuleInfo[] BinaryModules;
public BuildTargetReferenceInfo[] References;
internal void AddExternalBinaryModules(ref int i, string projectPath, HashSet<BuildOptions.ExternalModule> externalModules)
{
foreach (var externalModule in externalModules)
{
var binaryModuleInfo = new BuildTargetBinaryModuleInfo
{
NativePath = string.Empty,
ManagedPath = string.Empty,
Name = externalModule.Name,
};
switch (externalModule.Type)
{
case BuildOptions.ExternalModule.Types.Native:
binaryModuleInfo.NativePath = externalModule.Path;
binaryModuleInfo.NativePathProcessed = ProcessPath(binaryModuleInfo.NativePath, projectPath);
break;
case BuildOptions.ExternalModule.Types.CSharp:
binaryModuleInfo.ManagedPath = externalModule.Path;
binaryModuleInfo.ManagedPathProcessed = ProcessPath(binaryModuleInfo.ManagedPath, projectPath);
break;
}
binaryModuleInfo.NativePathProcessed = ProcessPath(binaryModuleInfo.NativePath, projectPath);
binaryModuleInfo.ManagedPathProcessed = ProcessPath(binaryModuleInfo.ManagedPath, projectPath);
BinaryModules[i++] = binaryModuleInfo;
}
}
internal void AddReferencedBuilds(ref int i, string projectPath, Dictionary<ProjectInfo, BuildData> referencedBuilds)
{
foreach (var referenceBuild in referencedBuilds)
{
var reference = referenceBuild.Value;
var referenceOutputTargetFilePath = reference.Target.GetOutputFilePath(reference.TargetOptions);
var referenceOutputPath = Path.GetDirectoryName(referenceOutputTargetFilePath);
var referenceInfo = new BuildTargetReferenceInfo
{
ProjectPath = reference.Project.ProjectPath,
Path = Path.Combine(referenceOutputPath, reference.Target.Name + ".Build.json"),
};
referenceInfo.ProjectPathProcessed = ProcessPath(referenceInfo.ProjectPath, projectPath);
referenceInfo.PathProcessed = ProcessPath(referenceInfo.Path, projectPath);
References[i++] = referenceInfo;
}
}
public static string ProcessPath(string path, string projectPath)
{
if (string.IsNullOrEmpty(path))
@@ -319,6 +369,7 @@ namespace Flax.Build
moduleOptions.Libraries.AddRange(dependencyOptions.Libraries);
moduleOptions.DelayLoadLibraries.AddRange(dependencyOptions.DelayLoadLibraries);
moduleOptions.ScriptingAPI.Add(dependencyOptions.ScriptingAPI);
moduleOptions.ExternalModules.AddRange(dependencyOptions.ExternalModules);
}
}
foreach (var moduleName in moduleOptions.PublicDependencies)
@@ -337,6 +388,7 @@ namespace Flax.Build
moduleOptions.Libraries.AddRange(dependencyOptions.Libraries);
moduleOptions.DelayLoadLibraries.AddRange(dependencyOptions.DelayLoadLibraries);
moduleOptions.ScriptingAPI.Add(dependencyOptions.ScriptingAPI);
moduleOptions.ExternalModules.AddRange(dependencyOptions.ExternalModules);
}
}
@@ -449,6 +501,7 @@ namespace Flax.Build
if (dependencyModule != null && buildData.Modules.TryGetValue(dependencyModule, out var dependencyOptions))
{
moduleOptions.ScriptingAPI.Add(dependencyOptions.ScriptingAPI);
moduleOptions.ExternalModules.AddRange(dependencyOptions.ExternalModules);
}
}
foreach (var moduleName in moduleOptions.PublicDependencies)
@@ -457,6 +510,7 @@ namespace Flax.Build
if (dependencyModule != null && buildData.Modules.TryGetValue(dependencyModule, out var dependencyOptions))
{
moduleOptions.ScriptingAPI.Add(dependencyOptions.ScriptingAPI);
moduleOptions.ExternalModules.AddRange(dependencyOptions.ExternalModules);
}
}
@@ -810,6 +864,7 @@ namespace Flax.Build
buildData.TargetOptions.Libraries.AddRange(moduleOptions.Libraries);
buildData.TargetOptions.DelayLoadLibraries.AddRange(moduleOptions.DelayLoadLibraries);
buildData.TargetOptions.ScriptingAPI.Add(moduleOptions.ScriptingAPI);
buildData.TargetOptions.ExternalModules.AddRange(moduleOptions.ExternalModules);
}
}
}
@@ -840,11 +895,13 @@ namespace Flax.Build
Architecture = toolchain.Architecture.ToString(),
Configuration = configuration.ToString(),
HotReloadPostfix = targetBuildOptions.HotReloadPostfix,
BinaryModules = new BuildTargetBinaryModuleInfo[buildData.BinaryModules.Length],
BinaryModules = new BuildTargetBinaryModuleInfo[buildData.BinaryModules.Length + targetBuildOptions.ExternalModules.Count],
References = new BuildTargetReferenceInfo[buildData.ReferenceBuilds.Count],
};
int i;
for (i = 0; i < buildData.BuildInfo.BinaryModules.Length; i++)
// Binary modules
for (i = 0; i < buildData.BinaryModules.Length; i++)
{
var binaryModule = buildData.BinaryModules[i];
var binaryModuleInfo = new BuildTargetBinaryModuleInfo
@@ -905,23 +962,11 @@ namespace Flax.Build
buildData.BuildInfo.BinaryModules[i] = binaryModuleInfo;
}
buildData.BuildInfo.AddExternalBinaryModules(ref i, project.ProjectFolderPath, targetBuildOptions.ExternalModules);
i = 0;
foreach (var referenceBuild in buildData.ReferenceBuilds)
{
var reference = referenceBuild.Value;
var referenceOutputTargetFilePath = reference.Target.GetOutputFilePath(reference.TargetOptions);
var referenceOutputPath = Path.GetDirectoryName(referenceOutputTargetFilePath);
var referenceInfo = new BuildTargetReferenceInfo
{
ProjectPath = reference.Project.ProjectPath,
Path = Path.Combine(referenceOutputPath, reference.Target.Name + ".Build.json"),
};
buildData.BuildInfo.AddReferencedBuilds(ref i, project.ProjectFolderPath, buildData.ReferenceBuilds);
referenceInfo.ProjectPathProcessed = BuildTargetInfo.ProcessPath(referenceInfo.ProjectPath, project.ProjectFolderPath);
referenceInfo.PathProcessed = BuildTargetInfo.ProcessPath(referenceInfo.Path, project.ProjectFolderPath);
buildData.BuildInfo.References[i++] = referenceInfo;
}
if (!buildData.Target.IsPreBuilt)
Utilities.WriteFileIfChanged(Path.Combine(outputPath, target.Name + ".Build.json"), JsonConvert.SerializeObject(buildData.BuildInfo, Formatting.Indented));
}
@@ -1071,6 +1116,7 @@ namespace Flax.Build
// Merge module into target environment
buildData.TargetOptions.ScriptingAPI.Add(moduleOptions.ScriptingAPI);
buildData.TargetOptions.ExternalModules.AddRange(moduleOptions.ExternalModules);
foreach (var e in moduleOptions.DependencyFiles)
buildData.TargetOptions.DependencyFiles.Add(e);
foreach (var e in moduleOptions.OptionalDependencyFiles)
@@ -1097,10 +1143,12 @@ namespace Flax.Build
Architecture = architecture.ToString(),
Configuration = configuration.ToString(),
HotReloadPostfix = targetBuildOptions.HotReloadPostfix,
BinaryModules = new BuildTargetBinaryModuleInfo[buildData.BinaryModules.Length],
BinaryModules = new BuildTargetBinaryModuleInfo[buildData.BinaryModules.Length + targetBuildOptions.ExternalModules.Count],
References = new BuildTargetReferenceInfo[buildData.ReferenceBuilds.Count],
};
int i;
// Binary modules
for (i = 0; i < buildData.BuildInfo.BinaryModules.Length; i++)
{
var binaryModule = buildData.BinaryModules[i];
@@ -1115,23 +1163,11 @@ namespace Flax.Build
buildData.BuildInfo.BinaryModules[i] = binaryModuleInfo;
}
buildData.BuildInfo.AddExternalBinaryModules(ref i, project.ProjectFolderPath, targetBuildOptions.ExternalModules);
i = 0;
foreach (var referenceBuild in buildData.ReferenceBuilds)
{
var reference = referenceBuild.Value;
var referenceOutputTargetFilePath = reference.Target.GetOutputFilePath(reference.TargetOptions);
var referenceOutputPath = Path.GetDirectoryName(referenceOutputTargetFilePath);
var referenceInfo = new BuildTargetReferenceInfo
{
ProjectPath = reference.Project.ProjectPath,
Path = Path.Combine(referenceOutputPath, reference.Target.Name + ".Build.json"),
};
buildData.BuildInfo.AddReferencedBuilds(ref i, project.ProjectFolderPath, buildData.ReferenceBuilds);
referenceInfo.ProjectPathProcessed = BuildTargetInfo.ProcessPath(referenceInfo.ProjectPath, project.ProjectFolderPath);
referenceInfo.PathProcessed = BuildTargetInfo.ProcessPath(referenceInfo.Path, project.ProjectFolderPath);
buildData.BuildInfo.References[i++] = referenceInfo;
}
if (!buildData.Target.IsPreBuilt)
Utilities.WriteFileIfChanged(Path.Combine(outputPath, target.Name + ".Build.json"), JsonConvert.SerializeObject(buildData.BuildInfo, Formatting.Indented));
}