// 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();
}
}
}
}