// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; using System.IO; namespace Flax.Build.NativeCpp { /// /// The native C++ module build flag types. /// [Flags] public enum BuildFlags { /// /// Nothing. /// None = 0, /// /// Projects generation (not actual build, just build setup evaluation). /// GenerateProject = 1, } /// /// The nullable context type used with reference types (C#). /// public enum CSharpNullableReferences { /// /// The code is nullable oblivious, nullable warnings and language analysis features are disabled. /// Disable, /// /// The compiler enables all null reference analysis and all language features. /// Enable, /// /// The compiler performs all null analysis and emits warnings when code might dereference null. /// Warnings, /// /// The compiler doesn't perform null analysis or emit warnings when code might dereference null. /// Annotations, } /// /// The native C++ module build settings container. /// public sealed class BuildOptions { /// /// The target that builds this module. /// public Target Target; /// /// The build platform. /// public Platform Platform; /// /// The build platform toolchain. /// public Toolchain Toolchain; /// /// The build architecture. /// public TargetArchitecture Architecture; /// /// The build configuration. /// public TargetConfiguration Configuration; /// /// The module compilation environment. /// public CompileEnvironment CompileEnv; /// /// The module linking environment. /// public LinkEnvironment LinkEnv; /// /// The source file directories. By default it contains the directory that contains this module file. /// public List SourcePaths = new List(); /// /// The source files to include in module build. /// public List SourceFiles = new List(); /// /// The collection of the modules that are required by this module (for linking). Inherited by the modules that include it. /// public List PublicDependencies = new List(); /// /// The collection of the modules that are required by this module (for linking). /// public List PrivateDependencies = new List(); /// /// The collection of defines with preprocessing symbol for a source files of this module. Inherited by the modules that include it. /// public readonly HashSet PublicDefinitions = new HashSet(); /// /// The collection of defines with preprocessing symbol for a source files of this module. /// public readonly HashSet PrivateDefinitions = new HashSet(); /// /// The collection of additional include paths for a source files of this module. Inherited by the modules that include it. /// public readonly HashSet PublicIncludePaths = new HashSet(); /// /// The collection of additional include paths for a source files of this module. /// public readonly HashSet PrivateIncludePaths = new HashSet(); /// /// The dependency files to include with output (additional debug files, dynamic libraries, etc.). /// public HashSet DependencyFiles = new HashSet(); /// /// The optional dependency files to include with output (additional debug files, dynamic libraries, etc.). Missing files won't fail the build. /// public HashSet OptionalDependencyFiles = new HashSet(); /// /// The list of libraries to link (typically external and third-party plugins). /// public HashSet Libraries = new HashSet(); /// /// The list of libraries to link for delay-load (typically external and third-party plugins). /// public HashSet DelayLoadLibraries = new HashSet(); /// /// The build output files (binaries, object files and static or dynamic libraries). /// public List OutputFiles = new List(); /// /// The intermediate build artifacts folder directory. /// public string IntermediateFolder; /// /// The output build artifacts folder directory. /// public string OutputFolder; /// /// The build commands working folder directory. /// public string WorkingDirectory; /// /// The hot reload postfix added to the output binaries. /// public string HotReloadPostfix; /// /// The build flags. /// public BuildFlags Flags; /// /// The full path to the dependencies folder for the current build platform, configuration, and architecture. /// public string DepsFolder => Path.Combine(Globals.EngineRoot, "Source", "Platforms", Platform.Target.ToString(), "Binaries", "ThirdParty", Architecture.ToString()); /// /// The C# scripting API building options. /// public struct ScriptingAPIOptions { /// /// The preprocessor defines. /// public HashSet Defines; /// /// The system libraries references. /// public HashSet SystemReferences; /// /// The system analyzers/source generators. /// public HashSet SystemAnalyzers; /// /// The .NET libraries references (dll or exe files paths). /// public HashSet FileReferences; /// /// The .NET analyzers (dll or exe files paths). /// public HashSet Analyzers; /// /// True if ignore compilation warnings due to missing code documentation comments. /// public bool IgnoreMissingDocumentationWarnings; /// /// The nullable context used in C# project. /// public CSharpNullableReferences CSharpNullableReferences = CSharpNullableReferences.Disable; /// /// Enable code optimization. /// public bool? Optimization; public ScriptingAPIOptions() { } /// /// Adds the other options into this. /// /// The other. public void Add(ScriptingAPIOptions other, bool addBuildOptions = true) { Defines.AddRange(other.Defines); SystemReferences.AddRange(other.SystemReferences); FileReferences.AddRange(other.FileReferences); Analyzers.AddRange(other.Analyzers); IgnoreMissingDocumentationWarnings |= other.IgnoreMissingDocumentationWarnings; if (addBuildOptions) { if (other.Optimization.HasValue) Optimization |= other.Optimization; } } } /// /// The scripting API building options. /// public ScriptingAPIOptions ScriptingAPI = new ScriptingAPIOptions { Defines = new HashSet(), SystemReferences = new HashSet { "mscorlib", "netstandard", "Microsoft.CSharp", "System", "System.Collections", "System.Collections.Concurrent", "System.Collections.NonGeneric", "System.Collections.Specialized", "System.Collections.Immutable", "System.ComponentModel", "System.ComponentModel.DataAnnotations", "System.ComponentModel.Primitives", //"System.ComponentModel.TypeConverter", "System.Console", "System.Core", "System.Diagnostics.StackTrace", "System.Globalization", "System.IO", "System.IO.Compression", "System.IO.FileSystem.Watcher", "System.Linq", "System.Linq.Expressions", "System.Memory", "System.Net", "System.Net.Http", "System.Net.Primitives", "System.ObjectModel", "System.ValueTuple", "System.Runtime", "System.Runtime.Extensions", "System.Runtime.Handles", "System.Runtime.Intrinsics", "System.Runtime.Numerics", "System.Runtime.Loader", "System.Runtime.CompilerServices.Unsafe", "System.Runtime.InteropServices", "System.Runtime.InteropServices.RuntimeInformation", "System.Runtime.Serialization", "System.Runtime.Serialization.Formatters", "System.Security.Cryptography", "System.Security.Cryptography.Algorithms", "System.Security.Cryptography.Primitives", //"System.Text.RegularExpressions", "System.Threading.Tasks.Parallel", //"System.Xml", "System.Threading", "System.Threading.Thread", "System.Reflection", //"System.Reflection.Metadata", }, SystemAnalyzers = new HashSet { "Microsoft.Interop.LibraryImportGenerator", "Microsoft.Interop.SourceGeneration", }, FileReferences = new HashSet(), Analyzers = new HashSet(), }; /// /// The external module linking options. /// public struct ExternalModule : IEquatable { 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; } /// public bool Equals(ExternalModule other) { return Name == other.Name; } /// public override bool Equals(object obj) { return obj is ExternalModule other && Equals(other); } /// public override int GetHashCode() { return Name.GetHashCode(); } /// public override string ToString() { return Name; } } /// /// 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. /// public HashSet ExternalModules = new HashSet(); /// /// Merges the files from input source paths into source files and clears the source paths list. /// internal void MergeSourcePathsIntoSourceFiles() { if (SourcePaths.Count == 0) return; using (new ProfileEventScope("MergeSourcePathsIntoSourceFiles")) { for (var i = 0; i < SourcePaths.Count; i++) { var path = SourcePaths[i]; if (!Directory.Exists(path)) continue; var files = Directory.GetFiles(path, "*", SearchOption.AllDirectories); var count = SourceFiles.Count; if (SourceFiles.Count == 0) { SourceFiles.AddRange(files); } else { for (int j = 0; j < files.Length; j++) { bool unique = true; for (int k = 0; k < count; k++) { if (SourceFiles[k] == files[j]) { unique = false; break; } } if (unique) SourceFiles.Add(files[j]); } } } SourcePaths.Clear(); } } } }