Nuke.Unreal
Build Unreal apps in Style.
Loading...
Searching...
No Matches
UnrealBuild.Templating.cs
1using System;
2using Nuke.Common;
3using Nuke.Common.IO;
4using Nuke.Common.Utilities.Collections;
6using Serilog;
7
8namespace Nuke.Unreal;
9
10public abstract partial class UnrealBuild : NukeBuild, IUnrealBuild
11{
12
13 /// <summary>
14 /// <para>
15 /// **NUKE PARAMETER**
16 /// </para>
17 /// Specify a folder containing generator specific folders for Scriban scaffolding and templates. If left empty
18 /// the templates coming with Nuke.Unreal will be used.
19 /// </summary>
20 [Parameter]
21 public virtual AbsolutePath TemplatesPath { get; set; } = BoilerplateGenerator.DefaultTemplateFolder;
22
23 /// <summary>
24 /// <para>
25 /// **NUKE PARAMETER**
26 /// </para>
27 /// Name parameter for boilerplate generators.
28 /// </summary>
29 [Parameter]
30 public string[] Name { get; set; } = [];
31
32 /// <summary>
33 /// <para>
34 /// **NUKE PARAMETER**
35 /// </para>
36 /// <para>
37 /// Specification(s) of the imported library(ies). This is used slightly differently based on which library
38 /// type is being used:
39 /// </para>
40 /// <para>
41 /// Header / CMake: It's only the name of the library (like `\--Spec spdlog`)
42 /// </para>
43 /// <para>
44 /// XRepo: specify the xrepo package reference and its config separated by space. For example:
45 /// </para>
46 /// <code>
47 /// \--Spec "zlib"
48 /// \--Spec "zlib 1.2.x"
49 /// \--Spec "boost regex=true,thread=true"
50 /// \--Spec "imgui 1.91.1 freetype=true"
51 /// </code>
52 /// <para>
53 /// Or multiple libraries at once
54 /// </para>
55 /// <code>
56 /// \--Spec "zlib 1.2.x" "boost regex=true,thread=true" "imgui 1.91.1 freetype=true"
57 /// </code>
58 /// <para>
59 /// More about xrepo: https://xrepo.xmake.io
60 /// </para>
61 /// </summary>
62 /// <remarks>
63 /// Since Unreal uses MD runtime linkage `runtimes='MD'` config is always appended by Nuke.Unreal, and the
64 /// user must not specify it.
65 /// </remarks>
66 [Parameter]
67 public virtual string[] Spec { get; set; } = [];
68
69 /// <summary>
70 /// <para>
71 /// **NUKE PARAMETER**
72 /// </para>
73 /// Some boilerplate generators allows to define an extra suffix for names depending on their use case. For
74 /// example `NewLibrary` can use the plain `Name` for library folder structure and `Name_MySuffix` for module
75 /// names (when `Suffix` is set to `MySuffix`)
76 /// </summary>
77 [Parameter]
78 public string? Suffix { get; set; }
79
80 /// <summary>
81 /// <para>
82 /// **NUKE PARAMETER**
83 /// </para>
84 /// <para>
85 /// Specify the type of the third-party library being imported:
86 /// </para>
87 /// <para>
88 /// `Header`<br />
89 /// header only C++ library which doesn't need extra preparation
90 /// </para>
91 /// <para>
92 /// `CMake`<br />
93 /// generates an extra nuke target which prepares the CMake library to be used and distributed in Unreal.
94 /// </para>
95 /// <para>
96 /// `XRepo`<br />
97 /// generates an extra nuke target which then installs the library on preparation via the xrepo package
98 /// manager. The library for a specific platform will be available when running Prepare&lt;library&gt;,
99 /// Prepare or Generate targets.
100 /// </para>
101 /// </summary>
102 [Parameter]
103 public LibraryType? LibraryType { get; set; }
104
105 /// <summary>
106 /// <para>
107 /// **NUKE PARAMETER**
108 /// </para>
109 /// Explicitly add new module to project target
110 /// </summary>
111 [Parameter]
112 public bool AddToTarget { get; set; }
113
114 /// <summary>
115 /// <para>
116 /// **NUKE TARGET**
117 /// </para>
118 /// Create new module in the owning project or plugin (depending on working directory)
119 /// <code>
120 /// \--Name (req,)
121 /// \--AddToTarget
122 /// \--TemplatesPath (adv.)
123 /// </code>
124 /// </summary>
125 public Target NewModule => _ => _
126 .Description(
127 """
128 |
129 | Create new module in the owning project or plugin
130 | (depending on working directory)
131 |
132 | --Name (req,)
133 | --AddToTarget
134 | --TemplatesPath (adv.)
135
136 """
137 )
138 .Before(Generate)
139 .Requires(() => Name)
140 .Executes(() =>
141 Name.ForEach(n =>
142 new ModuleGenerator()
143 .SetAddToTarget(AddToTarget)
144 .Generate(
146 (AbsolutePath) Environment.CurrentDirectory,
147 n
148 )
149 )
150 );
151
152 /// <summary>
153 /// <para>
154 /// **NUKE TARGET**
155 /// </para>
156 /// Add C++ code to a project which doesn't have one yet.
157 /// <code>
158 /// \--Name (req,)
159 /// \--TemplatesPath (adv.)
160 /// </code>
161 /// </summary>
162 public Target AddCode => _ => _
163 .Description(
164 """
165 |
166 | Add C++ code to a project which doesn't have one yet.
167 |
168 | --Name (req,)
169 | --TemplatesPath (adv.)
170
171 """
172 )
173 .Before(Generate)
174 .Executes(() =>
179 )
180 );
181
182 /// <summary>
183 /// <para>
184 /// **NUKE TARGET**
185 /// </para>
186 /// Create a new project plugin.
187 /// <code>
188 /// \--Name (req,)
189 /// \--TemplatesPath (adv.)
190 /// </code>
191 /// </summary>
192 public Target NewPlugin => _ => _
193 .Description(
194 """
195 |
196 | Create a new project plugin.
197 |
198 | --Name (req,)
199 | --TemplatesPath (adv.)
200
201 """
202 )
203 .Before(Generate)
204 .Requires(() => Name)
205 .Executes(() =>
206 Name.ForEach(n =>
209 (AbsolutePath) Environment.CurrentDirectory,
210 n, Unreal.Version(this)
211 )
212 )
213 );
214
215 /// <summary>
216 /// <para>
217 /// **NUKE TARGET**
218 /// </para>
219 /// Create new Unreal Actor in current directory
220 /// <code>
221 /// \--Name (req,)
222 /// \--TemplatesPath (adv.)
223 /// </code>
224 /// </summary>
225 public Target NewActor => _ => _
226 .Description(
227 """
228 |
229 | Create new Unreal Actor in current directory
230 |
231 | --Name (req,)
232 | --TemplatesPath (adv.)
233
234 """
235 )
236 .Before(Generate)
237 .Requires(() => Name)
238 .Executes(() =>
239 Name.ForEach(n =>
242 (AbsolutePath) Environment.CurrentDirectory,
243 new(n)
244 )
245 )
246 );
247
248 /// <summary>
249 /// <para>
250 /// **NUKE TARGET**
251 /// </para>
252 /// Create new Unreal Interface in current directory
253 /// <code>
254 /// \--Name (req,)
255 /// \--TemplatesPath (adv.)
256 /// </code>
257 /// </summary>
258 public Target NewInterface => _ => _
259 .Description(
260 """
261 |
262 | Create new Unreal Interface in current directory
263 |
264 | --Name (req,)
265 | --TemplatesPath (adv.)
266
267 """
268 )
269 .Before(Generate)
270 .Requires(() => Name)
271 .Executes(() =>
272 Name.ForEach(n =>
275 (AbsolutePath) Environment.CurrentDirectory,
276 new(n)
277 )
278 )
279 );
280
281 /// <summary>
282 /// <para>
283 /// **NUKE TARGET**
284 /// </para>
285 /// Create new Unreal Object in current directory
286 /// <code>
287 /// \--Name (req,)
288 /// \--TemplatesPath (adv.)
289 /// </code>
290 /// </summary>
291 public Target NewObject => _ => _
292 .Description(
293 """
294 |
295 | Create new Unreal Object in current directory
296 |
297 | --Name (req,)
298 | --TemplatesPath (adv.)
299
300 """
301 )
302 .Before(Generate)
303 .Requires(() => Name)
304 .Executes(() =>
305 Name.ForEach(n =>
308 (AbsolutePath) Environment.CurrentDirectory,
309 new(n)
310 )
311 )
312 );
313
314 /// <summary>
315 /// <para>
316 /// **NUKE TARGET**
317 /// </para>
318 /// Create new Unreal Struct in current directory
319 /// <code>
320 /// \--Name (req,)
321 /// \--TemplatesPath (adv.)
322 /// </code>
323 /// </summary>
324 public Target NewStruct => _ => _
325 .Description(
326 """
327 |
328 | Create new Unreal Struct in current directory
329 |
330 | --Name (req,)
331 | --TemplatesPath (adv.)
332
333 """
334 )
335 .Before(Generate)
336 .Requires(() => Name)
337 .Executes(() =>
338 Name.ForEach(n =>
341 (AbsolutePath) Environment.CurrentDirectory,
342 new(n)
343 )
344 )
345 );
346
347 /// <summary>
348 /// <para>
349 /// **NUKE TARGET**
350 /// </para>
351 /// Create new Unreal Automation Spec in current directory
352 /// <code>
353 /// \--Name (req,)
354 /// \--TemplatesPath (adv.)
355 /// </code>
356 /// </summary>
357 public Target NewSpec => _ => _
358 .Description(
359 """
360 |
361 | Create new Unreal Automation Spec in current directory
362 |
363 | --Name (req,)
364 | --TemplatesPath (adv.)
365
366 """
367 )
368 .Before(Generate)
369 .Requires(() => Name)
370 .Executes(() =>
371 Name.ForEach(n =>
374 (AbsolutePath) Environment.CurrentDirectory,
375 new(n)
376 )
377 )
378 );
379
380 /// <summary>
381 /// <para>
382 /// **NUKE TARGET**
383 /// </para>
384 /// <para>
385 /// Create boilerplate module for third-party C++ libraries. Specify the kind of
386 /// library with `\--LibraryType Header|CMake|XRepo` The latter two will generate
387 /// extra nuke targets preparing the library to be consumed by Unreal.
388 /// Fetching/storing the library is up to the developer
389 /// (except of course with XRepo).
390 /// </para>
391 /// <para>
392 /// Use type specific targets for more comfortable CLI experience, for example <br />
393 /// `nuke use-xrepo \--Spec tracy` <br />
394 /// instead of <br />
395 /// `nuke UseLibrary --LibraryType xrepo --Spec tracy`
396 /// </para>
397 /// <para>
398 /// This only needs to be done once, you can check the results into source control.
399 /// </para>
400 /// <code>
401 /// \--Spec (req,)
402 /// \--LibraryType
403 /// \--Suffix (adv.)
404 /// </code>
405 /// </summary>
406 public Target UseLibrary => _ => _
407 .Description(
408 """
409 |
410 | Create boilerplate module for third-party C++ libraries. Specify the kind of
411 | library with `--LibraryType Header|CMake|XRepo` The latter two will generate
412 | extra nuke targets preparing the library to be consumed by Unreal.
413 | Fetching/storing the library is up to the developer
414 | (except of course with XRepo).
415 |
416 | Use type specific targets for more comfortable CLI experience, for example
417 | nuke use-xrepo --spec tracy
418 | instead of
419 | nuke UseLibrary --LibraryType xrepo --spec tracy
420 |
421 | This only needs to be done once, you can check the results into source control.
422 |
423 | --Spec (req,)
424 | --LibraryType
425 | --Suffix (adv.)
426
427 """
428 )
429 .DependsOn(EnsureBuildPluginSupport)
430 .Before(Prepare, Generate)
431 .Executes(() =>
432 {
433 Assert.NotEmpty(Spec);
434 Assert.NotNull(LibraryType);
435
436 Spec.ForEach(n =>
437 {
438 Log.Information("Preparing library {0}", n);
439 new LibraryGenerator().Generate(
440 this,
442 EnvironmentInfo.WorkingDirectory,
444 );
445 }
446 );
447 if (LibraryType == LibraryType.XRepo)
448 Log.Information("Run `Prepare` or `Generate` to install new libraries.");
449 Log.Information("This only needs to be done once, you can check the results into source control.");
450 });
451
452 /// <summary>
453 /// <para>
454 /// **NUKE TARGET**
455 /// </para>
456 /// <para>
457 /// Use libraries from the xrepo package manager. This target only configures another target which will
458 /// eventually fetch the input libraries. To make them available to Unreal run `Prepare` or `Generate`
459 /// targets.
460 /// </para>
461 /// <para>
462 /// Specify the xrepo package reference and its config separated by space. For example:
463 /// </para>
464 /// <code>
465 /// nuke UseXRepo \--Spec "zlib"
466 /// nuke UseXRepo \--Spec "zlib 1.2.x"
467 /// nuke UseXRepo \--Spec "boost regex=true,thread=true"
468 /// nuke UseXRepo \--Spec "imgui 1.91.1 freetype=true"
469 /// </code>
470 /// <para>
471 /// Or multiple libraries at once
472 /// </para>
473 /// <code>
474 /// nuke UseXRepo \--Spec "zlib 1.2.x" "boost regex=true,thread=true" "imgui 1.91.1 freetype=true"
475 /// </code>
476 /// <para>
477 /// More about xrepo: https://xrepo.xmake.io
478 /// </para>
479 /// <code>
480 /// \--Spec (req,)
481 /// \--Suffix (adv.)
482 /// </code>
483 /// </summary>
484 /// <remarks>
485 /// Since Unreal uses MD runtime linkage `runtimes='MD'` config is always appended by Nuke.Unreal, and the
486 /// user must not specify it.
487 /// </remarks>
488 public Target UseXRepo => _ => _
489 .Description(
490 """
491 |
492 | Use libraries from the xrepo package manager. This target only configures
493 | another target which will eventually fetch the input libraries. To make them
494 | available to Unreal run `Prepare` or `Generate` targets.
495 |
496 | Specify the xrepo package reference and its config separated by space.
497 | For example:
498 |
499 | nuke UseXRepo --Spec "zlib"
500 | nuke UseXRepo --Spec "zlib 1.2.x"
501 | nuke UseXRepo --Spec "boost regex=true,thread=true"
502 | nuke UseXRepo --Spec "imgui 1.91.1 freetype=true"
503 |
504 | Or multiple libraries at once
505 |
506 | nuke UseXRepo --Spec
507 | "zlib 1.2.x"
508 | "boost regex=true,thread=true"
509 | "imgui 1.91.1 freetype=true"
510 | <etc...>
511 |
512 | More about xrepo: https://xrepo.xmake.io
513 | NOTE: since Unreal uses MD runtime linkage `runtimes='MD'` config is always
514 | appended by Nuke.Unreal, and the user must not specify it.
515 |
516 | This only needs to be done once, you can check the results into source control.
517 |
518 | --Spec (req,)
519 | --Suffix (adv.)
520
521 """
522 )
523 .Triggers(UseLibrary)
524 .Requires(() => Spec)
525 .Executes(() => LibraryType = LibraryType.XRepo);
526
527 /// <summary>
528 /// <para>
529 /// **NUKE TARGET**
530 /// </para>
531 /// </summary>
532 public Target UseCMake => _ => _
533 .Triggers(UseLibrary)
534 .Requires(() => Spec)
535 .Executes(() => LibraryType = LibraryType.CMake);
536
537 /// <summary>
538 /// <para>
539 /// **NUKE TARGET**
540 /// </para>
541 /// </summary>
542 public Target UseHeaderOnly => _ => _
543 .Triggers(UseLibrary)
544 .Requires(() => Spec)
545 .Executes(() => LibraryType = LibraryType.Header);
546}
The main build class Unreal projects using Nuke.Unreal should inherit from. This class contains all b...
AbsolutePath ProjectFolder
Path to folder containing the .project file.
virtual AbsolutePath TemplatesPath
string ProjectName
Short name of the project.
virtual Target EnsureBuildPluginSupport
A collection of utilities around basic functions regarding the environment of the Engine we're workin...
Definition Unreal.cs:24
static EngineVersion Version(IUnrealBuild build)
Get high-level version of currently used Engine.
Base interface for build components which require an UnrealBuild main class.