UProjectInfo(FileReference InFilePath, bool bInIsCodeProject) { GameName = InFilePath.GetFileNameWithoutExtension(); FileName = InFilePath.GetFileName(); FilePath = InFilePath; Folder = FilePath.Directory; bIsCodeProject = bInIsCodeProject; }
private static void GenerateTempTarget(FileReference RawProjectPath) { DirectoryReference TempDir = DirectoryReference.Combine(RawProjectPath.Directory, "Intermediate", "Source"); DirectoryReference.CreateDirectory(TempDir); // Get the project name for use in temporary files string ProjectName = RawProjectPath.GetFileNameWithoutExtension(); // Create a target.cs file FileReference TargetLocation = FileReference.Combine(TempDir, ProjectName + ".Target.cs"); using (StreamWriter Writer = new StreamWriter(TargetLocation.FullName)) { Writer.WriteLine("using UnrealBuildTool;"); Writer.WriteLine(); Writer.WriteLine("public class {0}Target : TargetRules", ProjectName); Writer.WriteLine("{"); Writer.WriteLine("\tpublic {0}Target(TargetInfo Target) : base(Target)", ProjectName); Writer.WriteLine("\t{"); Writer.WriteLine("\t\tType = TargetType.Game;"); Writer.WriteLine("\t\tExtraModuleNames.Add(\"{0}\");", ProjectName); Writer.WriteLine("\t}"); Writer.WriteLine("}"); } // Create a build.cs file FileReference ModuleLocation = FileReference.Combine(TempDir, ProjectName + ".Build.cs"); using (StreamWriter Writer = new StreamWriter(ModuleLocation.FullName)) { Writer.WriteLine("using UnrealBuildTool;"); Writer.WriteLine(); Writer.WriteLine("public class {0} : ModuleRules", ProjectName); Writer.WriteLine("{"); Writer.WriteLine("\tpublic {0}(ReadOnlyTargetRules Target) : base(Target)", ProjectName); Writer.WriteLine("\t{"); Writer.WriteLine("\t\tPCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;"); Writer.WriteLine(); Writer.WriteLine("\t\tPrivateDependencyModuleNames.Add(\"Core\");"); Writer.WriteLine("\t\tPrivateDependencyModuleNames.Add(\"Core\");"); Writer.WriteLine("\t}"); Writer.WriteLine("}"); } // Create a main module cpp file FileReference SourceFileLocation = FileReference.Combine(TempDir, ProjectName + ".cpp"); using (StreamWriter Writer = new StreamWriter(SourceFileLocation.FullName)) { Writer.WriteLine("#include \"CoreTypes.h\""); Writer.WriteLine("#include \"Modules/ModuleManager.h\""); Writer.WriteLine(); Writer.WriteLine("IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultModuleImpl, {0}, \"{0}\");", ProjectName); } }
public BranchUProject(FileReference ProjectFile) { GameName = ProjectFile.GetFileNameWithoutExtension(); //not sure what the heck this path is relative to FilePath = ProjectFile; if (!CommandUtils.FileExists_NoExceptions(FilePath.FullName)) { throw new AutomationException("Could not resolve relative path corrctly {0} -> {1} which doesn't exist.", ProjectFile, FilePath); } }
protected void InitBuildSource(FileReference InProjectPath, DirectoryReference InUnrealPath, bool InUsesSharedBuildType, string InBuildArgument, Func <string, string> ResolutionDelegate) { UnrealPath = InUnrealPath; UsesSharedBuildType = InUsesSharedBuildType; ProjectPath = InProjectPath; ProjectName = InProjectPath.GetFileNameWithoutExtension(); // Resolve the build argument into something meaningful string ResolvedBuildName; IEnumerable <string> ResolvedPaths = null; if (!ResolveBuildReference(InBuildArgument, ResolutionDelegate, out ResolvedPaths, out ResolvedBuildName)) { throw new AutomationException("Unable to resolve {0} to a valid build", InBuildArgument); } BuildName = ResolvedBuildName; BuildPaths = ResolvedPaths; DiscoveredBuilds = DiscoverBuilds(); if (DiscoveredBuilds.Count() == 0) { throw new AutomationException("No builds were discovered from resolved build argument {0}", InBuildArgument); } // any Branch/CL info? Match M = Regex.Match(BuildName, @"(\+\+.+)-CL-(\d+)"); if (M.Success) { Branch = M.Groups[1].Value.Replace("+", "/"); Changelist = Convert.ToInt32(M.Groups[2].Value); } else { Branch = ""; Changelist = 0; } // allow user overrides (TODO - centralize all this!) Branch = Globals.Params.ParseValue("branch", Branch); Changelist = Convert.ToInt32(Globals.Params.ParseValue("changelist", Changelist.ToString())); }
static void BackupLogFile(FileReference LogFile, TimeSpan RetentionSpan) { string LogPrefix = LogFile.GetFileNameWithoutExtension() + "-backup-"; string LogSuffix = LogFile.GetExtension(); if (FileReference.Exists(LogFile)) { string Timestamp = FileReference.GetLastWriteTime(LogFile).ToString("yyyy.MM.dd-HH.mm.ss"); string UniqueSuffix = ""; for (int NextSuffixIdx = 2; ; NextSuffixIdx++) { FileReference BackupLogFile = FileReference.Combine(LogFile.Directory, String.Format("{0}{1}{2}{3}", LogPrefix, Timestamp, UniqueSuffix, LogSuffix)); if (!FileReference.Exists(BackupLogFile)) { try { FileReference.Move(LogFile, BackupLogFile); } catch (Exception Ex) { Log.TraceWarning("Unable to backup {0} to {1} ({2})", LogFile, BackupLogFile, Ex.Message); Log.TraceLog(ExceptionUtils.FormatException(Ex)); } break; } UniqueSuffix = String.Format("_{0}", NextSuffixIdx); } } DateTime DeleteTime = DateTime.UtcNow - RetentionSpan; foreach (FileInfo File in new DirectoryInfo(LogFile.Directory.FullName).EnumerateFiles(LogPrefix + "*" + LogSuffix)) { if (File.LastWriteTimeUtc < DeleteTime) { File.Delete(); } } }
/// <summary> /// Return any custom paths for VisualStudio this platform requires /// This include ReferencePath, LibraryPath, LibraryWPath, IncludePath and ExecutablePath. /// </summary> /// <param name="InPlatform"> The UnrealTargetPlatform being built</param> /// <param name="TargetType"> The type of target (game or program)</param> /// <returns>string The custom path lines for the project file; Empty string if it doesn't require one</returns> public override string GetVisualStudioPathsEntries(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetRules.TargetType TargetType, FileReference TargetRulesPath, FileReference ProjectFilePath, FileReference NMakeOutputPath) { if (!IsNsightInstalled()) { return base.GetVisualStudioPathsEntries(InPlatform, InConfiguration, TargetType, TargetRulesPath, ProjectFilePath, NMakeOutputPath); } // NOTE: We are intentionally overriding defaults for these paths with empty strings. We never want Visual Studio's // defaults for these fields to be propagated, since they are version-sensitive paths that may not reflect // the environment that UBT is building in. We'll set these environment variables ourselves! // NOTE: We don't touch 'ExecutablePath' because that would result in Visual Studio clobbering the system "Path" // environment variable //@todo android: clean up debug path generation string GameName = TargetRulesPath.GetFileNameWithoutExtension(); GameName = Path.GetFileNameWithoutExtension(GameName); // intermediate path for Engine or Game's intermediate string IntermediateDirectoryPath; IntermediateDirectoryPath = Path.GetDirectoryName(NMakeOutputPath.FullName) + "/../../Intermediate/Android/APK"; // string for <OverrideAPKPath> string APKPath = Path.Combine( Path.GetDirectoryName(NMakeOutputPath.FullName), Path.GetFileNameWithoutExtension(NMakeOutputPath.FullName) + "-armv7-es2.apk"); // string for <BuildXmlPath> and <AndroidManifestPath> string BuildXmlPath = IntermediateDirectoryPath; string AndroidManifestPath = Path.Combine(IntermediateDirectoryPath, "AndroidManifest.xml"); // string for <AdditionalLibraryDirectories> string AdditionalLibDirs = ""; AdditionalLibDirs += IntermediateDirectoryPath + @"\obj\local\armeabi-v7a"; AdditionalLibDirs += ";" + IntermediateDirectoryPath + @"\obj\local\x86"; AdditionalLibDirs += @";$(AdditionalLibraryDirectories)"; string PathsLines = " <IncludePath />" + ProjectFileGenerator.NewLine + " <ReferencePath />" + ProjectFileGenerator.NewLine + " <LibraryPath />" + ProjectFileGenerator.NewLine + " <LibraryWPath />" + ProjectFileGenerator.NewLine + " <SourcePath />" + ProjectFileGenerator.NewLine + " <ExcludePath />" + ProjectFileGenerator.NewLine + " <AndroidAttach>False</AndroidAttach>" + ProjectFileGenerator.NewLine + " <DebuggerFlavor>AndroidDebugger</DebuggerFlavor>" + ProjectFileGenerator.NewLine + " <OverrideAPKPath>" + APKPath + "</OverrideAPKPath>" + ProjectFileGenerator.NewLine + " <AdditionalLibraryDirectories>" + AdditionalLibDirs + "</AdditionalLibraryDirectories>" + ProjectFileGenerator.NewLine + " <BuildXmlPath>" + BuildXmlPath + "</BuildXmlPath>" + ProjectFileGenerator.NewLine + " <AndroidManifestPath>" + AndroidManifestPath + "</AndroidManifestPath>" + ProjectFileGenerator.NewLine; return PathsLines; }
/// <summary> /// Gets the default location to stage an input file /// </summary> /// <param name="InputFile">Location of the file in the file system</param> /// <returns>Staged file location</returns> public StagedFileReference GetStagedFileLocation(FileReference InputFile) { StagedFileReference OutputFile; if (InputFile.IsUnderDirectory(ProjectRoot)) { OutputFile = StagedFileReference.Combine(RelativeProjectRootForStage, InputFile.MakeRelativeTo(ProjectRoot)); } else if (InputFile.HasExtension(".uplugin")) { DirectoryReference EnterpriseRoot = DirectoryReference.Combine(EngineRoot, "..", "Enterprise"); // Enterprise plugins aren't under the project additional plugin directories, so they shouldn't be remapped if (InputFile.IsUnderDirectory(EngineRoot) || InputFile.IsUnderDirectory(EnterpriseRoot)) { OutputFile = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { // This is a plugin that lives outside of the Engine/Plugins or Game/Plugins directory so needs to be remapped for staging/packaging // We need to remap C:\SomePath\PluginName\PluginName.uplugin to RemappedPlugins\PluginName\PluginName.uplugin OutputFile = new StagedFileReference(String.Format("RemappedPlugins/{0}/{1}", InputFile.GetFileNameWithoutExtension(), InputFile.GetFileName())); } } else if (InputFile.IsUnderDirectory(LocalRoot)) { OutputFile = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { throw new AutomationException("Can't deploy {0} because it doesn't start with {1} or {2}", InputFile, ProjectRoot, LocalRoot); } return(OutputFile); }
/// <summary> /// Execute the task. /// </summary> /// <param name="Job">Information about the current job</param> /// <param name="BuildProducts">Set of build products produced by this node.</param> /// <param name="TagNameToFileSet">Mapping from tag names to the set of files they include</param> public override void Execute(JobContext Job, HashSet <FileReference> BuildProducts, Dictionary <string, HashSet <FileReference> > TagNameToFileSet) { // Find the directories we're going to rebase relative to HashSet <DirectoryReference> RebaseDirs = new HashSet <DirectoryReference> { CommandUtils.RootDirectory }; if (Parameters.RebaseDir != null) { RebaseDirs.UnionWith(Parameters.RebaseDir); } // Get the output parameter FileReference OutputFile = Parameters.Output; // Check for a ResponseFile parameter FileReference ResponseFile = Parameters.ResponseFile; if (ResponseFile == null) { // Get a unique filename for the response file ResponseFile = FileReference.Combine(new DirectoryReference(CommandUtils.CmdEnv.LogFolder), String.Format("PakList_{0}.txt", OutputFile.GetFileNameWithoutExtension())); for (int Idx = 2; FileReference.Exists(ResponseFile); Idx++) { ResponseFile = FileReference.Combine(ResponseFile.Directory, String.Format("PakList_{0}_{1}.txt", OutputFile.GetFileNameWithoutExtension(), Idx)); } // Write out the response file HashSet <FileReference> Files = ResolveFilespec(CommandUtils.RootDirectory, Parameters.Files, TagNameToFileSet); using (StreamWriter Writer = new StreamWriter(ResponseFile.FullName, false, new System.Text.UTF8Encoding(true))) { foreach (FileReference File in Files) { string RelativePath = FindShortestRelativePath(File, RebaseDirs); if (RelativePath == null) { throw new AutomationException("Couldn't find relative path for '{0}' - not under any rebase directories", File.FullName); } Writer.WriteLine("\"{0}\" \"{1}\"{2}", File.FullName, RelativePath, Parameters.Compress ? " -compress" : ""); } } } // Format the command line StringBuilder CommandLine = new StringBuilder(); CommandLine.AppendFormat("{0} -create={1}", CommandUtils.MakePathSafeToUseWithCommandLine(OutputFile.FullName), CommandUtils.MakePathSafeToUseWithCommandLine(ResponseFile.FullName)); if (Parameters.Sign != null) { CommandLine.AppendFormat(" -sign={0}", CommandUtils.MakePathSafeToUseWithCommandLine(Parameters.Sign.FullName)); } if (Parameters.Order != null) { CommandLine.AppendFormat(" -order={0}", CommandUtils.MakePathSafeToUseWithCommandLine(Parameters.Order.FullName)); } if (CommandUtils.IsEngineInstalled()) { CommandLine.Append(" -installed"); } if (GlobalCommandLine.UTF8Output) { CommandLine.AppendFormat(" -UTF8Output"); } // Get the executable path FileReference UnrealPakExe; if (HostPlatform.Current.HostEditorPlatform == UnrealTargetPlatform.Win64) { UnrealPakExe = ResolveFile("Engine/Binaries/Win64/UnrealPak.exe"); } else { UnrealPakExe = ResolveFile(String.Format("Engine/Binaries/{0}/UnrealPak", HostPlatform.Current.HostEditorPlatform.ToString())); } // Run it CommandUtils.LogInformation("Running '{0} {1}'", CommandUtils.MakePathSafeToUseWithCommandLine(UnrealPakExe.FullName), CommandLine.ToString()); CommandUtils.RunAndLog(CommandUtils.CmdEnv, UnrealPakExe.FullName, CommandLine.ToString(), Options: CommandUtils.ERunOptions.Default | CommandUtils.ERunOptions.UTF8Output); BuildProducts.Add(OutputFile); // Apply the optional tag to the output file foreach (string TagName in FindTagNamesFromList(Parameters.Tag)) { FindOrAddTagSet(TagNameToFileSet, TagName).Add(OutputFile); } }
/// <summary> /// Execute the task. /// </summary> /// <param name="Job">Information about the current job</param> /// <param name="BuildProducts">Set of build products produced by this node.</param> /// <param name="TagNameToFileSet">Mapping from tag names to the set of files they include</param> public override void Execute(JobContext Job, HashSet <FileReference> BuildProducts, Dictionary <string, HashSet <FileReference> > TagNameToFileSet) { // Get the project path, and check it exists FileReference ProjectFile = Parameters.Project; if (Parameters.Project != null && !FileReference.Exists(ProjectFile)) { throw new AutomationException("Couldn't find project '{0}'", ProjectFile.FullName); } // Get the directories used for staging this project DirectoryReference SourceEngineDir = CommandUtils.EngineDirectory; DirectoryReference SourceProjectDir = (ProjectFile == null)? SourceEngineDir : ProjectFile.Directory; // Get the output directories. We flatten the directory structure on output. DirectoryReference TargetDir = Parameters.ToDir; DirectoryReference TargetEngineDir = DirectoryReference.Combine(TargetDir, "Engine"); DirectoryReference TargetProjectDir = DirectoryReference.Combine(TargetDir, ProjectFile.GetFileNameWithoutExtension()); // Get the path to the receipt FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(SourceProjectDir, Parameters.Target, Parameters.Platform, Parameters.Configuration, Parameters.Architecture); // Try to load it TargetReceipt Receipt; if (!TargetReceipt.TryRead(ReceiptFileName, out Receipt)) { throw new AutomationException("Couldn't read receipt '{0}'", ReceiptFileName); } // Stage all the build products needed at runtime HashSet <FileReference> SourceFiles = new HashSet <FileReference>(); foreach (BuildProduct BuildProduct in Receipt.BuildProducts) { SourceFiles.Add(BuildProduct.Path); } foreach (RuntimeDependency RuntimeDependency in Receipt.RuntimeDependencies.Where(x => x.Type != StagedFileType.UFS)) { SourceFiles.Add(RuntimeDependency.Path); } // Get all the target files List <FileReference> TargetFiles = new List <FileReference>(); foreach (FileReference SourceFile in SourceFiles) { // Get the destination file to copy to, mapping to the new engine and project directories as appropriate FileReference TargetFile; if (SourceFile.IsUnderDirectory(SourceEngineDir)) { TargetFile = FileReference.Combine(TargetEngineDir, SourceFile.MakeRelativeTo(SourceEngineDir)); } else { TargetFile = FileReference.Combine(TargetProjectDir, SourceFile.MakeRelativeTo(SourceProjectDir)); } // Fixup the case of the output file. Would expect Platform.DeployLowerCaseFilenames() to return true here, but seems not to be the case. if (Parameters.Platform == UnrealTargetPlatform.PS4) { TargetFile = FileReference.Combine(TargetDir, TargetFile.MakeRelativeTo(TargetDir).ToLowerInvariant()); } // Only copy the output file if it doesn't already exist. We can stage multiple targets to the same output directory. if (Parameters.Overwrite || !FileReference.Exists(TargetFile)) { DirectoryReference.CreateDirectory(TargetFile.Directory); CommandUtils.CopyFile(SourceFile.FullName, TargetFile.FullName); // Force all destination files to not readonly. CommandUtils.SetFileAttributes(TargetFile.FullName, ReadOnly: false); } // Add it to the list of target files TargetFiles.Add(TargetFile); } // Apply the optional tag to the build products foreach (string TagName in FindTagNamesFromList(Parameters.Tag)) { FindOrAddTagSet(TagNameToFileSet, TagName).UnionWith(TargetFiles); } // Add the target file to the list of build products BuildProducts.UnionWith(TargetFiles); }
FileReference CreateHostProject(FileReference HostProjectFile, FileReference PluginFile) { DirectoryReference HostProjectDir = HostProjectFile.Directory; HostProjectDir.CreateDirectory(); // Create the new project descriptor File.WriteAllText(HostProjectFile.FullName, "{ \"FileVersion\": 3, \"Plugins\": [ { \"Name\": \"" + PluginFile.GetFileNameWithoutExtension() + "\", \"Enabled\": true } ] }"); // Get the plugin directory in the host project, and copy all the files in DirectoryReference HostProjectPluginDir = DirectoryReference.Combine(HostProjectDir, "Plugins", PluginFile.GetFileNameWithoutExtension()); CommandUtils.ThreadedCopyFiles(PluginFile.Directory.FullName, HostProjectPluginDir.FullName); CommandUtils.DeleteDirectory(true, DirectoryReference.Combine(HostProjectPluginDir, "Intermediate").FullName); // Return the path to the plugin file in the host project return FileReference.Combine(HostProjectPluginDir, PluginFile.GetFileName()); }
private static bool RequiresTempTarget(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, List <UnrealTargetConfiguration> ClientTargetConfigurations, bool AssetNativizationRequested, out string Reason) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { Reason = null; return(false); } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source")).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { Reason = null; return(false); } } // // once we reach this point, we can surmise that this is an asset- // only (code free) project if (AssetNativizationRequested) { // we're going to be converting some of the project's assets // into native code, so we require a distinct target (executable) // be generated for this project Reason = "asset nativization is enabled"; return(true); } if (ClientTargetPlatforms != null) { foreach (UnrealTargetPlatform ClientPlatform in ClientTargetPlatforms) { EncryptionAndSigning.CryptoSettings Settings = EncryptionAndSigning.ParseCryptoSettings(RawProjectPath.Directory, ClientPlatform); if (Settings.IsAnyEncryptionEnabled() || Settings.IsPakSigningEnabled()) { Reason = "encryption/signing is enabled"; return(true); } } } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } List <UnrealTargetConfiguration> TargetConfigurations = ClientTargetConfigurations; if (TargetConfigurations == null || TargetConfigurations.Count < 1) { // No client target configurations, add all in TargetConfigurations = new List <UnrealTargetConfiguration>(); foreach (UnrealTargetConfiguration TargetConfigurationType in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (TargetConfigurationType != UnrealTargetConfiguration.Unknown) { TargetConfigurations.Add(TargetConfigurationType); } } } // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath); List <PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(CommandUtils.EngineDirectory, RawProjectPath, Project.AdditionalPluginDirectories); // check the target platforms for any differences in build settings or additional plugins foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { if (!CommandUtils.IsEngineInstalled() && !PlatformExports.HasDefaultBuildConfig(RawProjectPath, TargetPlatformType)) { Reason = "project has non-default build configuration"; return(true); } if (PlatformExports.RequiresBuild(RawProjectPath, TargetPlatformType)) { Reason = "overriden by target platform"; return(true); } // find if there are any plugins enabled or disabled which differ from the default foreach (PluginInfo Plugin in AvailablePlugins) { bool bPluginEnabledForTarget = false; foreach (UnrealTargetConfiguration TargetConfigType in TargetConfigurations) { bPluginEnabledForTarget |= Plugins.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType, TargetConfigType, TargetRules.TargetType.Game); } bool bPluginEnabledForBaseTarget = false; if (!Plugin.Descriptor.bInstalled) { foreach (UnrealTargetConfiguration TargetConfigType in TargetConfigurations) { bPluginEnabledForBaseTarget |= Plugins.IsPluginEnabledForProject(Plugin, null, TargetPlatformType, TargetConfigType, TargetRules.TargetType.Game); } } if (bPluginEnabledForTarget != bPluginEnabledForBaseTarget) { if (bPluginEnabledForTarget) { Reason = String.Format("{0} plugin is enabled", Plugin.Name); return(true); } else { Reason = String.Format("{0} plugin is disabled", Plugin.Name); return(true); } } } } Reason = null; return(false); }
public override void ExecuteBuild() { // Get the plugin filename string PluginParam = ParseParamValue("Plugin"); if (PluginParam == null) { throw new AutomationException("Plugin file name was not specified via the -plugin argument"); } // Read the plugin FileReference PluginFile = new FileReference(PluginParam); DirectoryReference PluginDirectory = PluginFile.Directory; PluginDescriptor Plugin = PluginDescriptor.FromFile(PluginFile); // Clean the intermediate build directory DirectoryReference IntermediateBuildDirectory = DirectoryReference.Combine(PluginDirectory, "Intermediate", "Build"); if (CommandUtils.DirectoryExists(IntermediateBuildDirectory.FullName)) { CommandUtils.DeleteDirectory(IntermediateBuildDirectory.FullName); } // Create a host project for the plugin. For script generator plugins, we need to have UHT be able to load it - and that can only happen if it's enabled in a project. DirectoryReference HostProjectDirectory = DirectoryReference.Combine(new DirectoryReference(CommandUtils.CmdEnv.LocalRoot), "HostProject"); if (CommandUtils.DirectoryExists(HostProjectDirectory.FullName)) { CommandUtils.DeleteDirectory(HostProjectDirectory.FullName); } DirectoryReference HostProjectPluginDirectory = DirectoryReference.Combine(HostProjectDirectory, "Plugins", PluginFile.GetFileNameWithoutExtension()); string[] CopyPluginFiles = Directory.EnumerateFiles(PluginDirectory.FullName, "*", SearchOption.AllDirectories).ToArray(); foreach (string CopyPluginFile in CopyPluginFiles) { CommandUtils.CopyFile(CopyPluginFile, CommandUtils.MakeRerootedFilePath(CopyPluginFile, PluginDirectory.FullName, HostProjectPluginDirectory.FullName)); } FileReference HostProjectPluginFile = FileReference.Combine(HostProjectPluginDirectory, PluginFile.GetFileName()); FileReference HostProjectFile = FileReference.Combine(HostProjectDirectory, "HostProject.uproject"); File.WriteAllText(HostProjectFile.FullName, "{ \"FileVersion\": 3, \"Plugins\": [ { \"Name\": \"" + PluginFile.GetFileNameWithoutExtension() + "\", \"Enabled\": true } ] }"); // Get any additional arguments from the commandline string AdditionalArgs = ""; // Build the host platforms List <string> ReceiptFileNames = new List <string>(); UnrealTargetPlatform HostPlatform = BuildHostPlatform.Current.Platform; if (!ParseParam("NoHostPlatform")) { if (Plugin.bCanBeUsedWithUnrealHeaderTool) { BuildPluginWithUBT(PluginFile, Plugin, null, "UnrealHeaderTool", TargetRules.TargetType.Program, HostPlatform, UnrealTargetConfiguration.Development, ReceiptFileNames, String.Format("{0} -plugin {1}", AdditionalArgs, CommandUtils.MakePathSafeToUseWithCommandLine(HostProjectPluginFile.FullName))); } BuildPluginWithUBT(PluginFile, Plugin, HostProjectFile, "UE4Editor", TargetRules.TargetType.Editor, HostPlatform, UnrealTargetConfiguration.Development, ReceiptFileNames, AdditionalArgs); } // Add the game targets List <UnrealTargetPlatform> TargetPlatforms = Rocket.RocketBuild.GetTargetPlatforms(this, HostPlatform); foreach (UnrealTargetPlatform TargetPlatform in TargetPlatforms) { if (Rocket.RocketBuild.IsCodeTargetPlatform(HostPlatform, TargetPlatform)) { BuildPluginWithUBT(PluginFile, Plugin, HostProjectFile, "UE4Game", TargetRules.TargetType.Game, TargetPlatform, UnrealTargetConfiguration.Development, ReceiptFileNames, AdditionalArgs); BuildPluginWithUBT(PluginFile, Plugin, HostProjectFile, "UE4Game", TargetRules.TargetType.Game, TargetPlatform, UnrealTargetConfiguration.Shipping, ReceiptFileNames, AdditionalArgs); } } // Package the plugin to the output folder string PackageDirectory = ParseParamValue("Package"); if (PackageDirectory != null) { List <BuildProduct> BuildProducts = GetBuildProductsFromReceipts(UnrealBuildTool.UnrealBuildTool.EngineDirectory, HostProjectDirectory, ReceiptFileNames); PackagePlugin(HostProjectPluginFile, BuildProducts, PackageDirectory); } }
/// <summary> /// Helper function to get the console app BinaryName-Cmd.exe filename based on the binary filename. /// </summary> /// <param name="BinaryPath">Full path to the binary exe.</param> /// <returns></returns> public static FileReference GetAdditionalConsoleAppPath(FileReference BinaryPath) { return FileReference.Combine(BinaryPath.Directory, BinaryPath.GetFileNameWithoutExtension() + "-Cmd" + BinaryPath.GetExtension()); }
private static bool RequiresTempTarget(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { return(false); } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source")).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { return(false); } } // // once we reach this point, we can surmise that this is an asset- // only (code free) project if (AssetNativizationRequested) { // we're going to be converting some of the project's assets // into native code, so we require a distinct target (executable) // be generated for this project return(true); } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } // Change the working directory to be the Engine/Source folder. We are running from Engine/Binaries/DotNET string oldCWD = Directory.GetCurrentDirectory(); if (BuildConfiguration.RelativeEnginePath == "../../Engine/") { string EngineSourceDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()), "..", "..", "..", "Engine", "Source"); if (!Directory.Exists(EngineSourceDirectory)) // only set the directory if it exists, this should only happen if we are launching the editor from an artist sync { EngineSourceDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()), "..", "..", "..", "Engine", "Binaries"); } Directory.SetCurrentDirectory(EngineSourceDirectory); } // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath.FullName); List <PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(new DirectoryReference(BuildConfiguration.RelativeEnginePath), RawProjectPath); // check the target platforms for any differences in build settings or additional plugins bool RetVal = false; foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { UEBuildPlatform BuildPlat = UEBuildPlatform.GetBuildPlatform(TargetPlatformType, true); if (!Automation.IsEngineInstalled() && BuildPlat != null && !(BuildPlat as UEBuildPlatform).HasDefaultBuildConfig(TargetPlatformType, RawProjectPath.Directory)) { RetVal = true; break; } // find if there are any plugins enabled or disabled which differ from the default foreach (PluginInfo Plugin in AvailablePlugins) { bool bPluginEnabledForProject = UProjectInfo.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType, TargetRules.TargetType.Game); if ((bPluginEnabledForProject && !Plugin.Descriptor.bEnabledByDefault) || (bPluginEnabledForProject && Plugin.Descriptor.bInstalled)) { if (Plugin.Descriptor.Modules.Any(Module => Module.IsCompiledInConfiguration(TargetPlatformType, TargetRules.TargetType.Game, bBuildDeveloperTools: false, bBuildEditor: false))) { RetVal = true; break; } } } } // Change back to the original directory Directory.SetCurrentDirectory(oldCWD); return(RetVal); }
private static bool RequiresTempTarget(FileReference RawProjectPath, List<UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested) { // check to see if we already have a Target.cs file if (File.Exists (Path.Combine (Path.GetDirectoryName (RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { return false; } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo( Path.Combine (Path.GetDirectoryName (RawProjectPath.FullName), "Source")).GetFiles ("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { return false; } } // // once we reach this point, we can surmise that this is an asset- // only (code free) project if (AssetNativizationRequested) { // we're going to be converting some of the project's assets // into native code, so we require a distinct target (executable) // be generated for this project return true; } // no Target file, now check to see if build settings have changed List<UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List<UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } // Change the working directory to be the Engine/Source folder. We are running from Engine/Binaries/DotNET string oldCWD = Directory.GetCurrentDirectory(); if (BuildConfiguration.RelativeEnginePath == "../../Engine/") { string EngineSourceDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()), "..", "..", "..", "Engine", "Source"); if (!Directory.Exists(EngineSourceDirectory)) // only set the directory if it exists, this should only happen if we are launching the editor from an artist sync { EngineSourceDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()), "..", "..", "..", "Engine", "Binaries"); } Directory.SetCurrentDirectory(EngineSourceDirectory); } // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath.FullName); DirectoryReference EngineDirectory = new DirectoryReference(BuildConfiguration.RelativeEnginePath); List<PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(EngineDirectory, RawProjectPath, Project.AdditionalPluginDirectories); // check the target platforms for any differences in build settings or additional plugins bool RetVal = false; foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { UEBuildPlatform BuildPlat = UEBuildPlatform.GetBuildPlatform(TargetPlatformType, true); if (!Automation.IsEngineInstalled() && BuildPlat != null && !(BuildPlat as UEBuildPlatform).HasDefaultBuildConfig(TargetPlatformType, RawProjectPath.Directory)) { RetVal = true; break; } // find if there are any plugins enabled or disabled which differ from the default foreach(PluginInfo Plugin in AvailablePlugins) { bool bPluginEnabledForProject = UProjectInfo.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType, TargetRules.TargetType.Game); if ((bPluginEnabledForProject && !Plugin.Descriptor.bEnabledByDefault) || (bPluginEnabledForProject && Plugin.Descriptor.bInstalled)) { if(Plugin.Descriptor.Modules.Any(Module => Module.IsCompiledInConfiguration(TargetPlatformType, TargetRules.TargetType.Game, bBuildDeveloperTools: false, bBuildEditor: false))) { RetVal = true; break; } } } } // Change back to the original directory Directory.SetCurrentDirectory(oldCWD); return RetVal; }
private static bool ProjectHasCode(FileReference RawProjectPath) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { return(true); } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source")).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { return(true); } } return(false); }
/// <summary> /// Called after command line params are applied. Perform any checks / fixup /// </summary> /// <param name="InParams"></param> public virtual void ParametersWereApplied(string[] InParams) { // save params this.Params = new Params(InParams); if (string.IsNullOrEmpty(TempDir)) { TempDir = Globals.TempDir; } else { Globals.TempDir = TempDir; } if (string.IsNullOrEmpty(LogDir)) { LogDir = Globals.LogDir; } else { Globals.LogDir = LogDir; } // normalize the project name and get the path if (File.Exists(Project)) { ProjectPath = new FileReference(Project); Project = ProjectPath.GetFileNameWithoutExtension(); } else { if (!string.IsNullOrEmpty(Project)) { ProjectPath = ProjectUtils.FindProjectFileFromName(Project); if (ProjectPath == null) { throw new AutomationException("Could not find project file for {0}", Project); } Project = ProjectPath.GetFileNameWithoutExtension(); } } if (string.IsNullOrEmpty(Sandbox)) { Sandbox = Project; } // parse platforms. These will be in the format of Win64(param1,param2='foo,bar') etc // check for old-style -platform=Win64(params) List <string> PlatformArgStrings = Params.ParseValues("Platform="); // check for convenience flags of -Win64(params) (TODO - need to think about this..) /*foreach (UnrealTargetPlatform Plat in UnrealTargetPlatform.GetValidPlatforms()) * { * IEnumerable<string> RawPlatformArgs = InParams.Where(P => P.ToLower().StartsWith(Plat.ToString().ToLower())); * * PlatformArgStrings.AddRange(RawPlatformArgs); * }*/ // now turn the Plat(param1,param2) etc into an argument/parm pair PlatformList = PlatformArgStrings.SelectMany(P => ArgumentWithParams.CreateFromString(P)).ToList(); List <string> TestArgStrings = Params.ParseValues("test="); // clear all tests incase this is called multiple times TestList.Clear(); if (TestArgStrings.Count == 0) { TestArgStrings = Params.ParseValues("tests="); } foreach (string TestArg in TestArgStrings) { foreach (ArgumentWithParams TestWithParms in ArgumentWithParams.CreateFromString(TestArg)) { TestRequest Test = new TestRequest() { TestName = TestWithParms.Argument, TestParams = new Params(TestWithParms.AllArguments) }; // parse any specified platforms foreach (string PlatformArg in Test.TestParams.ParseValues("Platform=")) { List <ArgumentWithParams> PlatParams = ArgumentWithParams.CreateFromString(PlatformArg); Test.Platforms.AddRange(PlatParams); // register platform in test options PlatParams.ForEach(TestPlat => { if (PlatformList.Where(Plat => Plat.Argument == TestPlat.Argument).Count() == 0) { PlatformList.Add(TestPlat); } }); } TestList.Add(Test); } } if (PlatformList.Count == 0) { // Default to local platform PlatformList.Add(new ArgumentWithParams(BuildHostPlatform.Current.Platform.ToString(), new string[0])); } // do we have any tests? Need to check the global test list bool HaveTests = TestList.Count > 0 || PlatformList.Where(Plat => Plat.ParseValues("test").Count() > 0).Count() > 0; // turn -device=BobsKit,BobsKit(PS4) into a device list List <string> DeviceArgStrings = Params.ParseValues("device="); if (DeviceArgStrings.Count == 0) { DeviceArgStrings = Params.ParseValues("devices="); } DeviceList = DeviceArgStrings.SelectMany(D => ArgumentWithParams.CreateFromString(D)).ToList(); if (DeviceList.Count == 0) { // Add the default test DeviceList.Add(new ArgumentWithParams("default", new string[0])); } // remote all -test and -platform arguments from our params. Nothing else should be looking at these now... string[] CleanArgs = Params.AllArguments .Where(Arg => !Arg.StartsWith("test=", StringComparison.OrdinalIgnoreCase) && !Arg.StartsWith("platform=", StringComparison.OrdinalIgnoreCase) && !Arg.StartsWith("device=", StringComparison.OrdinalIgnoreCase)) .ToArray(); Params = new Params(CleanArgs); }
FileReference CreateHostProject(FileReference HostProjectFile, FileReference PluginFile) { DirectoryReference HostProjectDir = HostProjectFile.Directory; DirectoryReference.CreateDirectory(HostProjectDir); // Create the new project descriptor File.WriteAllText(HostProjectFile.FullName, "{ \"FileVersion\": 3, \"Plugins\": [ { \"Name\": \"" + PluginFile.GetFileNameWithoutExtension() + "\", \"Enabled\": true } ] }"); // Get the plugin directory in the host project, and copy all the files in DirectoryReference HostProjectPluginDir = DirectoryReference.Combine(HostProjectDir, "Plugins", PluginFile.GetFileNameWithoutExtension()); CommandUtils.ThreadedCopyFiles(PluginFile.Directory.FullName, HostProjectPluginDir.FullName); CommandUtils.DeleteDirectory(true, DirectoryReference.Combine(HostProjectPluginDir, "Intermediate").FullName); // Return the path to the plugin file in the host project return(FileReference.Combine(HostProjectPluginDir, PluginFile.GetFileName())); }
/// <summary> /// Creates a rules assembly with the given parameters. /// </summary> /// <param name="ProjectFileName">The project file to create rules for. Null for the engine.</param> /// <param name="ForeignPlugins">List of foreign plugin folders to include in the assembly. May be null.</param> public static RulesAssembly CreateProjectRulesAssembly(FileReference ProjectFileName) { // Check if there's an existing assembly for this project RulesAssembly ProjectRulesAssembly; if (!LoadedAssemblyMap.TryGetValue(ProjectFileName, out ProjectRulesAssembly)) { // Create the engine rules assembly RulesAssembly Parent = CreateEngineRulesAssembly(); // Find all the rules under the project source directory DirectoryReference ProjectDirectory = ProjectFileName.Directory; DirectoryReference ProjectSourceDirectory = DirectoryReference.Combine(ProjectDirectory, "Source"); List<FileReference> ModuleFiles = new List<FileReference>(FindAllRulesFiles(ProjectSourceDirectory, RulesFileType.Module)); List<FileReference> TargetFiles = new List<FileReference>(FindAllRulesFiles(ProjectSourceDirectory, RulesFileType.Target)); // Find all the project plugins List<PluginInfo> ProjectPlugins = new List<PluginInfo>(Plugins.ReadProjectPlugins(ProjectFileName.Directory)); ProjectDescriptor Project = ProjectDescriptor.FromFile(ProjectFileName.FullName); // Add the project's additional plugin directories plugins too ProjectPlugins.AddRange(Plugins.ReadAdditionalPlugins(Project.AdditionalPluginDirectories)); Dictionary<FileReference, PluginInfo> ModuleFileToPluginInfo = new Dictionary<FileReference, PluginInfo>(); FindModuleRulesForPlugins(ProjectPlugins, ModuleFiles, ModuleFileToPluginInfo); // Add the games project's intermediate source folder DirectoryReference ProjectIntermediateSourceDirectory = DirectoryReference.Combine(ProjectDirectory, "Intermediate", "Source"); if (ProjectIntermediateSourceDirectory.Exists()) { TargetFiles.AddRange(FindAllRulesFiles(ProjectIntermediateSourceDirectory, RulesFileType.Target)); } // Compile the assembly FileReference AssemblyFileName = FileReference.Combine(ProjectDirectory, BuildConfiguration.BaseIntermediateFolder, "BuildRules", ProjectFileName.GetFileNameWithoutExtension() + "ModuleRules.dll"); ProjectRulesAssembly = new RulesAssembly(ProjectPlugins, ModuleFiles, TargetFiles, ModuleFileToPluginInfo, AssemblyFileName, Parent); LoadedAssemblyMap.Add(ProjectFileName, ProjectRulesAssembly); } return ProjectRulesAssembly; }
private static bool RequiresTempTarget(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { return(false); } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source")).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { return(false); } } // // once we reach this point, we can surmise that this is an asset- // only (code free) project if (AssetNativizationRequested) { // we're going to be converting some of the project's assets // into native code, so we require a distinct target (executable) // be generated for this project return(true); } if (ClientTargetPlatforms != null) { foreach (UnrealTargetPlatform ClientPlatform in ClientTargetPlatforms) { String EncryptionKey; String[] SigningKeys; EncryptionAndSigning.ParseEncryptionIni(RawProjectPath.Directory, ClientPlatform, out SigningKeys, out EncryptionKey); if (SigningKeys != null || !string.IsNullOrEmpty(EncryptionKey)) { return(true); } } } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } // Change the working directory to be the Engine/Source folder. We are running from Engine/Binaries/DotNET DirectoryReference oldCWD = DirectoryReference.GetCurrentDirectory(); try { DirectoryReference EngineSourceDirectory = DirectoryReference.Combine(CommandUtils.EngineDirectory, "Source"); if (!DirectoryReference.Exists(EngineSourceDirectory)) // only set the directory if it exists, this should only happen if we are launching the editor from an artist sync { EngineSourceDirectory = DirectoryReference.Combine(CommandUtils.EngineDirectory, "Binaries"); } Directory.SetCurrentDirectory(EngineSourceDirectory.FullName); // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath); List <PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(CommandUtils.EngineDirectory, RawProjectPath, Project.AdditionalPluginDirectories); // check the target platforms for any differences in build settings or additional plugins bool RetVal = false; foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { if (!Automation.IsEngineInstalled() && !PlatformExports.HasDefaultBuildConfig(RawProjectPath, TargetPlatformType)) { RetVal = true; break; } // find if there are any plugins enabled or disabled which differ from the default foreach (PluginInfo Plugin in AvailablePlugins) { bool bPluginEnabledForProject = Plugins.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType, TargetType.Game); if ((bPluginEnabledForProject != Plugin.EnabledByDefault) || (bPluginEnabledForProject && Plugin.Descriptor.bInstalled)) { // NOTE: this code was only marking plugins that compiled for the platform to upgrade to code project, however // this doesn't work in practice, because the runtime code will look for the plugin, without a .uplugin file, // and will fail. This is the safest way to make sure all platforms are acting the same. However, if you // whitelist the plugin in the .uproject file, the above UProjectInfo.IsPluginEnabledForProject check won't pass // so you won't get in here. Leaving this commented out code in there, because someone is bound to come looking // for why a non-whitelisted platform module is causing a project to convert to code-based. // As an aside, if you run the project with UE4Game (not your Project's binary) from the debugger, it will work // _in this case_ because the .uplugin file will have been staged, and there is no needed library // if(Plugin.Descriptor.Modules.Any(Module => Module.IsCompiledInConfiguration(TargetPlatformType, TargetType.Game, bBuildDeveloperTools: false, bBuildEditor: false))) { RetVal = true; break; } } } } return(RetVal); } finally { // Change back to the original directory Directory.SetCurrentDirectory(oldCWD.FullName); } }
public void StageFile(StagedFileType FileType, FileReference InputFile, StagedFileReference OutputFile = null, bool bRemap = true) { if (OutputFile == null) { if (InputFile.IsUnderDirectory(ProjectRoot)) { OutputFile = StagedFileReference.Combine(RelativeProjectRootForStage, InputFile.MakeRelativeTo(ProjectRoot)); } else if (InputFile.HasExtension(".uplugin")) { if (InputFile.IsUnderDirectory(EngineRoot)) { OutputFile = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { // This is a plugin that lives outside of the Engine/Plugins or Game/Plugins directory so needs to be remapped for staging/packaging // We need to remap C:\SomePath\PluginName\PluginName.uplugin to RemappedPlugins\PluginName\PluginName.uplugin OutputFile = new StagedFileReference(String.Format("RemappedPlugins/{0}/{1}", InputFile.GetFileNameWithoutExtension(), InputFile.GetFileName())); } } else if (InputFile.IsUnderDirectory(LocalRoot)) { OutputFile = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { throw new AutomationException("Can't deploy {0} because it doesn't start with {1} or {2}", InputFile, ProjectRoot, LocalRoot); } } if (bRemap) { OutputFile = StageTargetPlatform.Remap(OutputFile); } FilesToStage.Add(FileType, OutputFile, InputFile); }
/// <summary> /// Execute the task. /// </summary> /// <param name="Job">Information about the current job</param> /// <param name="BuildProducts">Set of build products produced by this node.</param> /// <param name="TagNameToFileSet">Mapping from tag names to the set of files they include</param> /// <returns>True if the task succeeded</returns> public override bool Execute(JobContext Job, HashSet <FileReference> BuildProducts, Dictionary <string, HashSet <FileReference> > TagNameToFileSet) { // Get the project path, and check it exists FileReference ProjectFile = null; if (Parameters.Project != null) { ProjectFile = ResolveFile(Parameters.Project); if (!ProjectFile.Exists()) { CommandUtils.LogError("Couldn't find project '{0}'", ProjectFile.FullName); return(false); } } // Get the directories used for staging this project DirectoryReference SourceEngineDir = UnrealBuildTool.UnrealBuildTool.EngineDirectory; DirectoryReference SourceProjectDir = (ProjectFile == null)? SourceEngineDir : ProjectFile.Directory; // Get the output directories. We flatten the directory structure on output. DirectoryReference TargetDir = ResolveDirectory(Parameters.ToDir); DirectoryReference TargetEngineDir = DirectoryReference.Combine(TargetDir, "Engine"); DirectoryReference TargetProjectDir = DirectoryReference.Combine(TargetDir, ProjectFile.GetFileNameWithoutExtension()); // Get the path to the receipt string ReceiptFileName = TargetReceipt.GetDefaultPath(SourceProjectDir.FullName, Parameters.Target, Parameters.Platform, Parameters.Configuration, Parameters.Architecture); // Try to load it TargetReceipt Receipt; if (!TargetReceipt.TryRead(ReceiptFileName, out Receipt)) { CommandUtils.LogError("Couldn't read receipt '{0}'", ReceiptFileName); return(false); } // Expand all the paths from the receipt Receipt.ExpandPathVariables(SourceEngineDir, SourceProjectDir); // Stage all the build products needed at runtime HashSet <FileReference> SourceFiles = new HashSet <FileReference>(); foreach (BuildProduct BuildProduct in Receipt.BuildProducts.Where(x => x.Type != BuildProductType.StaticLibrary && x.Type != BuildProductType.ImportLibrary)) { SourceFiles.Add(new FileReference(BuildProduct.Path)); } foreach (RuntimeDependency RuntimeDependency in Receipt.RuntimeDependencies.Where(x => x.Type != StagedFileType.UFS)) { SourceFiles.UnionWith(CommandUtils.ResolveFilespec(CommandUtils.RootDirectory, RuntimeDependency.Path, new string[] { ".../*.umap", ".../*.uasset" })); } // Get all the target files List <FileReference> TargetFiles = new List <FileReference>(); foreach (FileReference SourceFile in SourceFiles) { // Get the destination file to copy to, mapping to the new engine and project directories as appropriate FileReference TargetFile; if (SourceFile.IsUnderDirectory(SourceEngineDir)) { TargetFile = FileReference.Combine(TargetEngineDir, SourceFile.MakeRelativeTo(SourceEngineDir)); } else { TargetFile = FileReference.Combine(TargetProjectDir, SourceFile.MakeRelativeTo(SourceProjectDir)); } // Fixup the case of the output file. Would expect Platform.DeployLowerCaseFilenames() to return true here, but seems not to be the case. if (Parameters.Platform == UnrealTargetPlatform.PS4) { TargetFile = FileReference.Combine(TargetDir, TargetFile.MakeRelativeTo(TargetDir).ToLowerInvariant()); } // Only copy the output file if it doesn't already exist. We can stage multiple targets to the same output directory. if (Parameters.Overwrite || !TargetFile.Exists()) { TargetFile.Directory.CreateDirectory(); CommandUtils.CopyFile(SourceFile.FullName, TargetFile.FullName); } // Add it to the list of target files TargetFiles.Add(TargetFile); } // Apply the optional tag to the build products foreach (string TagName in FindTagNamesFromList(Parameters.Tag)) { FindOrAddTagSet(TagNameToFileSet, TagName).UnionWith(TargetFiles); } // Add the target file to the list of build products BuildProducts.UnionWith(TargetFiles); return(true); }
public override void CompileCSharpProject(CSharpEnvironment CompileEnvironment, FileReference ProjectFileName, FileReference DestinationFile) { // Initialize environment variables required for spawned tools. VCEnvironment EnvVars = VCEnvironment.SetEnvironment(CompileEnvironment.EnvironmentTargetPlatform, bSupportWindowsXP); Action BuildProjectAction = new Action(ActionType.BuildProject); // Specify the source file (prerequisite) for the action FileItem ProjectFileItem = FileItem.GetExistingItemByFileReference(ProjectFileName); if (ProjectFileItem == null) { throw new BuildException("Expected C# project file {0} to exist.", ProjectFileName); } // Add the project and the files contained to the prerequisites. BuildProjectAction.PrerequisiteItems.Add(ProjectFileItem); VCSharpProjectFile ProjectFile = new VCSharpProjectFile(ProjectFileName); List<string> ProjectPreReqs = ProjectFile.GetCSharpDependencies(); DirectoryReference ProjectFolder = ProjectFileName.Directory; foreach (string ProjectPreReqRelativePath in ProjectPreReqs) { FileReference ProjectPreReqAbsolutePath = FileReference.Combine(ProjectFolder, ProjectPreReqRelativePath); FileItem ProjectPreReqFileItem = FileItem.GetExistingItemByFileReference(ProjectPreReqAbsolutePath); if (ProjectPreReqFileItem == null) { throw new BuildException("Expected C# dependency {0} to exist.", ProjectPreReqAbsolutePath); } BuildProjectAction.PrerequisiteItems.Add(ProjectPreReqFileItem); } // We might be able to distribute this safely, but it doesn't take any time. BuildProjectAction.bCanExecuteRemotely = false; // Setup execution via MSBuild. BuildProjectAction.WorkingDirectory = UnrealBuildTool.EngineSourceDirectory.FullName; BuildProjectAction.StatusDescription = ProjectFileName.GetFileName(); BuildProjectAction.CommandPath = EnvVars.MSBuildPath; if (CompileEnvironment.TargetConfiguration == CSharpTargetConfiguration.Debug) { BuildProjectAction.CommandArguments = " /target:rebuild /property:Configuration=Debug"; } else { BuildProjectAction.CommandArguments = " /target:rebuild /property:Configuration=Development"; } // Be less verbose BuildProjectAction.CommandArguments += " /nologo /verbosity:minimal"; // Add project BuildProjectAction.CommandArguments += String.Format(" \"{0}\"", ProjectFileItem.AbsolutePath); // Specify the output files. FileReference PDBFilePath = FileReference.Combine(DestinationFile.Directory, DestinationFile.GetFileNameWithoutExtension() + ".pdb"); FileItem PDBFile = FileItem.GetItemByFileReference(PDBFilePath); BuildProjectAction.ProducedItems.Add(FileItem.GetItemByFileReference(DestinationFile)); BuildProjectAction.ProducedItems.Add(PDBFile); }