diff --git a/Source/Engine/Foliage/FoliageType.h b/Source/Engine/Foliage/FoliageType.h index 0bc556fc9..4251b6924 100644 --- a/Source/Engine/Foliage/FoliageType.h +++ b/Source/Engine/Foliage/FoliageType.h @@ -46,7 +46,7 @@ API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API FoliageType : public ScriptingOb DECLARE_SCRIPTING_TYPE_NO_SPAWN(FoliageType); friend Foliage; private: - int8 _isReady : 1; + uint8 _isReady : 1; public: /// diff --git a/Source/Engine/Level/Actor.h b/Source/Engine/Level/Actor.h index a1f2dc78f..0ce9a0dbc 100644 --- a/Source/Engine/Level/Actor.h +++ b/Source/Engine/Level/Actor.h @@ -33,12 +33,12 @@ API_CLASS(Abstract) class FLAXENGINE_API Actor : public SceneObject friend Prefab; friend PrefabInstanceData; protected: - int16 _isActive : 1; - int16 _isActiveInHierarchy : 1; - int16 _isPrefabRoot : 1; - int16 _isEnabled : 1; - int16 _drawNoCulling : 1; - int16 _drawCategory : 4; + uint16 _isActive : 1; + uint16 _isActiveInHierarchy : 1; + uint16 _isPrefabRoot : 1; + uint16 _isEnabled : 1; + uint16 _drawNoCulling : 1; + uint16 _drawCategory : 4; byte _layer; StaticFlags _staticFlags; Transform _localTransform; diff --git a/Source/Engine/Physics/Actors/RigidBody.h b/Source/Engine/Physics/Actors/RigidBody.h index e7b929483..2ef50ca7a 100644 --- a/Source/Engine/Physics/Actors/RigidBody.h +++ b/Source/Engine/Physics/Actors/RigidBody.h @@ -30,14 +30,14 @@ protected: Float3 _centerOfMassOffset; RigidbodyConstraints _constraints; - int32 _enableSimulation : 1; - int32 _isKinematic : 1; - int32 _useCCD : 1; - int32 _enableGravity : 1; - int32 _startAwake : 1; - int32 _updateMassWhenScaleChanges : 1; - int32 _overrideMass : 1; - int32 _isUpdatingTransform : 1; + uint32 _enableSimulation : 1; + uint32 _isKinematic : 1; + uint32 _useCCD : 1; + uint32 _enableGravity : 1; + uint32 _startAwake : 1; + uint32 _updateMassWhenScaleChanges : 1; + uint32 _overrideMass : 1; + uint32 _isUpdatingTransform : 1; public: /// diff --git a/Source/Engine/Renderer/RenderList.h b/Source/Engine/Renderer/RenderList.h index 493f80101..a2cd48696 100644 --- a/Source/Engine/Renderer/RenderList.h +++ b/Source/Engine/Renderer/RenderList.h @@ -41,8 +41,8 @@ struct RendererDirectionalLightData StaticFlags StaticFlags; float IndirectLightingIntensity; int16 ShadowDataIndex = -1; - int8 CastVolumetricShadow : 1; - int8 RenderedVolumetricFog : 1; + uint8 CastVolumetricShadow : 1; + uint8 RenderedVolumetricFog : 1; float ShadowsDistance; int32 CascadeCount; @@ -86,9 +86,9 @@ struct RendererSpotLightData StaticFlags StaticFlags; int16 ShadowDataIndex = -1; - int8 CastVolumetricShadow : 1; - int8 RenderedVolumetricFog : 1; - int8 UseInverseSquaredFalloff : 1; + uint8 CastVolumetricShadow : 1; + uint8 RenderedVolumetricFog : 1; + uint8 UseInverseSquaredFalloff : 1; GPUTexture* IESTexture; Guid ID; @@ -124,9 +124,9 @@ struct RendererPointLightData StaticFlags StaticFlags; int16 ShadowDataIndex = -1; - int8 CastVolumetricShadow : 1; - int8 RenderedVolumetricFog : 1; - int8 UseInverseSquaredFalloff : 1; + uint8 CastVolumetricShadow : 1; + uint8 RenderedVolumetricFog : 1; + uint8 UseInverseSquaredFalloff : 1; GPUTexture* IESTexture; Guid ID; @@ -146,8 +146,8 @@ struct RendererSkyLightData float IndirectLightingIntensity; StaticFlags StaticFlags; - int8 CastVolumetricShadow : 1; - int8 RenderedVolumetricFog : 1; + uint8 CastVolumetricShadow : 1; + uint8 RenderedVolumetricFog : 1; CubeTexture* Image; Guid ID; diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index 35411f635..55cedecdb 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -1654,9 +1654,9 @@ bool InitHostfxr() const ::String csharpLibraryPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll"); const ::String csharpRuntimeConfigPath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.runtimeconfig.json"); if (!FileSystem::FileExists(csharpLibraryPath)) - LOG(Fatal, "Failed to initialize managed runtime, missing file: {0}", csharpLibraryPath); + LOG(Fatal, "Failed to initialize .NET runtime, missing file: {0}", csharpLibraryPath); if (!FileSystem::FileExists(csharpRuntimeConfigPath)) - LOG(Fatal, "Failed to initialize managed runtime, missing file: {0}", csharpRuntimeConfigPath); + LOG(Fatal, "Failed to initialize .NET runtime, missing file: {0}", csharpRuntimeConfigPath); const FLAX_CORECLR_STRING& libraryPath = FLAX_CORECLR_STRING(csharpLibraryPath); // Get path to hostfxr library @@ -1707,9 +1707,9 @@ bool InitHostfxr() Platform::OpenUrl(TEXT("https://dotnet.microsoft.com/en-us/download/dotnet/7.0")); #endif #if USE_EDITOR - LOG(Fatal, "Missing .NET 7 SDK installation required to run Flax Editor."); + LOG(Fatal, "Missing .NET 7 or later SDK installation required to run Flax Editor."); #else - LOG(Fatal, "Missing .NET 7 Runtime installation required to run this application."); + LOG(Fatal, "Missing .NET 7 or later Runtime installation required to run this application."); #endif return true; } @@ -1739,14 +1739,13 @@ bool InitHostfxr() return true; } - // TODO: Implement picking different version of hostfxr, currently prefers highest available version. - // Allow future and preview versions of .NET - String dotnetRollForward; + // TODO: Implement support for picking RC/beta updates of .NET runtime + // Uncomment for enabling support for upcoming .NET major release candidates +#if 0 String dotnetRollForwardPr; - if (Platform::GetEnvironmentVariable(TEXT("DOTNET_ROLL_FORWARD"), dotnetRollForward)) - Platform::SetEnvironmentVariable(TEXT("DOTNET_ROLL_FORWARD"), TEXT("LatestMajor")); if (Platform::GetEnvironmentVariable(TEXT("DOTNET_ROLL_FORWARD_TO_PRERELEASE"), dotnetRollForwardPr)) Platform::SetEnvironmentVariable(TEXT("DOTNET_ROLL_FORWARD_TO_PRERELEASE"), TEXT("1")); +#endif // Initialize hosting component const char_t* argv[1] = { libraryPath.Get() }; diff --git a/Source/Engine/Scripting/Script.h b/Source/Engine/Scripting/Script.h index 49cba0ec4..8cf1d0670 100644 --- a/Source/Engine/Scripting/Script.h +++ b/Source/Engine/Scripting/Script.h @@ -15,15 +15,15 @@ API_CLASS(Abstract) class FLAXENGINE_API Script : public SceneObject friend SceneTicking; friend class PrefabInstanceData; protected: - int32 _enabled : 1; - int32 _tickFixedUpdate : 1; - int32 _tickUpdate : 1; - int32 _tickLateUpdate : 1; - int32 _tickLateFixedUpdate : 1; - int32 _wasStartCalled : 1; - int32 _wasEnableCalled : 1; + uint16 _enabled : 1; + uint16 _tickFixedUpdate : 1; + uint16 _tickUpdate : 1; + uint16 _tickLateUpdate : 1; + uint16 _tickLateFixedUpdate : 1; + uint16 _wasStartCalled : 1; + uint16 _wasEnableCalled : 1; #if USE_EDITOR - int32 _executeInEditor : 1; + uint16 _executeInEditor : 1; #endif public: diff --git a/Source/Engine/Utilities/VariantUtils.cs b/Source/Engine/Utilities/VariantUtils.cs index 81520ae1b..8cccfb1ab 100644 --- a/Source/Engine/Utilities/VariantUtils.cs +++ b/Source/Engine/Utilities/VariantUtils.cs @@ -1,5 +1,11 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. +#if USE_LARGE_WORLDS +using Real = System.Double; +#else +using Real = System.Single; +#endif + using System; using System.Collections; using System.Collections.Generic; @@ -33,56 +39,56 @@ namespace FlaxEngine.Utilities if (typeof(T) == typeof(Vector2)) { if (value is Float2 asFloat2) - return (T)(object)new Vector2(asFloat2.X, asFloat2.Y); + return (T)(object)new Vector2((Real)asFloat2.X, (Real)asFloat2.Y); if (value is Float3 asFloat3) - return (T)(object)new Vector2(asFloat3.X, asFloat3.Y); + return (T)(object)new Vector2((Real)asFloat3.X, (Real)asFloat3.Y); if (value is Float4 asFloat4) - return (T)(object)new Vector2(asFloat4.X, asFloat4.Y); + return (T)(object)new Vector2((Real)asFloat4.X, (Real)asFloat4.Y); } else if (typeof(T) == typeof(Vector3)) { if (value is Float2 asFloat2) - return (T)(object)new Vector3(asFloat2.X, asFloat2.Y, 0); + return (T)(object)new Vector3((Real)asFloat2.X, (Real)asFloat2.Y, (Real)0); if (value is Float3 asFloat3) - return (T)(object)new Vector3(asFloat3.X, asFloat3.Y, asFloat3.Z); + return (T)(object)new Vector3((Real)asFloat3.X, (Real)asFloat3.Y, (Real)asFloat3.Z); if (value is Float4 asFloat4) - return (T)(object)new Vector3(asFloat4.X, asFloat4.Y, asFloat4.Z); + return (T)(object)new Vector3((Real)asFloat4.X, (Real)asFloat4.Y, (Real)asFloat4.Z); } else if (typeof(T) == typeof(Vector4)) { if (value is Float2 asFloat2) - return (T)(object)new Vector4(asFloat2.X, asFloat2.Y, 0, 0); + return (T)(object)new Vector4((Real)asFloat2.X, (Real)asFloat2.Y, (Real)0, (Real)0); if (value is Float3 asFloat3) - return (T)(object)new Vector4(asFloat3.X, asFloat3.Y, asFloat3.Z, 0); + return (T)(object)new Vector4((Real)asFloat3.X, (Real)asFloat3.Y, (Real)asFloat3.Z, (Real)0); if (value is Vector4 asFloat4) - return (T)(object)new Vector4(asFloat4.X, asFloat4.Y, asFloat4.Z, asFloat4.W); + return (T)(object)new Vector4((Real)asFloat4.X, (Real)asFloat4.Y, (Real)asFloat4.Z, (Real)asFloat4.W); } else if (typeof(T) == typeof(Float2)) { if (value is Vector2 asVector2) - return (T)(object)new Float2(asVector2.X, asVector2.Y); + return (T)(object)new Float2((float)asVector2.X, (float)asVector2.Y); if (value is Vector3 asVector3) - return (T)(object)new Float2(asVector3.X, asVector3.Y); + return (T)(object)new Float2((float)asVector3.X, (float)asVector3.Y); if (value is Vector4 asVector4) - return (T)(object)new Float2(asVector4.X, asVector4.Y); + return (T)(object)new Float2((float)asVector4.X, (float)asVector4.Y); } else if (typeof(T) == typeof(Float3)) { if (value is Vector2 asVector2) - return (T)(object)new Float3(asVector2.X, asVector2.Y, 0); + return (T)(object)new Float3((float)asVector2.X, (float)asVector2.Y, (float)0); if (value is Vector3 asVector3) - return (T)(object)new Float3(asVector3.X, asVector3.Y, asVector3.Z); + return (T)(object)new Float3((float)asVector3.X, (float)asVector3.Y, (float)asVector3.Z); if (value is Vector4 asFloat4) - return (T)(object)new Float3(asFloat4.X, asFloat4.Y, asFloat4.Z); + return (T)(object)new Float3((float)asFloat4.X, (float)asFloat4.Y, (float)asFloat4.Z); } else if (typeof(T) == typeof(Float4)) { if (value is Vector2 asVector2) - return (T)(object)new Float4(asVector2.X, asVector2.Y, 0, 0); + return (T)(object)new Float4((float)asVector2.X, (float)asVector2.Y, (float)0, (float)0); if (value is Vector3 asVector3) - return (T)(object)new Float4(asVector3.X, asVector3.Y, asVector3.Z, 0); + return (T)(object)new Float4((float)asVector3.X, (float)asVector3.Y, (float)asVector3.Z, (float)0); if (value is Vector4 asVector4) - return (T)(object)new Float4(asVector4.X, asVector4.Y, asVector4.Z, asVector4.W); + return (T)(object)new Float4((float)asVector4.X, (float)asVector4.Y, (float)asVector4.Z, (float)asVector4.W); } return (T)Convert.ChangeType(value, typeof(T)); } diff --git a/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json b/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json index 202425667..134a0ef98 100644 --- a/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json +++ b/Source/ThirdParty/nethost/FlaxEngine.CSharp.runtimeconfig.json @@ -3,7 +3,8 @@ "tfm": "net7.0", "framework": { "name": "Microsoft.NETCore.App", - "version": "7.0.0" + "version": "7.0.0", + "rollForward": "latestMajor" } } } diff --git a/Source/ThirdParty/pugixml/pugixml.cpp b/Source/ThirdParty/pugixml/pugixml.cpp index 56860bb90..c4d4ec845 100644 --- a/Source/ThirdParty/pugixml/pugixml.cpp +++ b/Source/ThirdParty/pugixml/pugixml.cpp @@ -3967,7 +3967,11 @@ PUGI__NS_BEGIN PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, int value) { char buf[128]; +#if __APPLE__ + snprintf(buf, sizeof(buf), "%d", value); +#else sprintf(buf, "%d", value); +#endif return set_value_buffer(dest, header, header_mask, buf); } @@ -3975,7 +3979,11 @@ PUGI__NS_BEGIN PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned int value) { char buf[128]; +#if __APPLE__ + snprintf(buf, sizeof(buf), "%u", value); +#else sprintf(buf, "%u", value); +#endif return set_value_buffer(dest, header, header_mask, buf); } @@ -3983,7 +3991,11 @@ PUGI__NS_BEGIN PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, float value) { char buf[128]; +#if __APPLE__ + snprintf(buf, sizeof(buf), "%.9g", value); +#else sprintf(buf, "%.9g", value); +#endif return set_value_buffer(dest, header, header_mask, buf); } @@ -3991,7 +4003,11 @@ PUGI__NS_BEGIN PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, double value) { char buf[128]; +#if __APPLE__ + snprintf(buf, sizeof(buf), "%.17g", value); +#else sprintf(buf, "%.17g", value); +#endif return set_value_buffer(dest, header, header_mask, buf); } @@ -4005,7 +4021,11 @@ PUGI__NS_BEGIN PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, long long value) { char buf[128]; +#if __APPLE__ + snprintf(buf, sizeof(buf), "%lld", value); +#else sprintf(buf, "%lld", value); +#endif return set_value_buffer(dest, header, header_mask, buf); } @@ -4013,7 +4033,11 @@ PUGI__NS_BEGIN PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, unsigned long long value) { char buf[128]; +#if __APPLE__ + snprintf(buf, sizeof(buf), "%llu", value); +#else sprintf(buf, "%llu", value); +#endif return set_value_buffer(dest, header, header_mask, buf); } diff --git a/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs b/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs index eff24dbf3..c2999999d 100644 --- a/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs +++ b/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs @@ -118,6 +118,11 @@ namespace Flax.Build /// public static Version MinimumVersion => new Version(7, 0); + /// + /// The maximum SDK version. + /// + public static Version MaximumVersion => new Version(8, 0); + /// public override TargetPlatform[] Platforms { @@ -245,21 +250,24 @@ namespace Flax.Build dotnetSdkVersions = GetVersions(Path.Combine(dotnetPath, "sdk")); if (dotnetRuntimeVersions == null) dotnetRuntimeVersions = GetVersions(Path.Combine(dotnetPath, "shared/Microsoft.NETCore.App")); - string dotnetSdkVersion = dotnetSdkVersions.OrderByDescending(ParseVersion).FirstOrDefault(); - string dotnetRuntimeVersion = dotnetRuntimeVersions.OrderByDescending(ParseVersion).FirstOrDefault(); + + dotnetSdkVersions = dotnetSdkVersions.OrderByDescending(ParseVersion); + dotnetRuntimeVersions = dotnetRuntimeVersions.OrderByDescending(ParseVersion); + + string dotnetSdkVersion = dotnetSdkVersions.FirstOrDefault(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major); + string dotnetRuntimeVersion = dotnetRuntimeVersions.FirstOrDefault(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major); if (string.IsNullOrEmpty(dotnetSdkVersion)) dotnetSdkVersion = dotnetPath; + if (dotnetSdkVersion == null && dotnetSdkVersions.Count() > 0) + { + Log.Warning($"Unsupported .NET SDK {dotnetSdkVersions.First()} version found. Minimum version required is .NET {MinimumVersion}."); + return; + } if (string.IsNullOrEmpty(dotnetSdkVersion) || string.IsNullOrEmpty(dotnetRuntimeVersion)) { Log.Warning("Missing .NET SDK"); return; } - int majorVersion = int.Parse(dotnetSdkVersion.Substring(0, dotnetSdkVersion.IndexOf("."))); - if (majorVersion < MinimumVersion.Major) - { - Log.Warning($"Unsupported .NET SDK {dotnetSdkVersion} version found. Minimum version required is .NET {MinimumVersion}."); - return; - } RootPath = dotnetPath; Version = ParseVersion(dotnetSdkVersion); VersionName = dotnetSdkVersion; @@ -452,8 +460,9 @@ namespace Flax.Build private static string GetVersion(IEnumerable versions) { - // TODO: reject 'future' versions like .Net 8? - return versions.OrderByDescending(ParseVersion).FirstOrDefault(); + return versions.OrderByDescending(ParseVersion) + .Where(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major) + .FirstOrDefault(); } private static string SearchForDotnetLocationLinux() diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs b/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs index 232b52ba0..f6df4068e 100644 --- a/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs +++ b/Source/Tools/Flax.Build/Build/NativeCpp/Builder.NativeCpp.cs @@ -641,7 +641,7 @@ namespace Flax.Build } } if (failed) - throw new Exception($"Failed to build target {target.Name}. See log."); + throw new BuildException($"Failed to build target {target.Name}. See log."); } else { @@ -702,7 +702,7 @@ namespace Flax.Build } } if (failed) - throw new Exception($"Failed to build target {target.Name}. See log."); + throw new BuildException($"Failed to build target {target.Name}. See log."); } else { diff --git a/Source/Tools/Flax.Build/Program.cs b/Source/Tools/Flax.Build/Program.cs index 5e7cf926c..d6a70de30 100644 --- a/Source/Tools/Flax.Build/Program.cs +++ b/Source/Tools/Flax.Build/Program.cs @@ -171,7 +171,9 @@ namespace Flax.Build } catch (Exception ex) { - Log.Exception(ex); + // Ignore exception logging for build errors + if (!(ex is BuildException)) + Log.Exception(ex); failed = true; } finally diff --git a/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs index 387a0dcff..77b7abf46 100644 --- a/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs +++ b/Source/Tools/Flax.Build/Projects/VisualStudio/CSSDKProjectGenerator.cs @@ -90,6 +90,11 @@ namespace Flax.Build.Projects.VisualStudio var baseConfiguration = project.Configurations.First(); var baseOutputDir = Utilities.MakePathRelativeTo(project.CSharp.OutputPath ?? baseConfiguration.TargetBuildOptions.OutputFolder, projectDirectory); var baseIntermediateOutputPath = Utilities.MakePathRelativeTo(project.CSharp.IntermediateOutputPath ?? Path.Combine(baseConfiguration.TargetBuildOptions.IntermediateFolder, "CSharp"), projectDirectory); + + bool isMainProject = Globals.Project.ProjectFolderPath == project.WorkspaceRootPath && project.Name != "BuildScripts" && (Globals.Project.Name != "Flax" || project.Name != "FlaxEngine"); + var flaxBuildTargetsFilename = isMainProject ? "Flax.Build.CSharp.targets" : "Flax.Build.CSharp.SkipBuild.targets"; + var cacheProjectsPath = Utilities.MakePathRelativeTo(Path.Combine(Globals.Root, "Cache", "Projects"), projectDirectory); + var flaxBuildTargetsPath = !string.IsNullOrEmpty(cacheProjectsPath) ? Path.Combine(cacheProjectsPath, flaxBuildTargetsFilename) : flaxBuildTargetsFilename; csProjectFileContent.AppendLine(" net7.0"); csProjectFileContent.AppendLine(" disable"); @@ -106,14 +111,14 @@ namespace Flax.Build.Projects.VisualStudio csProjectFileContent.AppendLine(" 11.0"); csProjectFileContent.AppendLine(" 512"); - // Needed for Hostfxr - csProjectFileContent.AppendLine(" true"); - csProjectFileContent.AppendLine(" true"); //csProjectFileContent.AppendLine(" false"); // TODO: use it to reduce burden of framework libs - // This needs to be set here to fix errors in VS - csProjectFileContent.AppendLine(string.Format(" {0}", baseOutputDir)); - csProjectFileContent.AppendLine(string.Format(" {0}", baseIntermediateOutputPath)); + // Custom .targets file for overriding MSBuild build tasks + csProjectFileContent.AppendLine(string.Format(" $(MSBuildThisFileDirectory){0}", flaxBuildTargetsPath)); + + // Hide annoying warnings during build + csProjectFileContent.AppendLine(" false"); + csProjectFileContent.AppendLine(" True"); csProjectFileContent.AppendLine(" "); csProjectFileContent.AppendLine(""); diff --git a/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs index 1ba8e6709..eda2f7a95 100644 --- a/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs +++ b/Source/Tools/Flax.Build/Projects/VisualStudio/VisualStudioProjectGenerator.cs @@ -518,7 +518,15 @@ namespace Flax.Build.Projects.VisualStudio else if (firstFullMatch != -1) { projectConfiguration = configuration; - build = solution.MainProject == project || (solution.MainProject == null && project.Name == solution.Name); + + // Always build the main project + build = solution.MainProject == project; + + // Build C# projects (needed for Rider solution wide analysis) + build |= project.Type == TargetType.DotNetCore; + + // Always build the project named after solution if main project was not set + build |= solution.MainProject == null && project.Name == solution.Name; } else if (firstPlatformMatch != -1 && !configuration.Name.StartsWith("Editor.")) { @@ -679,6 +687,57 @@ namespace Flax.Build.Projects.VisualStudio Utilities.WriteFileIfChanged(dotSettingsUserFilePath, dotSettingsFileContent.ToString()); } + + // Custom MSBuild .targets file to prevent building Flax C#-projects directly with MSBuild + { + var targetsFileContent = new StringBuilder(); + targetsFileContent.AppendLine(""); + targetsFileContent.AppendLine(" "); + targetsFileContent.AppendLine(" "); + targetsFileContent.AppendLine(""); + + Utilities.WriteFileIfChanged(Path.Combine(Globals.Root, "Cache", "Projects", "Flax.Build.CSharp.SkipBuild.targets"), targetsFileContent.ToString()); + } + + // Override MSBuild build tasks to run Flax.Build in C#-only projects + { + // Build command for the build tool + var buildToolPath = Path.ChangeExtension(Utilities.MakePathRelativeTo(typeof(Builder).Assembly.Location, Path.GetDirectoryName(solution.MainProject.Path)), null); + + var targetsFileContent = new StringBuilder(); + targetsFileContent.AppendLine(""); + targetsFileContent.AppendLine(" "); + targetsFileContent.AppendLine(" "); + AppendBuildToolCommands(targetsFileContent, "-build"); + targetsFileContent.AppendLine(" "); + targetsFileContent.AppendLine(" "); + AppendBuildToolCommands(targetsFileContent, "-rebuild"); + targetsFileContent.AppendLine(" "); + targetsFileContent.AppendLine(" "); + AppendBuildToolCommands(targetsFileContent, "-clean"); + targetsFileContent.AppendLine(" "); + targetsFileContent.AppendLine(""); + + Utilities.WriteFileIfChanged(Path.Combine(Globals.Root, "Cache", "Projects", "Flax.Build.CSharp.targets"), targetsFileContent.ToString()); + + void AppendBuildToolCommands(StringBuilder str, string extraArgs) + { + foreach (var configuration in solution.MainProject.Configurations) + { + var cmdLine = string.Format("{0} -log -mutex -workspace={1} -arch={2} -configuration={3} -platform={4} -buildTargets={5}", + FixPath(buildToolPath), + FixPath(solution.MainProject.WorkspaceRootPath), + configuration.Architecture, + configuration.Configuration, + configuration.Platform, + configuration.Target); + if (!string.IsNullOrEmpty(Configuration.Compiler)) + cmdLine += " -compiler=" + Configuration.Compiler; + + str.AppendLine(string.Format(" ", cmdLine, extraArgs, configuration.Name)); + } + } + } } /// @@ -716,5 +775,14 @@ namespace Flax.Build.Projects.VisualStudio projects.Add(project); } } + + private static string FixPath(string path) + { + if (path.Contains(' ')) + { + path = "\"" + path + "\""; + } + return path; + } } } diff --git a/Source/Tools/Flax.Build/Utilities/BuildException.cs b/Source/Tools/Flax.Build/Utilities/BuildException.cs new file mode 100644 index 000000000..5118c4154 --- /dev/null +++ b/Source/Tools/Flax.Build/Utilities/BuildException.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. + +using System; + +namespace Flax.Build +{ + internal class BuildException : Exception + { + public BuildException(string message) + : base(message) + { + } + } +}