// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using EpicGames.Core;
using Microsoft.Extensions.Logging;
namespace UnrealBuildTool
{
///
/// Base class for platform-specific project generators
///
abstract class PlatformProjectGenerator
{
public static readonly string DefaultPlatformConfigurationType = "Makefile";
protected readonly ILogger Logger;
///
/// Constructor
///
/// Command line arguments passed to the project generator
/// Logger for output
public PlatformProjectGenerator(CommandLineArguments Arguments, ILogger Logger)
{
this.Logger = Logger;
}
///
/// Register the platform with the UEPlatformProjectGenerator class
///
public abstract IEnumerable GetPlatforms();
public virtual void GenerateGameProjectStub(ProjectFileGenerator InGenerator, string InTargetName, string InTargetFilepath, TargetRules InTargetRules,
List InPlatforms, List InConfigurations)
{
// Do nothing
}
public virtual void GenerateGameProperties(UnrealTargetConfiguration Configuration, StringBuilder VCProjectFileContent, TargetType TargetType, DirectoryReference RootDirectory, FileReference TargetFilePath)
{
// Do nothing
}
public virtual bool RequiresVSUserFileGeneration()
{
return false;
}
ConcurrentDictionary FoundVSISupportDict = new();
public struct VSSettings
{
public UnrealTargetPlatform Platform;
public UnrealTargetConfiguration Configuration = UnrealTargetConfiguration.Development;
public VCProjectFileFormat ProjectFileFormat = VCProjectFileFormat.Default;
public UnrealArch? Architecture = null;
public VSSettings(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, VCProjectFileFormat InProjectFileFormat, UnrealArch? InArchitecture)
{
Platform = InPlatform;
Configuration = InConfiguration;
ProjectFileFormat = InProjectFileFormat;
Architecture = InArchitecture;
}
};
///
/// Checks the local VS install directories to see if the platform is supported.
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// bool true if native VisualStudio support (or custom VSI) is available
public virtual bool HasVisualStudioSupport(VSSettings InVSSettings)
{
int HashResult = 691;
HashResult *= InVSSettings.Platform.ToString().GetHashCode();
HashResult *= InVSSettings.Configuration.ToString().GetHashCode();
HashResult *= InVSSettings.ProjectFileFormat.ToString().GetHashCode();
HashResult *= InVSSettings.Architecture != null ? InVSSettings.Architecture.ToString()!.GetHashCode() : 1;
return FoundVSISupportDict.GetOrAdd(HashResult, _ =>
{
WindowsCompiler VSCompiler;
string VCVersion;
switch (InVSSettings.ProjectFileFormat)
{
case VCProjectFileFormat.VisualStudio2019:
VSCompiler = WindowsCompiler.VisualStudio2019;
VCVersion = "v160";
break;
case VCProjectFileFormat.VisualStudio2022:
VSCompiler = WindowsCompiler.VisualStudio2022;
VCVersion = "v170";
break;
default:
// Unknown VS Version
return false;
}
IEnumerable? InstallDirs = WindowsPlatform.TryGetVSInstallDirs(VSCompiler, Logger);
if (InstallDirs != null)
{
foreach (DirectoryReference VSInstallDir in InstallDirs)
{
DirectoryReference PlatformsPath = new DirectoryReference(System.IO.Path.Combine(VSInstallDir.FullName, "MSBuild\\Microsoft\\VC\\", VCVersion, "Platforms", GetVisualStudioPlatformName(InVSSettings)));
if (DirectoryReference.Exists(PlatformsPath))
{
return true;
}
}
}
return false;
});
}
///
/// Return the VisualStudio platform name for this build platform
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// string The name of the platform that VisualStudio recognizes
public virtual string GetVisualStudioPlatformName(VSSettings InVSSettings)
{
// By default, return the platform string
return InVSSettings.Platform.ToString();
}
///
/// Return whether we need a distinct platform name - for cases where there are two targets of the same VS solution platform
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// bool
public virtual bool RequiresDistinctVisualStudioConfigurationName(VSSettings InVSSettings)
{
return false;
}
///
/// Return project configuration settings that must be included before the default props file for all configurations
///
/// The UnrealTargetPlatform being built
/// String builder for the project file
/// string The custom configuration section for the project file; Empty string if it doesn't require one
public virtual void GetVisualStudioPreDefaultString(UnrealTargetPlatform InPlatform, StringBuilder ProjectFileBuilder)
{
}
///
/// Return project configuration settings that must be included before the default props file
///
/// The UnrealTargetPlatform being built
/// The UnrealTargetConfiguration being built
/// String builder for the project file
/// string The custom configuration section for the project file; Empty string if it doesn't require one
public virtual void GetVisualStudioPreDefaultString(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, StringBuilder ProjectFileBuilder)
{
}
///
/// Return the platform toolset string to write into the project configuration
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// String builder for the project file
/// string The custom configuration section for the project file; Empty string if it doesn't require one
public virtual void GetVisualStudioPlatformToolsetString(VSSettings InVSSettings, StringBuilder ProjectFileBuilder)
{
}
///
/// Return any custom property group lines
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// String builder for the project file
/// string The custom property import lines for the project file; Empty string if it doesn't require one
public virtual void GetAdditionalVisualStudioPropertyGroups(VSSettings InVSSettings, StringBuilder ProjectFileBuilder)
{
}
///
/// Return any custom property group lines
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// string The platform configuration type. Defaults to "Makefile" unless overridden
public virtual string GetVisualStudioPlatformConfigurationType(VSSettings InVSSettings)
{
return DefaultPlatformConfigurationType;
}
///
/// Return any custom paths for VisualStudio this platform requires
/// This include ReferencePath, LibraryPath, LibraryWPath, IncludePath and ExecutablePath.
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// The type of target (game or program)
/// Path to the .target.cs file
///
///
/// String builder for the project file
/// The custom path lines for the project file; Empty string if it doesn't require one
public virtual void GetVisualStudioPathsEntries(VSSettings InVSSettings, TargetType TargetType, FileReference TargetRulesPath, FileReference ProjectFilePath, FileReference NMakeOutputPath, StringBuilder ProjectFileBuilder)
{
}
///
/// Return any custom property settings. These will be included in the ImportGroup section
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// String builder for the project file
/// string The custom property import lines for the project file; Empty string if it doesn't require one
public virtual void GetVisualStudioImportGroupProperties(VSSettings InVSSettings, StringBuilder ProjectFileBuilder)
{
}
///
/// Return any custom property settings. These will be included right after Global properties to make values available to all other imports.
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// String builder for the project file
/// string The custom property import lines for the project file; Empty string if it doesn't require one
public virtual void GetVisualStudioGlobalProperties(VSSettings InVSSettings, StringBuilder ProjectFileBuilder)
{
}
///
/// Return any custom target overrides. These will be included last in the project file so they have the opportunity to override any existing settings.
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// String builder for the project file
/// string The custom property import lines for the project file; Empty string if it doesn't require one
public virtual void GetVisualStudioTargetOverrides(VSSettings InVSSettings, StringBuilder ProjectFileBuilder)
{
}
///
/// Return any custom layout directory sections
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
///
/// The type of target (game or program)
///
///
///
/// string The custom property import lines for the project file; Empty string if it doesn't require one
public virtual string GetVisualStudioLayoutDirSection(VSSettings InVSSettings, string InConditionString, TargetType TargetType, FileReference TargetRulesPath, FileReference ProjectFilePath, FileReference NMakeOutputPath)
{
return "";
}
///
/// Get the output manifest section, if required
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// The type of the target being built
/// Path to the .target.cs file
/// Path to the project file
/// The output manifest section for the project file; Empty string if it doesn't require one
public virtual string GetVisualStudioOutputManifestSection(VSSettings InVSSettings, TargetType TargetType, FileReference TargetRulesPath, FileReference ProjectFilePath)
{
return "";
}
///
/// Get whether this platform deploys
///
/// bool true if the 'Deploy' option should be enabled
public virtual bool GetVisualStudioDeploymentEnabled(VSSettings InVSSettings)
{
return false;
}
///
/// Get the text to insert into the user file for the given platform/configuration/target
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// The condition string
/// The target rules
/// The target rules path
/// The project file path
/// The string to append to the user file
public virtual string GetVisualStudioUserFileStrings(VSSettings InVSSettings,
string InConditionString, TargetRules InTargetRules, FileReference TargetRulesPath, FileReference ProjectFilePath)
{
return "";
}
///
/// Get the text to insert into the user file for the given platform/configuration/target
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
/// The condition string
/// The target rules
/// The target rules path
/// The project file path
/// The name of the project
/// Path to foreign .uproject file, if any
/// The string to append to the user file
public virtual string GetVisualStudioUserFileStrings(VSSettings InVSSettings,
string InConditionString, TargetRules InTargetRules, FileReference TargetRulesPath, FileReference ProjectFilePath, string ProjectName, string? ForeignUProjectPath)
{
return GetVisualStudioUserFileStrings(InVSSettings, InConditionString, InTargetRules, TargetRulesPath, ProjectFilePath);
}
///
/// For Additional Project Property files that need to be written out. This is currently used only on Android.
///
public virtual void WriteAdditionalPropFile()
{
}
///
/// For additional Project files (ex. *PROJECTNAME*-AndroidRun.androidproj.user) that needs to be written out. This is currently used only on Android.
///
/// Project file this will be related to
public virtual void WriteAdditionalProjUserFile(ProjectFile ProjectFile)
{
}
///
/// For additional Project files (ex. *PROJECTNAME*-AndroidRun.androidproj) that needs to be written out. This is currently used only on Android.
///
/// Project file this will be related to
/// Project file written out, Solution folder it should be put in
public virtual Tuple? WriteAdditionalProjFile(ProjectFile ProjectFile)
{
return null;
}
///
/// Gets the text to insert into the UnrealVS configuration file
///
public virtual void GetUnrealVSConfigurationEntries(StringBuilder UnrealVSContent)
{
}
///
/// Gets the text to insert into the Project files as additional build arguments for given platform/configuration
///
/// The ProjectFileSettings that contains the project platform/configuration/etc info being built
public virtual string GetExtraBuildArguments(VSSettings InVSSettings)
{
return "";
}
///
/// Indicates whether this generator will be emitting additional build targets.
/// Functionally, it's fine to return true and not return any additional text in GetVisualStudioTargetsString, but doing
/// so may incur additional cost of preparing data for generation.
///
/// The platform being added
/// True if Targets will be generate, false otherwise. If true is returned, GetVisualStudioTargetsString will be called next.
///
public virtual bool HasVisualStudioTargets(UnrealTargetPlatform InPlatform)
{
return false;
}
///
/// Get the text to insert into the Project files as additional build targets for the given platform.
///
/// The platform being added
/// List of build configurations for the platform
/// String builder for the project file
public virtual void GetVisualStudioTargetsString(UnrealTargetPlatform InPlatform, List InPlatformConfigurations, StringBuilder ProjectFileBuilder)
{
}
}
}