diff --git a/Source/Editor/Cooker/CookingData.h b/Source/Editor/Cooker/CookingData.h index d155380e6..e91d9d6dc 100644 --- a/Source/Editor/Cooker/CookingData.h +++ b/Source/Editor/Cooker/CookingData.h @@ -194,7 +194,7 @@ public: API_FIELD(ReadOnly) String OriginalOutputPath; /// - /// The output path for data files (Content, Mono, etc.). + /// The output path for data files (Content, Dotnet, Mono, etc.). /// API_FIELD(ReadOnly) String DataOutputPath; @@ -306,13 +306,11 @@ public: /// /// Gets the absolute path to the Platform Data folder that contains the binary files used by the current build configuration. /// - /// The platform data folder path. String GetGameBinariesPath() const; /// /// Gets the absolute path to the platform folder that contains the dependency files used by the current build configuration. /// - /// The platform deps folder path. String GetPlatformBinariesRoot() const; public: diff --git a/Source/Editor/Cooker/Platform/Linux/LinuxPlatformTools.cpp b/Source/Editor/Cooker/Platform/Linux/LinuxPlatformTools.cpp index 8056f80dd..ec7b8e7e1 100644 --- a/Source/Editor/Cooker/Platform/Linux/LinuxPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Linux/LinuxPlatformTools.cpp @@ -34,6 +34,11 @@ ArchitectureType LinuxPlatformTools::GetArchitecture() const return ArchitectureType::x64; } +bool LinuxPlatformTools::UseSystemDotnet() const +{ + return true; +} + bool LinuxPlatformTools::OnDeployBinaries(CookingData& data) { const auto gameSettings = GameSettings::Get(); diff --git a/Source/Editor/Cooker/Platform/Linux/LinuxPlatformTools.h b/Source/Editor/Cooker/Platform/Linux/LinuxPlatformTools.h index 0215260d5..562b38962 100644 --- a/Source/Editor/Cooker/Platform/Linux/LinuxPlatformTools.h +++ b/Source/Editor/Cooker/Platform/Linux/LinuxPlatformTools.h @@ -18,6 +18,7 @@ public: const Char* GetName() const override; PlatformType GetPlatform() const override; ArchitectureType GetArchitecture() const override; + bool UseSystemDotnet() const override; bool OnDeployBinaries(CookingData& data) override; }; diff --git a/Source/Editor/Cooker/Platform/Mac/MacPlatformTools.cpp b/Source/Editor/Cooker/Platform/Mac/MacPlatformTools.cpp index 7bdc3d15f..f6df44ad9 100644 --- a/Source/Editor/Cooker/Platform/Mac/MacPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Mac/MacPlatformTools.cpp @@ -59,6 +59,11 @@ ArchitectureType MacPlatformTools::GetArchitecture() const return _arch; } +bool MacPlatformTools::UseSystemDotnet() const +{ + return true; +} + bool MacPlatformTools::IsNativeCodeFile(CookingData& data, const String& file) { String extension = FileSystem::GetExtension(file); diff --git a/Source/Editor/Cooker/Platform/Mac/MacPlatformTools.h b/Source/Editor/Cooker/Platform/Mac/MacPlatformTools.h index cca3ddc5e..21d9141e3 100644 --- a/Source/Editor/Cooker/Platform/Mac/MacPlatformTools.h +++ b/Source/Editor/Cooker/Platform/Mac/MacPlatformTools.h @@ -23,6 +23,7 @@ public: const Char* GetName() const override; PlatformType GetPlatform() const override; ArchitectureType GetArchitecture() const override; + bool UseSystemDotnet() const override; bool IsNativeCodeFile(CookingData& data, const String& file) override; void OnBuildStarted(CookingData& data) override; bool OnPostProcess(CookingData& data) override; diff --git a/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.cpp b/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.cpp index 81216e420..feca5c0a0 100644 --- a/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.cpp @@ -33,6 +33,11 @@ ArchitectureType WindowsPlatformTools::GetArchitecture() const return _arch; } +bool WindowsPlatformTools::UseSystemDotnet() const +{ + return true; +} + bool WindowsPlatformTools::OnDeployBinaries(CookingData& data) { const auto platformSettings = WindowsPlatformSettings::Get(); diff --git a/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.h b/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.h index 64b5b14af..5f03c9575 100644 --- a/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.h +++ b/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.h @@ -29,6 +29,7 @@ public: const Char* GetName() const override; PlatformType GetPlatform() const override; ArchitectureType GetArchitecture() const override; + bool UseSystemDotnet() const override; bool OnDeployBinaries(CookingData& data) override; void OnRun(CookingData& data, String& executableFile, String& commandLineFormat, String& workingDir) override; }; diff --git a/Source/Editor/Cooker/PlatformTools.h b/Source/Editor/Cooker/PlatformTools.h index 2c294f965..488519d16 100644 --- a/Source/Editor/Cooker/PlatformTools.h +++ b/Source/Editor/Cooker/PlatformTools.h @@ -24,36 +24,39 @@ public: /// /// Gets the name of the platform for UI and logging. /// - /// The name. virtual const Char* GetDisplayName() const = 0; /// /// Gets the name of the platform for filesystem cache directories, deps folder. /// - /// The name. virtual const Char* GetName() const = 0; /// /// Gets the type of the platform. /// - /// The platform type. virtual PlatformType GetPlatform() const = 0; /// /// Gets the architecture of the platform. /// - /// The architecture type. virtual ArchitectureType GetArchitecture() const = 0; /// - /// Gets the value indicating whenever platform requires AOT. + /// Gets the value indicating whenever platform requires AOT (needs C# assemblies to be precompiled). /// - /// True if platform uses AOT and needs C# assemblies to be precompiled, otherwise false. virtual bool UseAOT() const { return false; } + /// + /// Gets the value indicating whenever platform supports using system-installed .Net Runtime. + /// + virtual bool UseSystemDotnet() const + { + return false; + } + /// /// Gets the texture format that is supported by the platform for a given texture. /// diff --git a/Source/Editor/Cooker/Steps/DeployDataStep.cpp b/Source/Editor/Cooker/Steps/DeployDataStep.cpp index d50cb9f8a..ff3aaaee8 100644 --- a/Source/Editor/Cooker/Steps/DeployDataStep.cpp +++ b/Source/Editor/Cooker/Steps/DeployDataStep.cpp @@ -1,19 +1,22 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "DeployDataStep.h" +#include "Engine/Platform/File.h" #include "Engine/Platform/FileSystem.h" -#include "Editor/Cooker/PlatformTools.h" +#include "Engine/Core/Collections/Sorting.h" #include "Engine/Core/Config/BuildSettings.h" #include "Engine/Core/Config/GameSettings.h" #include "Engine/Renderer/ReflectionsPass.h" #include "Engine/Renderer/AntiAliasing/SMAA.h" #include "Engine/Engine/Globals.h" +#include "Editor/Cooker/PlatformTools.h" bool DeployDataStep::Perform(CookingData& data) { data.StepProgress(TEXT("Deploying engine data"), 0); const String depsRoot = data.GetPlatformBinariesRoot(); - const auto gameSettings = GameSettings::Get(); + const auto& gameSettings = *GameSettings::Get(); + const auto& buildSettings = *BuildSettings::Get(); // Setup output folders and copy required data const auto contentDir = data.DataOutputPath / TEXT("Content"); @@ -26,24 +29,24 @@ bool DeployDataStep::Perform(CookingData& data) Platform::Sleep(10); } FileSystem::CreateDirectory(contentDir); + const String dstMono = data.DataOutputPath / TEXT("Mono"); #if USE_NETCORE // TODO: Optionally copy all files needed for self-contained deployment { // Remove old Mono files - FileSystem::DeleteDirectory(data.DataOutputPath / TEXT("Mono")); + FileSystem::DeleteDirectory(dstMono); FileSystem::DeleteFile(data.DataOutputPath / TEXT("MonoPosixHelper.dll")); } #else - const auto srcMono = depsRoot / TEXT("Mono"); - const auto dstMono = data.DataOutputPath / TEXT("Mono"); if (!FileSystem::DirectoryExists(dstMono)) { + // Deploy Mono files (from platform data folder) + const String srcMono = depsRoot / TEXT("Mono"); if (!FileSystem::DirectoryExists(srcMono)) { data.Error(TEXT("Missing Mono runtime data files.")); return true; } - if (FileSystem::CopyDirectory(dstMono, srcMono, true)) { data.Error(TEXT("Failed to copy Mono runtime data files.")); @@ -51,6 +54,101 @@ bool DeployDataStep::Perform(CookingData& data) } } #endif + const String dstDotnet = data.DataOutputPath / TEXT("Dotnet"); + if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet()) + { + // Use system-installed .Net Runtime + FileSystem::DeleteDirectory(dstDotnet); + } + else + { + // Deploy .Net Runtime files + FileSystem::CreateDirectory(dstDotnet); + String srcDotnet = depsRoot / TEXT("Dotnet"); + if (FileSystem::DirectoryExists(srcDotnet)) + { + // Use prebuilt .Net installation for that platform + if (FileSystem::CopyDirectory(dstMono, srcDotnet, true)) + { + data.Error(TEXT("Failed to copy .Net runtime data files.")); + return true; + } + } + else + { + bool canUseSystemDotnet = false; + switch (data.Platform) + { + case BuildPlatform::Windows32: + case BuildPlatform::Windows64: + canUseSystemDotnet = PLATFORM_TYPE == PlatformType::Windows; + break; + case BuildPlatform::LinuxX64: + canUseSystemDotnet = PLATFORM_TYPE == PlatformType::Linux; + break; + case BuildPlatform::MacOSx64: + case BuildPlatform::MacOSARM64: + canUseSystemDotnet = PLATFORM_TYPE == PlatformType::Mac; + break; + } + if (!canUseSystemDotnet) + { + data.Error(TEXT("Missing .Net files for a target platform.")); + return true; + } + + // Ask Flax.Build to provide .Net SDK location for current platform (assuming there are no prebuilt dotnet files) + String sdks; + bool failed = ScriptsBuilder::RunBuildTool(TEXT("-log -printSDKs -logfile=SDKs.txt"), data.CacheDirectory); + failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks); + int32 idx = sdks.Find(TEXT("] DotNetSdk, "), StringSearchCase::CaseSensitive); + if (idx != -1) + { + idx = sdks.Find(TEXT(", "), StringSearchCase::CaseSensitive, idx + 14); + idx += 2; + int32 end = sdks.Find(TEXT("\n"), StringSearchCase::CaseSensitive, idx); + if (sdks[end] == '\r') + end--; + srcDotnet = String(sdks.Get() + idx, end - idx).TrimTrailing(); + } + if (failed || !FileSystem::DirectoryExists(srcDotnet)) + { + data.Error(TEXT("Failed to get .Net SDK location for a current platform.")); + return true; + } + + // Select version to use + Array versions; + FileSystem::GetChildDirectories(versions, srcDotnet / TEXT("host/fxr")); + if (versions.Count() == 0) + { + data.Error(TEXT("Failed to get .Net SDK location for a current platform.")); + return true; + } + for (String& version : versions) + { + version = StringUtils::GetFileName(version); + if (!version.StartsWith(TEXT("7."))) + version.Clear(); + } + Sorting::QuickSort(versions.Get(), versions.Count()); + const String version = versions.Last(); + LOG(Info, "Using .Net Runtime {} at {}", version, srcDotnet); + + // Deploy runtime files + FileSystem::CopyFile(dstDotnet / TEXT("LICENSE.TXT"), srcDotnet / TEXT("LICENSE.txt")); + FileSystem::CopyFile(dstDotnet / TEXT("LICENSE.TXT"), srcDotnet / TEXT("LICENSE.TXT")); + FileSystem::CopyFile(dstDotnet / TEXT("THIRD-PARTY-NOTICES.TXT"), srcDotnet / TEXT("ThirdPartyNotices.txt")); + FileSystem::CopyFile(dstDotnet / TEXT("THIRD-PARTY-NOTICES.TXT"), srcDotnet / TEXT("THIRD-PARTY-NOTICES.TXT")); + failed |= FileSystem::CopyDirectory(dstDotnet / TEXT("host/fxr") / version, srcDotnet / TEXT("host/fxr") / version, true); + failed |= FileSystem::CopyDirectory(dstDotnet / TEXT("shared/Microsoft.NETCore.App") / version, srcDotnet / TEXT("shared/Microsoft.NETCore.App") / version, true); + if (failed) + { + data.Error(TEXT("Failed to copy .Net runtime data files.")); + return true; + } + } + } // Deploy engine data for the target platform if (data.Tools->OnDeployBinaries(data)) @@ -91,7 +189,7 @@ bool DeployDataStep::Perform(CookingData& data) data.AddRootEngineAsset(TEXT("Engine/DefaultMaterial")); data.AddRootEngineAsset(TEXT("Engine/DefaultDeformableMaterial")); data.AddRootEngineAsset(TEXT("Engine/DefaultTerrainMaterial")); - if (!gameSettings->NoSplashScreen && !gameSettings->SplashScreen.IsValid()) + if (!gameSettings.NoSplashScreen && !gameSettings.SplashScreen.IsValid()) data.AddRootEngineAsset(TEXT("Engine/Textures/Logo")); data.AddRootEngineAsset(TEXT("Engine/Textures/NormalTexture")); data.AddRootEngineAsset(TEXT("Engine/Textures/BlackTexture")); @@ -121,7 +219,6 @@ bool DeployDataStep::Perform(CookingData& data) // Register game assets data.StepProgress(TEXT("Deploying game data"), 50); - auto& buildSettings = *BuildSettings::Get(); for (auto& e : buildSettings.AdditionalAssets) data.AddRootAsset(e.GetID()); for (auto& e : buildSettings.AdditionalScenes) diff --git a/Source/Engine/Core/Config/BuildSettings.h b/Source/Engine/Core/Config/BuildSettings.h index c2bbfa843..90fb3c144 100644 --- a/Source/Engine/Core/Config/BuildSettings.h +++ b/Source/Engine/Core/Config/BuildSettings.h @@ -13,37 +13,37 @@ /// API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API BuildSettings : public SettingsBase { -DECLARE_SCRIPTING_TYPE_MINIMAL(BuildSettings); -public: + DECLARE_SCRIPTING_TYPE_MINIMAL(BuildSettings); +public: /// /// The maximum amount of assets to include into a single assets package. Asset packages will split into several packages if need to. /// - API_FIELD(Attributes="EditorOrder(10), DefaultValue(4096), Limit(1, ushort.MaxValue), EditorDisplay(\"General\", \"Max assets per package\")") + API_FIELD(Attributes="EditorOrder(10), Limit(1, ushort.MaxValue), EditorDisplay(\"General\", \"Max assets per package\")") int32 MaxAssetsPerPackage = 4096; /// /// The maximum size of the single assets package (in megabytes). Asset packages will split into several packages if need to. /// - API_FIELD(Attributes="EditorOrder(20), DefaultValue(1024), Limit(1, ushort.MaxValue), EditorDisplay(\"General\", \"Max package size (in MB)\")") + API_FIELD(Attributes="EditorOrder(20), Limit(1, ushort.MaxValue), EditorDisplay(\"General\", \"Max package size (in MB)\")") int32 MaxPackageSizeMB = 1024; /// /// The game content cooking keycode. Use the same value for a game and DLC packages to support loading them by the build game. Use 0 to randomize it during building. /// - API_FIELD(Attributes="EditorOrder(30), DefaultValue(0), EditorDisplay(\"General\")") + API_FIELD(Attributes="EditorOrder(30), EditorDisplay(\"General\")") int32 ContentKey = 0; /// /// If checked, the builds produced by the Game Cooker will be treated as for final game distribution (eg. for game store upload). Builds done this way cannot be tested on console devkits (eg. Xbox One, Xbox Scarlett). /// - API_FIELD(Attributes="EditorOrder(40), DefaultValue(false), EditorDisplay(\"General\")") + API_FIELD(Attributes="EditorOrder(40), EditorDisplay(\"General\")") bool ForDistribution = false; /// /// If checked, the output build files won't be packaged for the destination platform. Useful when debugging build from local PC. /// - API_FIELD(Attributes="EditorOrder(50), DefaultValue(false), EditorDisplay(\"General\")") + API_FIELD(Attributes="EditorOrder(50), EditorDisplay(\"General\")") bool SkipPackaging = false; /// @@ -51,7 +51,7 @@ public: /// API_FIELD(Attributes="EditorOrder(1000), EditorDisplay(\"Additional Data\")") Array> AdditionalAssets; - + /// /// The list of additional scenes to include into build (into root assets set). /// @@ -67,17 +67,22 @@ public: /// /// Disables shaders compiler optimizations in cooked game. Can be used to debug shaders on a target platform or to speed up the shaders compilation time. /// - API_FIELD(Attributes="EditorOrder(2000), DefaultValue(false), EditorDisplay(\"Content\", \"Shaders No Optimize\")") + API_FIELD(Attributes="EditorOrder(2000), EditorDisplay(\"Content\", \"Shaders No Optimize\")") bool ShadersNoOptimize = false; /// /// Enables shader debug data generation for shaders in cooked game (depends on the target platform rendering backend). /// - API_FIELD(Attributes="EditorOrder(2010), DefaultValue(false), EditorDisplay(\"Content\")") + API_FIELD(Attributes="EditorOrder(2010), EditorDisplay(\"Content\")") bool ShadersGenerateDebugData = false; -public: + /// + /// If checked, .NET 7 Runtime won't be packaged with a game and will be required by user to be installed on system upon running game build. Available only on supported platforms such as Windows, Linux and macOS. + /// + API_FIELD(Attributes="EditorOrder(3000), EditorDisplay(\"Scripting\", \"Skip .NET Runtime Packaging\")") + bool SkipDotnetPackaging = false; +public: /// /// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use. /// @@ -95,5 +100,6 @@ public: DESERIALIZE(AdditionalAssetFolders); DESERIALIZE(ShadersNoOptimize); DESERIALIZE(ShadersGenerateDebugData); + DESERIALIZE(SkipDotnetPackaging); } }; diff --git a/Source/Engine/Scripting/DotNet/CoreCLR.cpp b/Source/Engine/Scripting/DotNet/CoreCLR.cpp index da5b74860..ecc3a8229 100644 --- a/Source/Engine/Scripting/DotNet/CoreCLR.cpp +++ b/Source/Engine/Scripting/DotNet/CoreCLR.cpp @@ -1,13 +1,15 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "CoreCLR.h" + #if USE_NETCORE #include "Engine/Core/Log.h" #include "Engine/Platform/Platform.h" #include "Engine/Platform/FileSystem.h" #include "Engine/Core/Types/DateTime.h" -#include "Engine/Debug/DebugLog.h" #include "Engine/Core/Collections/Dictionary.h" +#include "Engine/Debug/DebugLog.h" +#include "Engine/Engine/Globals.h" #include #include #include @@ -17,12 +19,8 @@ #undef LoadLibrary #endif -static Dictionary cachedFunctions; -#if PLATFORM_WINDOWS -static const char_t* typeName = TEXT("FlaxEngine.NativeInterop, FlaxEngine.CSharp"); -#else -static const char_t* typeName = "FlaxEngine.NativeInterop, FlaxEngine.CSharp"; -#endif +static Dictionary CachedFunctions; +static const char_t* NativeInteropTypeName = FLAX_CORECLR_TEXT("FlaxEngine.NativeInterop, FlaxEngine.CSharp"); hostfxr_initialize_for_runtime_config_fn hostfxr_initialize_for_runtime_config; hostfxr_initialize_for_dotnet_command_line_fn hostfxr_initialize_for_dotnet_command_line; @@ -42,21 +40,33 @@ bool CoreCLR::InitHostfxr(const String& configPath, const String& libraryPath) get_hostfxr_parameters get_hostfxr_params; get_hostfxr_params.size = sizeof(hostfxr_initialize_parameters); get_hostfxr_params.assembly_path = library_path.Get(); + FLAX_CORECLR_STRING dotnetRoot; // TODO: implement proper lookup for dotnet instalation folder and handle standalone build of FlaxGame #if PLATFORM_MAC get_hostfxr_params.dotnet_root = "/usr/local/share/dotnet"; #else get_hostfxr_params.dotnet_root = nullptr; +#endif +#if !USE_EDITOR + const String& bundledDotnetPath = Globals::ProjectFolder / TEXT("Dotnet"); + if (FileSystem::DirectoryExists(bundledDotnetPath)) + { + dotnetRoot = FLAX_CORECLR_STRING(bundledDotnetPath); +#if PLATFORM_WINDOWS_FAMILY + dotnetRoot.Replace('/', '\\'); +#endif + get_hostfxr_params.dotnet_root = dotnetRoot.Get(); + } #endif char_t hostfxrPath[1024]; size_t hostfxrPathSize = sizeof(hostfxrPath) / sizeof(char_t); int rc = get_hostfxr_path(hostfxrPath, &hostfxrPathSize, &get_hostfxr_params); if (rc != 0) { - LOG(Error, "Failed to find hostfxr: {0:x}", (unsigned int)rc); + LOG(Error, "Failed to find hostfxr: {0:x} ({1})", (unsigned int)rc, String(get_hostfxr_params.dotnet_root)); return true; } - const String path(hostfxrPath); + String path(hostfxrPath); LOG(Info, "Found hostfxr in {0}", path); // Get API from hostfxr library @@ -84,12 +94,15 @@ bool CoreCLR::InitHostfxr(const String& configPath, const String& libraryPath) hostfxr_initialize_parameters init_params; init_params.size = sizeof(hostfxr_initialize_parameters); init_params.host_path = library_path.Get(); - init_params.dotnet_root = nullptr;//dotnetRoot.Get(); // This probably must be set + path = String(StringUtils::GetDirectoryName(path)) / TEXT("/../../../"); + StringUtils::PathRemoveRelativeParts(path); + dotnetRoot = FLAX_CORECLR_STRING(path); + init_params.dotnet_root = dotnetRoot.Get(); hostfxr_handle handle = nullptr; rc = hostfxr_initialize_for_dotnet_command_line(ARRAY_COUNT(argv), argv, &init_params, &handle); if (rc != 0 || handle == nullptr) { - LOG(Error, "Failed to initialize hostfxr: {0:x}", (unsigned int)rc); + LOG(Error, "Failed to initialize hostfxr: {0:x} ({1})", (unsigned int)rc, String(init_params.dotnet_root)); hostfxr_close(handle); return true; } @@ -111,15 +124,14 @@ bool CoreCLR::InitHostfxr(const String& configPath, const String& libraryPath) void* CoreCLR::GetStaticMethodPointer(const String& methodName) { void* fun; - if (cachedFunctions.TryGet(methodName, fun)) + if (CachedFunctions.TryGet(methodName, fun)) return fun; - int rc = get_function_pointer(typeName, FLAX_CORECLR_STRING(methodName).Get(), UNMANAGEDCALLERSONLY_METHOD, nullptr, nullptr, &fun); + int rc = get_function_pointer(NativeInteropTypeName, FLAX_CORECLR_STRING(methodName).Get(), UNMANAGEDCALLERSONLY_METHOD, nullptr, nullptr, &fun); if (rc != 0) LOG(Fatal, "Failed to get unmanaged function pointer for method {0}: 0x{1:x}", methodName.Get(), (unsigned int)rc); - cachedFunctions.Add(methodName, fun); - + CachedFunctions.Add(methodName, fun); return fun; } diff --git a/Source/Engine/Scripting/DotNet/CoreCLR.h b/Source/Engine/Scripting/DotNet/CoreCLR.h index 5fe2b8691..97343e7bd 100644 --- a/Source/Engine/Scripting/DotNet/CoreCLR.h +++ b/Source/Engine/Scripting/DotNet/CoreCLR.h @@ -11,9 +11,11 @@ #if defined(_WIN32) #define CORECLR_DELEGATE_CALLTYPE __stdcall #define FLAX_CORECLR_STRING String +#define FLAX_CORECLR_TEXT(x) TEXT(x) #else #define CORECLR_DELEGATE_CALLTYPE #define FLAX_CORECLR_STRING StringAnsi +#define FLAX_CORECLR_TEXT(x) x #endif /// @@ -56,8 +58,8 @@ public: static void Free(void* ptr); static MGCHandle NewGCHandle(void* obj, bool pinned); static MGCHandle NewGCHandleWeakref(void* obj, bool track_resurrection); - static void* GetGCHandleTarget(const MGCHandle& MGCHandle); - static void FreeGCHandle(const MGCHandle& MGCHandle); + static void* GetGCHandleTarget(const MGCHandle& handle); + static void FreeGCHandle(const MGCHandle& handle); static bool HasCustomAttribute(void* klass, void* attribClass); static bool HasCustomAttribute(void* klass); diff --git a/Source/Engine/Scripting/DotNet/MonoApi.cpp b/Source/Engine/Scripting/DotNet/MonoApi.cpp index b8ac4db28..ddb62ebaa 100644 --- a/Source/Engine/Scripting/DotNet/MonoApi.cpp +++ b/Source/Engine/Scripting/DotNet/MonoApi.cpp @@ -606,15 +606,15 @@ MGCHandle CoreCLR::NewGCHandleWeakref(void* obj, bool track_resurrection) return (MGCHandle)CoreCLR::CallStaticMethod(NewGCHandleWeakrefPtr, obj, track_resurrection); } -void* CoreCLR::GetGCHandleTarget(const MGCHandle& MGCHandle) +void* CoreCLR::GetGCHandleTarget(const MGCHandle& handle) { - return (void*)MGCHandle; + return (void*)handle; } -void CoreCLR::FreeGCHandle(const MGCHandle& MGCHandle) +void CoreCLR::FreeGCHandle(const MGCHandle& handle) { static void* FreeGCHandlePtr = CoreCLR::GetStaticMethodPointer(TEXT("FreeGCHandle")); - CoreCLR::CallStaticMethod(FreeGCHandlePtr, (void*)MGCHandle); + CoreCLR::CallStaticMethod(FreeGCHandlePtr, (void*)handle); } const char* CoreCLR::GetClassFullname(void* klass) diff --git a/Source/Tools/Flax.Build/Deps/Dependencies/nethost.cs b/Source/Tools/Flax.Build/Deps/Dependencies/nethost.cs index 11533852c..c8598fd68 100644 --- a/Source/Tools/Flax.Build/Deps/Dependencies/nethost.cs +++ b/Source/Tools/Flax.Build/Deps/Dependencies/nethost.cs @@ -180,7 +180,7 @@ namespace Flax.Deps.Dependencies { Utilities.FileCopy(Path.Combine(srcHostRuntime, file), Path.Combine(dstBinaries, file)); } - var dstDotnet = Path.Combine(dstBinaries, "Dotnet"); + var dstDotnet = Path.Combine(GetBinariesFolder(options, targetPlatform), "Dotnet"); var dstClassLibrary = Path.Combine(dstDotnet, "shared", "Microsoft.NETCore.App", version); SetupDirectory(dstClassLibrary, true); foreach (var file in new[]