Files
FlaxEngine/Source/Editor/Cooker/Steps/PrecompileAssembliesStep.cpp

88 lines
4.1 KiB
C++

// Copyright (c) Wojciech Figat. All rights reserved.
#include "PrecompileAssembliesStep.h"
#include "Engine/Platform/FileSystem.h"
#include "Engine/Platform/File.h"
#include "Engine/Core/Config/BuildSettings.h"
#include "Engine/Engine/Globals.h"
#include "Editor/Scripting/ScriptsBuilder.h"
#include "Editor/Cooker/PlatformTools.h"
#include "Editor/Utilities/EditorUtilities.h"
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
{
const DotNetAOTModes aotMode = data.Tools->UseAOT();
if (aotMode == DotNetAOTModes::None)
return;
const auto& buildSettings = *BuildSettings::Get();
// Redirect C# assemblies to intermediate cooking directory (processed by ILC)
data.ManagedCodeOutputPath = data.CacheDirectory / TEXT("AOTAssemblies");
// Reset any AOT cache from previous run if the AOT mode has changed (eg. Mono AOT -> ILC on Desktop)
const String aotModeCacheFilePath = data.ManagedCodeOutputPath / TEXT("AOTMode.txt");
String aotModeCacheValue = String::Format(TEXT("{};{};{};{}"),
(int32)aotMode,
(int32)data.Configuration,
(int32)buildSettings.SkipUnusedDotnetLibsPackaging,
FileSystem::GetFileLastEditTime(ScriptsBuilder::GetBuildToolPath()).Ticks);
for (const String& define : data.CustomDefines)
aotModeCacheValue += define;
if (FileSystem::DirectoryExists(data.ManagedCodeOutputPath))
{
String cachedData;
File::ReadAllText(aotModeCacheFilePath, cachedData);
if (cachedData != aotModeCacheValue)
{
LOG(Info, "AOT cache invalidation");
FileSystem::DeleteDirectory(data.ManagedCodeOutputPath); // Remove AOT cache
FileSystem::DeleteDirectory(data.DataOutputPath / TEXT("Dotnet")); // Remove deployed Dotnet libs (be sure to remove any leftovers from previous build)
}
}
if (!FileSystem::DirectoryExists(data.ManagedCodeOutputPath))
{
FileSystem::CreateDirectory(data.ManagedCodeOutputPath);
File::WriteAllText(aotModeCacheFilePath, aotModeCacheValue, Encoding::ANSI);
}
}
bool PrecompileAssembliesStep::Perform(CookingData& data)
{
const DotNetAOTModes aotMode = data.Tools->UseAOT();
if (aotMode == DotNetAOTModes::None)
return false;
const auto& buildSettings = *BuildSettings::Get();
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
return false;
LOG(Info, "Using AOT...");
const String infoMsg = TEXT("Running AOT");
data.StepProgress(infoMsg, 0);
// Override Newtonsoft.Json with AOT-version (one that doesn't use System.Reflection.Emit)
EditorUtilities::CopyFileIfNewer(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.dll"), Globals::StartupFolder / TEXT("Source/Platforms/DotNet/AOT/Newtonsoft.Json.dll"));
FileSystem::DeleteFile(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.xml"));
FileSystem::DeleteFile(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.pdb"));
// Run AOT by Flax.Build (see DotNetAOT)
const Char *platform, *architecture, *configuration = ::ToString(data.Configuration);
data.GetBuildPlatformName(platform, architecture);
const String logFile = data.CacheDirectory / TEXT("AOTLog.txt");
String args = String::Format(
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\" {}"),
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath, data.GetDotnetCommandArg());
if (!buildSettings.SkipUnusedDotnetLibsPackaging)
args += TEXT(" -skipUnusedDotnetLibs=false"); // Run AOT on whole class library (not just used libs)
for (const String& define : data.CustomDefines)
{
args += TEXT(" -D");
args += define;
}
if (ScriptsBuilder::RunBuildTool(args))
{
data.Error(TEXT("Failed to precompile game scripts."));
return true;
}
return false;
}