Skip to content

Commit b730f14

Browse files
authored
feat: codegen during prebuild step (#9)
1 parent b19fb06 commit b730f14

File tree

1 file changed

+104
-3
lines changed

1 file changed

+104
-3
lines changed

Source/Ecsact/Ecsact.Build.cs

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
using System.IO;
33
using System.Diagnostics;
44
using System;
5+
using System.Linq;
6+
using System.Collections.Generic;
7+
using UnrealBuildBase;
8+
using EpicGames.Core;
59

610
[Serializable]
711
public class EcsactSdkNotFound : Exception {
@@ -33,8 +37,11 @@ public Ecsact(ReadOnlyTargetRules Target) : base(Target) {
3337
PrivateDependencyModuleNames.Add("UnrealEd");
3438
}
3539

36-
var ecsactSdkIncludeDir = GetEcsactSdkIncludeDir();
37-
PublicIncludePaths.Add(ecsactSdkIncludeDir);
40+
var EcsactSdkVersion = GetEcsactSdkVersion();
41+
Environment.SetEnvironmentVariable("EcsactPlugin_SdkVersion", EcsactSdkVersion);
42+
43+
var EcsactSdkIncludeDir = GetEcsactSdkIncludeDir();
44+
PublicIncludePaths.Add(EcsactSdkIncludeDir);
3845

3946
// NOTE: For now these APIs are loaded on module startup
4047
PublicDefinitions.AddRange(new string[] {
@@ -45,13 +52,64 @@ public Ecsact(ReadOnlyTargetRules Target) : base(Target) {
4552
"ECSACT_SERIALIZE_API_LOAD_AT_RUNTIME",
4653
"ECSACT_STATIC_API_LOAD_AT_RUNTIME",
4754
});
55+
56+
var EcsactSources = GetEcsactSources();
57+
58+
if(EcsactSources.Length > 0) {
59+
var CodegenArgs = new List<string>() {
60+
"codegen",
61+
"--format=json",
62+
"--plugin=cpp_header",
63+
"--plugin=systems_header",
64+
"--plugin=cpp_systems_header",
65+
"--plugin=cpp_systems_source"
66+
};
67+
CodegenArgs.AddRange(EcsactSources);
68+
ExecEcsactCli(CodegenArgs);
69+
}
70+
}
71+
72+
private string[] GetEcsactSources() {
73+
var projectRoot = GetProjectRoot(Target);
74+
return Directory.GetFiles(
75+
Path.Combine(projectRoot.FullName, "Source"),
76+
"*.ecsact",
77+
SearchOption.AllDirectories
78+
);
79+
}
80+
81+
private string GetEcsactSdkVersion() {
82+
var version = "";
83+
84+
try {
85+
var startInfo = new ProcessStartInfo();
86+
startInfo.FileName = "ecsact";
87+
startInfo.Arguments = "--version";
88+
startInfo.RedirectStandardOutput = true;
89+
startInfo.UseShellExecute = false;
90+
startInfo.CreateNoWindow = true;
91+
92+
using(Process process = Process.Start(startInfo)) {
93+
using(StreamReader reader = process.StandardOutput) {
94+
version = reader.ReadToEnd().Trim();
95+
}
96+
}
97+
} catch(Exception err) {
98+
throw new EcsactSdkNotFound(err);
99+
}
100+
101+
if(String.IsNullOrEmpty(version)) {
102+
throw new EcsactSdkNotFound(null);
103+
}
104+
105+
return version;
48106
}
49107

50108
private string GetEcsactSdkIncludeDir() {
51109
var includePath = "";
52110

53111
try {
54-
ProcessStartInfo startInfo = new ProcessStartInfo();
112+
var startInfo = new ProcessStartInfo();
55113
startInfo.FileName = "ecsact";
56114
startInfo.Arguments = "config include_dir";
57115
startInfo.RedirectStandardOutput = true;
@@ -69,4 +127,47 @@ private string GetEcsactSdkIncludeDir() {
69127

70128
return includePath;
71129
}
130+
131+
private void ExecEcsactCli(IList<string> Args) {
132+
try {
133+
var StartInfo = new ProcessStartInfo();
134+
StartInfo.FileName = "ecsact";
135+
foreach(var Arg in Args) {
136+
StartInfo.ArgumentList.Add(Arg);
137+
}
138+
StartInfo.UseShellExecute = false;
139+
StartInfo.CreateNoWindow = true;
140+
StartInfo.RedirectStandardOutput = true;
141+
StartInfo.RedirectStandardError = true;
142+
var Proc = Process.Start(StartInfo);
143+
144+
var Line = "";
145+
while((Line = Proc.StandardOutput.ReadLine()) != null) {
146+
Console.WriteLine(Line);
147+
}
148+
149+
Proc.WaitForExit();
150+
if(Proc.ExitCode != 0) {
151+
throw new BuildException("ecsact exited with code: " + Proc.ExitCode);
152+
}
153+
} catch(BuildException err) {
154+
throw err;
155+
} catch(Exception err) {
156+
throw new EcsactSdkNotFound(err);
157+
}
158+
}
159+
160+
private DirectoryReference GetProjectRoot(ReadOnlyTargetRules Target) {
161+
if (Target.ProjectFile != null) {
162+
return Target.ProjectFile.Directory;
163+
}
164+
165+
// Without a Target.ProjectFile we're probably installed as an Engine plugin.
166+
// Only information we have about the project is the current directory.
167+
var Root = new DirectoryReference(Directory.GetCurrentDirectory());
168+
while (Root != null && !File.Exists(Path.Combine(Root.FullName, "*.uproject"))) {
169+
Root = Root.ParentDirectory;
170+
}
171+
return Root;
172+
}
72173
}

0 commit comments

Comments
 (0)