Files
UnrealEngineUWP/Engine/Source/Programs/UnrealBuildTool/System/NativeProjects.cs
jake niman a3ae2a4770 Fix a few edge cases related to UBT project file detection for programs (especially those in the NotForLicensees directory)
* Default.uprojectdir's now contains NotForLicensees as a valid uproject search path
* Since programs uprojects are not found in the same directory as their .target.cs files, add a special exception for uprojects found in Programs dir that assumes any uproject for a program will have a .target.cs with the same name.

#jira UE-170080
#review-23132150 @josh.adams
#preflight 63daed6a3f006aee11b5e623
#preflight 63dbe49db61aac10880daa32

[CL 23971018 by jake niman in ue5-main branch]
2023-02-02 12:38:07 -05:00

83 lines
3.0 KiB
C#

// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EpicGames.Core;
using UnrealBuildBase;
using Microsoft.Extensions.Logging;
namespace UnrealBuildTool
{
/// <summary>
/// Utility functions for querying native projects (ie. those found via a .uprojectdirs query)
/// </summary>
public class NativeProjects : NativeProjectsBase
{
/// <summary>
/// Cached map of target names to the project file they belong to
/// </summary>
static Dictionary<string, FileReference>? CachedTargetNameToProjectFile;
/// <summary>
/// Clear our cached properties. Generally only needed if your script has modified local files...
/// </summary>
public static void ClearCache()
{
ClearCacheBase();
CachedTargetNameToProjectFile = null;
}
/// <summary>
/// Get the project folder for the given target name
/// </summary>
/// <param name="InTargetName">Name of the target of interest</param>
/// <param name="Logger">Logger for output</param>
/// <param name="OutProjectFileName">The project filename</param>
/// <returns>True if the target was found</returns>
public static bool TryGetProjectForTarget(string InTargetName, ILogger Logger, [NotNullWhen(true)] out FileReference? OutProjectFileName)
{
if(CachedTargetNameToProjectFile == null)
{
lock(LockObject)
{
if(CachedTargetNameToProjectFile == null)
{
Dictionary<string, FileReference> TargetNameToProjectFile = new Dictionary<string, FileReference>();
foreach(FileReference ProjectFile in EnumerateProjectFiles(Logger))
{
foreach (DirectoryReference ExtensionDir in Unreal.GetExtensionDirs(ProjectFile.Directory))
{
DirectoryReference SourceDirectory = DirectoryReference.Combine(ExtensionDir, "Source");
if (DirectoryLookupCache.DirectoryExists(SourceDirectory))
{
FindTargetFiles(SourceDirectory, TargetNameToProjectFile, ProjectFile);
}
DirectoryReference IntermediateSourceDirectory = DirectoryReference.Combine(ExtensionDir, "Intermediate", "Source");
if (DirectoryLookupCache.DirectoryExists(IntermediateSourceDirectory))
{
FindTargetFiles(IntermediateSourceDirectory, TargetNameToProjectFile, ProjectFile);
}
}
// Programs are a special case where the .uproject files are separated from the main project source code- in this case,
// we guarantee that a project under the Programs dir will always have an associated target file with the same name.
if (!TargetNameToProjectFile.ContainsKey(ProjectFile.GetFileNameWithoutAnyExtensions()) && ProjectFile.ContainsName("Programs", 0))
{
TargetNameToProjectFile.Add(ProjectFile.GetFileNameWithoutAnyExtensions(), ProjectFile);
}
}
CachedTargetNameToProjectFile = TargetNameToProjectFile;
}
}
}
return CachedTargetNameToProjectFile.TryGetValue(InTargetName, out OutProjectFileName);
}
}
}