/// <summary>
 /// Deploys the given target
 /// </summary>
 /// <param name="Receipt">Receipt for the target being deployed</param>
 public override void Deploy(TargetReceipt Receipt)
 {
     // do not package data if building via UBT
     new UEDeployAndroid(Receipt.ProjectFile, false).PrepTargetForDeployment(Receipt);
 }
Beispiel #2
0
		/// <summary>
		/// Creates a receipt for this binary.
		/// </summary>
		/// <param name="ToolChain">Toolchain for the target platform</param>
		/// <param name="BuildPlatform">Platform that we're building for</param>
		public virtual TargetReceipt MakeReceipt(IUEToolChain ToolChain)
		{
			TargetReceipt Receipt = new TargetReceipt();

			// Get the type of build products we're creating
			BuildProductType Type = BuildProductType.RequiredResource;
			switch(Config.Type)
			{
				case UEBuildBinaryType.Executable:
					Type = BuildProductType.Executable;
					break;
				case UEBuildBinaryType.DynamicLinkLibrary:
					Type = BuildProductType.DynamicLibrary;
					break;
				case UEBuildBinaryType.StaticLibrary:
					Type = BuildProductType.StaticLibrary;
					break;
			}

			// Add the primary build products
			string DebugExtension = UEBuildPlatform.GetBuildPlatform(Target.Platform).GetDebugInfoExtension(Config.Type);
			foreach (string OutputFilePath in Config.OutputFilePaths)
			{
				AddBuildProductAndDebugFile(OutputFilePath, Type, DebugExtension, Receipt, ToolChain);
			}

			// Add the console app, if there is one
			if (Config.Type == UEBuildBinaryType.Executable && Config.bBuildAdditionalConsoleApp)
			{
				foreach (string OutputFilePath in Config.OutputFilePaths)
				{
					AddBuildProductAndDebugFile(GetAdditionalConsoleAppPath(OutputFilePath), Type, DebugExtension, Receipt, ToolChain);
				}
			}

			// Add any extra files from the toolchain
			ToolChain.AddFilesToReceipt(Receipt, this);
			return Receipt;
		}
 public override bool PrepTargetForDeployment(TargetReceipt Receipt)
 {
     Log.TraceInformation("Deploying now!");
     return(true);
 }
	public void StageRuntimeDependenciesFromReceipt(TargetReceipt Receipt, bool RequireDependenciesToExist, bool bUsingPakFile)
	{
		// Patterns to exclude from wildcard searches. Any maps and assets must be cooked. 
		List<string> ExcludePatterns = new List<string>();
		ExcludePatterns.Add(".../*.umap");
		ExcludePatterns.Add(".../*.uasset");

		// Also stage any additional runtime dependencies, like ThirdParty DLLs
		foreach(RuntimeDependency RuntimeDependency in Receipt.RuntimeDependencies)
		{
			foreach(FileReference File in CommandUtils.ResolveFilespec(CommandUtils.RootDirectory, RuntimeDependency.Path, ExcludePatterns))
			{
				// allow missing files if needed
				if ((RequireDependenciesToExist && RuntimeDependency.Type != StagedFileType.DebugNonUFS) || File.Exists())
				{
					bool bRemap = RuntimeDependency.Type != StagedFileType.UFS || !bUsingPakFile;
					StageFile(RuntimeDependency.Type, File.FullName, bRemap: bRemap);
				}
			}
		}
	}
Beispiel #5
0
 /// <summary>
 /// Deploys the given target
 /// </summary>
 /// <param name="Receipt">Receipt for the target being deployed</param>
 public override void Deploy(TargetReceipt Receipt)
 {
 }
Beispiel #6
0
		/// <summary>
		/// Merges another receipt to this one.
		/// </summary>
		/// <param name="Other">Receipt which should be merged</param>
		public void Merge(TargetReceipt Other)
		{
			foreach(BuildProduct OtherBuildProduct in Other.BuildProducts)
			{
				BuildProducts.Add(OtherBuildProduct);
			}
			foreach(RuntimeDependency OtherRuntimeDependency in Other.RuntimeDependencies)
			{
				if(!RuntimeDependencies.Any(x => x.Path == OtherRuntimeDependency.Path && x.StagePath == OtherRuntimeDependency.StagePath))
				{
					RuntimeDependencies.Add(OtherRuntimeDependency);
				}
			}
		}
        public override void AddFilesToReceipt(TargetReceipt Receipt, UEBuildBinary Binary)
        {
            // we need to include the generated .mem and .symbols file.  
			if(Binary.Config.Type != UEBuildBinaryType.StaticLibrary)
			{
	            Receipt.AddBuildProduct(Binary.Config.OutputFilePath + ".mem", BuildProductType.RequiredResource);
				Receipt.AddBuildProduct(Binary.Config.OutputFilePath + ".symbols", BuildProductType.RequiredResource);
			}
        }
Beispiel #8
0
        /// <summary>
        /// Build a list of targets
        /// </summary>
        /// <param name="TargetDescriptors">Target descriptors</param>
        /// <param name="BuildConfiguration">Current build configuration</param>
        /// <param name="WorkingSet">The source file working set</param>
        /// <param name="Options">Additional options for the build</param>
        /// <param name="WriteOutdatedActionsFile">Files to write the list of outdated actions to (rather than building them)</param>
        /// <returns>Result from the compilation</returns>
        public static void Build(List <TargetDescriptor> TargetDescriptors, BuildConfiguration BuildConfiguration, ISourceFileWorkingSet WorkingSet, BuildOptions Options, FileReference WriteOutdatedActionsFile)
        {
            // Create a makefile for each target
            TargetMakefile[] Makefiles = new TargetMakefile[TargetDescriptors.Count];
            for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
            {
                Makefiles[TargetIdx] = CreateMakefile(BuildConfiguration, TargetDescriptors[TargetIdx], WorkingSet);
            }

            // Export the actions for each target
            for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
            {
                TargetDescriptor TargetDescriptor = TargetDescriptors[TargetIdx];
                foreach (FileReference WriteActionFile in TargetDescriptor.WriteActionFiles)
                {
                    Log.TraceInformation("Writing actions to {0}", WriteActionFile);
                    ActionGraph.ExportJson(Makefiles[TargetIdx].Actions, WriteActionFile);
                }
            }

            // Execute the build
            if ((Options & BuildOptions.SkipBuild) == 0)
            {
                // Make sure that none of the actions conflict with any other (producing output files differently, etc...)
                ActionGraph.CheckForConflicts(Makefiles.SelectMany(x => x.Actions));

                // Check we don't exceed the nominal max path length
                using (Timeline.ScopeEvent("ActionGraph.CheckPathLengths"))
                {
                    ActionGraph.CheckPathLengths(BuildConfiguration, Makefiles.SelectMany(x => x.Actions));
                }

                // Find all the actions to be executed
                HashSet <Action>[] ActionsToExecute = new HashSet <Action> [TargetDescriptors.Count];
                for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
                {
                    ActionsToExecute[TargetIdx] = GetActionsForTarget(BuildConfiguration, TargetDescriptors[TargetIdx], Makefiles[TargetIdx]);
                }

                // If there are multiple targets being built, merge the actions together
                List <Action> MergedActionsToExecute;
                if (TargetDescriptors.Count == 1)
                {
                    MergedActionsToExecute = new List <Action>(ActionsToExecute[0]);
                }
                else
                {
                    MergedActionsToExecute = MergeActionGraphs(TargetDescriptors, ActionsToExecute);
                }

                // Link all the actions together
                ActionGraph.Link(MergedActionsToExecute);

                // Make sure we're not modifying any engine files
                if ((Options & BuildOptions.NoEngineChanges) != 0)
                {
                    List <FileItem> EngineChanges = MergedActionsToExecute.SelectMany(x => x.ProducedItems).Where(x => x.Location.IsUnderDirectory(UnrealBuildTool.EngineDirectory)).Distinct().OrderBy(x => x.FullName).ToList();
                    if (EngineChanges.Count > 0)
                    {
                        StringBuilder Result = new StringBuilder("Building would modify the following engine files:\n");
                        foreach (FileItem EngineChange in EngineChanges)
                        {
                            Result.AppendFormat("\n{0}", EngineChange.FullName);
                        }
                        Result.Append("\n\nPlease rebuild from an IDE instead.");
                        Log.TraceError("{0}", Result.ToString());
                        throw new CompilationResultException(CompilationResult.FailedDueToEngineChange);
                    }
                }

                // Make sure the appropriate executor is selected
                foreach (TargetDescriptor TargetDescriptor in TargetDescriptors)
                {
                    UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(TargetDescriptor.Platform);
                    BuildConfiguration.bAllowXGE    &= BuildPlatform.CanUseXGE();
                    BuildConfiguration.bAllowDistcc &= BuildPlatform.CanUseDistcc();
                    BuildConfiguration.bAllowSNDBS  &= BuildPlatform.CanUseSNDBS();
                }

                // Delete produced items that are outdated.
                ActionGraph.DeleteOutdatedProducedItems(MergedActionsToExecute);

                // Save all the action histories now that files have been removed. We have to do this after deleting produced items to ensure that any
                // items created during the build don't have the wrong command line.
                ActionHistory.SaveAll();

                // Create directories for the outdated produced items.
                ActionGraph.CreateDirectoriesForProducedItems(MergedActionsToExecute);

                // Execute the actions
                if ((Options & BuildOptions.XGEExport) != 0)
                {
                    OutputToolchainInfo(TargetDescriptors, Makefiles);

                    // Just export to an XML file
                    using (Timeline.ScopeEvent("XGE.ExportActions()"))
                    {
                        XGE.ExportActions(MergedActionsToExecute);
                    }
                }
                else if (WriteOutdatedActionsFile != null)
                {
                    OutputToolchainInfo(TargetDescriptors, Makefiles);

                    // Write actions to an output file
                    using (Timeline.ScopeEvent("ActionGraph.WriteActions"))
                    {
                        ActionGraph.ExportJson(MergedActionsToExecute, WriteOutdatedActionsFile);
                    }
                }
                else
                {
                    // Execute the actions
                    if (MergedActionsToExecute.Count == 0)
                    {
                        if (TargetDescriptors.Any(x => !x.bQuiet))
                        {
                            Log.TraceInformation((TargetDescriptors.Count == 1)? "Target is up to date" : "Targets are up to date");
                        }
                    }
                    else
                    {
                        if (TargetDescriptors.Any(x => !x.bQuiet))
                        {
                            Log.TraceInformation("Building {0}...", StringUtils.FormatList(TargetDescriptors.Select(x => x.Name).Distinct()));
                        }

                        OutputToolchainInfo(TargetDescriptors, Makefiles);

                        using (Timeline.ScopeEvent("ActionGraph.ExecuteActions()"))
                        {
                            ActionGraph.ExecuteActions(BuildConfiguration, MergedActionsToExecute);
                        }
                    }

                    // Run the deployment steps
                    foreach (TargetMakefile Makefile in Makefiles)
                    {
                        if (Makefile.bDeployAfterCompile)
                        {
                            TargetReceipt Receipt = TargetReceipt.Read(Makefile.ReceiptFile);
                            Log.TraceInformation("Deploying {0} {1} {2}...", Receipt.TargetName, Receipt.Platform, Receipt.Configuration);

                            UEBuildPlatform.GetBuildPlatform(Receipt.Platform).Deploy(Receipt);
                        }
                    }
                }
            }
        }
		private List<string> CollectPluginDataPaths(TargetReceipt Receipt)
		{
			List<string> PluginExtras = new List<string>();
			if (Receipt == null)
			{
				Console.WriteLine("Receipt is NULL");
				//Log.TraceInformation("Receipt is NULL");
				return PluginExtras;
			}

			// collect plugin extra data paths from target receipt
			var Results = Receipt.AdditionalProperties.Where(x => x.Name == "IOSPlugin");
			foreach (var Property in Results)
			{
				// Keep only unique paths
				string PluginPath = Property.Value;
				if (PluginExtras.FirstOrDefault(x => x == PluginPath) == null)
				{
					PluginExtras.Add(PluginPath);
					Log.TraceInformation("IOSPlugin: {0}", PluginPath);
				}
			}
			return PluginExtras;
		}
Beispiel #10
0
        public override void AddFilesToReceipt(TargetReceipt Receipt, UEBuildBinary Binary)
		{
			// The cross-platform code adds .dSYMs for static libraries, which is just wrong, so
			// eliminate them here for now.
			string DebugExtension = UEBuildPlatform.GetBuildPlatform(Binary.Target.Platform).GetDebugInfoExtension(Binary.Config.Type);
			if(DebugExtension == ".dsym")
			{
				for (int i = 0; i < Receipt.BuildProducts.Count; i++)
				{
					if(Path.GetExtension(Receipt.BuildProducts[i].Path) == DebugExtension)
					{
						Receipt.BuildProducts.RemoveAt(i--);
					}
				}

				for (int i = 0; i < Receipt.BuildProducts.Count; i++)
				{
					if(Receipt.BuildProducts[i].Type == BuildProductType.Executable || Receipt.BuildProducts[i].Type == BuildProductType.DynamicLibrary)
					{
						Receipt.AddBuildProduct(Path.ChangeExtension(Receipt.BuildProducts[i].Path, DebugExtension), BuildProductType.SymbolFile);
					}
				}
			}

			if (Binary.Target.GlobalLinkEnvironment.Config.bIsBuildingConsoleApplication)
			{
				return;
			}

			if (BundleContentsDirectory == "" && Binary.Config.Type == UEBuildBinaryType.Executable)
			{
				BundleContentsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Binary.Config.OutputFilePath)) + "/";
			}

			// We need to know what third party dylibs would be copied to the bundle
			if(Binary.Config.Type != UEBuildBinaryType.StaticLibrary)
			{
				var Modules = Binary.GetAllDependencyModules(bIncludeDynamicallyLoaded: false, bForceCircular: false);
				var BinaryLinkEnvironment = Binary.Target.GlobalLinkEnvironment.DeepCopy();
				var BinaryDependencies = new List<UEBuildBinary>();
				var LinkEnvironmentVisitedModules = new Dictionary<UEBuildModule, bool>();
				foreach (var Module in Modules)
				{
					Module.SetupPrivateLinkEnvironment(Binary, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules);
				}

				foreach (string AdditionalLibrary in BinaryLinkEnvironment.Config.AdditionalLibraries)
				{
					string LibName = Path.GetFileName(AdditionalLibrary);
					if (LibName.StartsWith("lib"))
					{
						if (Path.GetExtension(AdditionalLibrary) == ".dylib" && !String.IsNullOrEmpty(BundleContentsDirectory))
						{
							string Entry = BundleContentsDirectory + "MacOS/" + LibName;
							Receipt.AddBuildProduct(Entry, BuildProductType.DynamicLibrary);
						}
					}
				}

				foreach (UEBuildBundleResource Resource in BinaryLinkEnvironment.Config.AdditionalBundleResources)
				{
					if (Directory.Exists(Resource.ResourcePath))
					{
						foreach (string ResourceFile in Directory.GetFiles(Resource.ResourcePath, "*", SearchOption.AllDirectories))
						{
							Receipt.AddBuildProduct(Path.Combine(BundleContentsDirectory, Resource.BundleContentsSubdir, ResourceFile.Substring(Path.GetDirectoryName(Resource.ResourcePath).Length + 1)), BuildProductType.RequiredResource);
						}
					}
					else
					{
						Receipt.AddBuildProduct(Path.Combine(BundleContentsDirectory, Resource.BundleContentsSubdir, Path.GetFileName(Resource.ResourcePath)), BuildProductType.RequiredResource);
					}
				}
			}

			if (Binary.Config.Type == UEBuildBinaryType.Executable)
			{
				// And we also need all the resources
				Receipt.AddBuildProduct(BundleContentsDirectory + "Info.plist", BuildProductType.RequiredResource);
				Receipt.AddBuildProduct(BundleContentsDirectory + "PkgInfo", BuildProductType.RequiredResource);
				Receipt.AddBuildProduct(BundleContentsDirectory + "Resources/UE4.icns", BuildProductType.RequiredResource);

				if (Binary.Target.AppName.StartsWith("UE4Editor"))
				{
					Receipt.AddBuildProduct(BundleContentsDirectory + "Resources/UProject.icns", BuildProductType.RequiredResource);
				}
			}
		}
        public override bool PrepTargetForDeployment(TargetReceipt Receipt)
        {
            // Use the project name if possible - InTarget.AppName changes for 'Client'/'Server' builds
            string ProjectName = Receipt.ProjectFile != null?Receipt.ProjectFile.GetFileNameWithoutAnyExtensions() : Receipt.Launch.GetFileNameWithoutExtension();

            Log.TraceInformation("Prepping {0} for deployment to {1}", ProjectName, Receipt.Platform.ToString());
            System.DateTime PrepDeployStartTime = DateTime.UtcNow;

            // Note: TargetReceipt.Read now expands path variables internally.
            TargetReceipt NewReceipt      = null;
            FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(Receipt.ProjectDir != null ? Receipt.ProjectDir : UnrealBuildTool.EngineDirectory, Receipt.TargetName, Receipt.Platform, Receipt.Configuration, "Multi");

            if (!TargetReceipt.TryRead(ReceiptFileName, UnrealBuildTool.EngineDirectory, out NewReceipt))
            {
                NewReceipt = new TargetReceipt(Receipt.ProjectFile, Receipt.TargetName, Receipt.TargetType, Receipt.Platform, Receipt.Configuration, Receipt.Version, "Multi");
            }

            AddWinMDReferencesFromReceipt(Receipt, Receipt.ProjectDir != null ? Receipt.ProjectDir : UnrealBuildTool.EngineDirectory, UnrealBuildTool.EngineDirectory.ParentDirectory.FullName);

            //PrepForUATPackageOrDeploy(InTarget.ProjectFile, InAppName, InTarget.ProjectDirectory.FullName, InTarget.OutputPath.FullName, TargetBuildEnvironment.RelativeEnginePath, false, "", false);
            List <UnrealTargetConfiguration> TargetConfigs = new List <UnrealTargetConfiguration> {
                Receipt.Configuration
            };
            List <string> ExePaths = new List <string> {
                Receipt.Launch.FullName
            };
            string RelativeEnginePath = UnrealBuildTool.EngineDirectory.MakeRelativeTo(DirectoryReference.GetCurrentDirectory());

            WindowsArchitecture Arch = WindowsArchitecture.ARM64;

            if (Receipt.Architecture.ToLower() == "x64")
            {
                Arch = WindowsArchitecture.x64;
            }

            string SDK     = "";
            var    Results = Receipt.AdditionalProperties.Where(x => x.Name == "SDK");

            if (Results.Any())
            {
                SDK = Results.First().Value;
            }
            HoloLensExports.InitWindowsSdkToolPath(SDK);

            string AbsoluteExeDirectory         = Path.GetDirectoryName(ExePaths[0]);
            UnrealTargetPlatform Platform       = UnrealTargetPlatform.HoloLens;
            string        IntermediateDirectory = Path.Combine(Receipt.ProjectDir != null ? Receipt.ProjectDir.FullName : UnrealBuildTool.EngineDirectory.FullName, "Intermediate", "Deploy", WindowsExports.GetArchitectureSubpath(Arch));
            List <string> UpdatedFiles          = new HoloLensManifestGenerator().CreateManifest(Platform, Arch, AbsoluteExeDirectory, IntermediateDirectory, Receipt.ProjectFile, Receipt.ProjectDir != null ? Receipt.ProjectDir.FullName : UnrealBuildTool.EngineDirectory.FullName, TargetConfigs, ExePaths, WinMDReferences);

            PrepForUATPackageOrDeploy(Receipt.ProjectFile, ProjectName, Receipt.ProjectDir != null ? Receipt.ProjectDir.FullName : UnrealBuildTool.EngineDirectory.FullName, Arch, TargetConfigs, ExePaths, RelativeEnginePath, false, "", false);
            MakePackage(Receipt, NewReceipt, Arch, UpdatedFiles);
            CopyDataAndSymbolsBetweenReceipts(Receipt, NewReceipt, Arch);

            NewReceipt.Write(ReceiptFileName, UnrealBuildTool.EngineDirectory);

            // Log out the time taken to deploy...
            double PrepDeployDuration = (DateTime.UtcNow - PrepDeployStartTime).TotalSeconds;

            Log.TraceInformation("HoloLens deployment preparation took {0:0.00} seconds", PrepDeployDuration);

            return(true);
        }
        private void MakePackage(TargetReceipt Receipt, TargetReceipt NewReceipt, WindowsArchitecture Architecture, List <string> UpdatedFiles)
        {
            string OutputName             = String.Format("{0}_{1}_{2}_{3}", Receipt.TargetName, Receipt.Platform, Receipt.Configuration, WindowsExports.GetArchitectureSubpath(Architecture));
            string IntermediateDirectory  = Path.Combine(Receipt.ProjectDir != null ? Receipt.ProjectDir.FullName : UnrealBuildTool.EngineDirectory.FullName, "Intermediate", "Deploy", WindowsExports.GetArchitectureSubpath(Architecture));
            string OutputDirectory        = Receipt.Launch.Directory.FullName;
            string OutputAppX             = Path.Combine(OutputDirectory, OutputName + ".appx");
            string SigningCertificate     = @"Build\HoloLens\SigningCertificate.pfx";
            string SigningCertificatePath = Path.Combine(Receipt.ProjectDir != null ? Receipt.ProjectDir.FullName : UnrealBuildTool.EngineDirectory.FullName, SigningCertificate);

            string MapFilename = Path.Combine(IntermediateDirectory, OutputName + ".pkgmap");
            var    LocalRoot   = Receipt.ProjectDir;
            var    EngineRoot  = UnrealBuildTool.RootDirectory;
            var    AddedFiles  = new Dictionary <string, string>();
            bool   PackageFileNeedToBeUpdated = !File.Exists(OutputAppX);

            DateTime AppXTime = DateTime.Now;

            PackageFileNeedToBeUpdated = true;

            if (!PackageFileNeedToBeUpdated)
            {
                AppXTime = File.GetLastWriteTimeUtc(OutputAppX);
            }

            {
                foreach (var Product in Receipt.BuildProducts)
                {
                    if (Product.Type == BuildProductType.Executable || Product.Type == BuildProductType.DynamicLibrary || Product.Type == BuildProductType.RequiredResource)
                    {
                        string Filename;
                        if (AddedFiles.ContainsKey(Product.Path.FullName))
                        {
                            continue;
                        }

                        if (LocalRoot != null && Product.Path.IsUnderDirectory(LocalRoot))
                        {
                            Filename = Product.Path.MakeRelativeTo(LocalRoot.ParentDirectory);
                        }
                        else if (Product.Path.IsUnderDirectory(EngineRoot))
                        {
                            Filename = Product.Path.MakeRelativeTo(EngineRoot);
                        }
                        else
                        {
                            throw new BuildException("Failed to parse target receipt file.  See log for details.");
                        }

                        AddedFiles.Add(Product.Path.FullName, Filename);
                    }
                }

                foreach (var Dep in Receipt.RuntimeDependencies)
                {
                    if (Dep.Type == StagedFileType.NonUFS)
                    {
                        if (AddedFiles.ContainsKey(Dep.Path.FullName))
                        {
                            continue;
                        }

                        string Filename;
                        if (LocalRoot != null && Dep.Path.IsUnderDirectory(LocalRoot))
                        {
                            Filename = Dep.Path.MakeRelativeTo(LocalRoot.ParentDirectory);
                        }
                        else if (Dep.Path.IsUnderDirectory(EngineRoot))
                        {
                            Filename = Dep.Path.MakeRelativeTo(EngineRoot);
                        }
                        else
                        {
                            throw new BuildException("Failed to parse target receipt file.  See log for details.");
                        }

                        AddedFiles.Add(Dep.Path.FullName, Filename);
                    }
                }
            }

            string ManifestName = String.Format("AppxManifest_{0}.xml", WindowsExports.GetArchitectureSubpath(Architecture));

            AddedFiles.Add(Path.Combine(OutputDirectory, ManifestName), "AppxManifest.xml");

            //manually add resources
            string PriFileName = String.Format("resources_{0}.pri", WindowsExports.GetArchitectureSubpath(Architecture));

            AddedFiles.Add(Path.Combine(OutputDirectory, PriFileName), "resources.pri");
            {
                DirectoryReference ResourceFolder = DirectoryReference.Combine(Receipt.Launch.Directory, WindowsExports.GetArchitectureSubpath(Architecture));
                foreach (var ResourcePath in UpdatedFiles)
                {
                    var ResourceFile = new FileReference(ResourcePath);

                    if (ResourceFile.IsUnderDirectory(ResourceFolder))
                    {
                        AddedFiles.Add(ResourceFile.FullName, ResourceFile.MakeRelativeTo(ResourceFolder));
                    }
                    else
                    {
                        Log.TraceError("Wrong path to resource \'{0}\', the resource should be in \'{1}\'", ResourceFile.FullName, ResourceFolder.FullName);
                        throw new BuildException("Failed to generate AppX file.  See log for details.");
                    }
                }
            }


            FileReference SourceNetworkManifestPath = new FileReference(Path.Combine(OutputDirectory, "NetworkManifest.xml"));

            if (FileReference.Exists(SourceNetworkManifestPath))
            {
                AddedFiles.Add(SourceNetworkManifestPath.FullName, "NetworkManifest.xml");
            }
            FileReference SourceXboxConfigPath = new FileReference(Path.Combine(OutputDirectory, "xboxservices.config"));

            if (FileReference.Exists(SourceXboxConfigPath))
            {
                AddedFiles.Add(SourceXboxConfigPath.FullName, "xboxservices.config");
            }

            do
            {
                if (PackageFileNeedToBeUpdated)
                {
                    break;
                }

                if (!File.Exists(MapFilename))
                {
                    PackageFileNeedToBeUpdated = true;
                    break;
                }
                string[] lines      = File.ReadAllLines(MapFilename, Encoding.UTF8);
                int      filesCount = 0;

                foreach (var line in lines)
                {
                    if (line[0] == '[')
                    {
                        continue;
                    }

                    string[] files = line.Split('\t');

                    if (files.Length != 2)
                    {
                        PackageFileNeedToBeUpdated = true;
                        break;
                    }

                    files[0] = files[0].Trim('\"');
                    files[1] = files[1].Trim('\"');

                    if (!AddedFiles.ContainsKey(files[0]))
                    {
                        PackageFileNeedToBeUpdated = true;
                        break;
                    }

                    if (AddedFiles[files[0]] != files[1])
                    {
                        PackageFileNeedToBeUpdated = true;
                        break;
                    }

                    if (File.GetLastWriteTimeUtc(files[0]).CompareTo(AppXTime) >= 0)
                    {
                        PackageFileNeedToBeUpdated = true;
                        break;
                    }

                    ++filesCount;
                }

                if (PackageFileNeedToBeUpdated)
                {
                    break;
                }

                if (filesCount != AddedFiles.Count)
                {
                    PackageFileNeedToBeUpdated = true;
                    break;
                }

                if (File.Exists(SigningCertificatePath) && File.GetLastWriteTimeUtc(SigningCertificatePath).CompareTo(AppXTime) >= 0)
                {
                    PackageFileNeedToBeUpdated = true;
                    break;
                }
            }while(false);

            if (!PackageFileNeedToBeUpdated)
            {
                NewReceipt.BuildProducts.Add(new BuildProduct(new FileReference(OutputAppX), BuildProductType.Package));
                return;
            }

            try
            {
                DeployHelper_DeleteFile(OutputAppX);
            }
            catch (Exception exceptionMessage)
            {
                Log.TraceError("Failed to delete {0} from deployment: {1}", OutputAppX, exceptionMessage);
                throw new BuildException("Failed to generate AppX file.  See log for details.");
            }

            var AppXRecipeBuiltFiles = new StringBuilder();

            AppXRecipeBuiltFiles.AppendLine(@"[Files]");
            foreach (var f in AddedFiles)
            {
                AppXRecipeBuiltFiles.AppendLine(String.Format("\"{0}\"\t\"{1}\"", f.Key, f.Value));
            }
            File.WriteAllText(MapFilename, AppXRecipeBuiltFiles.ToString(), Encoding.UTF8);

            NewReceipt.BuildProducts.Add(new BuildProduct(new FileReference(MapFilename), BuildProductType.MapFile));
        }
Beispiel #13
0
		/// <summary>
		/// Read a receipt from disk.
		/// </summary>
		/// <param name="FileName">Filename to read from</param>
		public static bool TryRead(string FileName, out TargetReceipt Receipt)
		{
			if (!File.Exists(FileName))
			{
				Receipt = null;
				return false;
			}

			try
			{
				using (StreamReader Reader = new StreamReader(FileName))
				{
					Receipt = (TargetReceipt)Serializer.Deserialize(Reader);
					return true;
				}
			}
			catch(Exception)
			{
				Receipt = null;
				return false;
			}
		}
 /// <summary>
 /// Deploys the given target
 /// </summary>
 /// <param name="Receipt">Receipt for the target being deployed</param>
 public override void Deploy(TargetReceipt Receipt)
 {
     new UEDeployLumin(Receipt.ProjectFile).PrepTargetForDeployment(Receipt);
 }
Beispiel #15
0
        /// <summary>
        /// Read a receipt from disk.
        /// </summary>
        /// <param name="FileName">Filename to read from</param>
        public static TargetReceipt Read(string FileName)
        {
            JsonObject RawObject = JsonObject.Read(FileName);

            // Read the initial fields
            string TargetName = RawObject.GetStringField("TargetName");
            UnrealTargetPlatform      Platform      = RawObject.GetEnumField <UnrealTargetPlatform>("Platform");
            UnrealTargetConfiguration Configuration = RawObject.GetEnumField <UnrealTargetConfiguration>("Configuration");
            string BuildId = RawObject.GetStringField("BuildId");

            // Try to read the build version
            BuildVersion Version;

            if (!BuildVersion.TryParse(RawObject.GetObjectField("Version"), out Version))
            {
                throw new JsonParseException("Invalid 'Version' field");
            }

            // Create the receipt
            TargetReceipt Receipt = new TargetReceipt(TargetName, Platform, Configuration, BuildId, Version);

            // Read the build products
            JsonObject[] BuildProductObjects;
            if (RawObject.TryGetObjectArrayField("BuildProducts", out BuildProductObjects))
            {
                foreach (JsonObject BuildProductObject in BuildProductObjects)
                {
                    string           Path;
                    BuildProductType Type;
                    if (BuildProductObject.TryGetStringField("Path", out Path) && BuildProductObject.TryGetEnumField("Type", out Type))
                    {
                        string Module;
                        BuildProductObject.TryGetStringField("Module", out Module);

                        BuildProduct NewBuildProduct = Receipt.AddBuildProduct(Path, Type);

                        bool IsPrecompiled;
                        if (BuildProductObject.TryGetBoolField("IsPrecompiled", out IsPrecompiled))
                        {
                            NewBuildProduct.IsPrecompiled = IsPrecompiled;
                        }
                    }
                }
            }

            // Read the runtime dependencies
            JsonObject[] RuntimeDependencyObjects;
            if (RawObject.TryGetObjectArrayField("RuntimeDependencies", out RuntimeDependencyObjects))
            {
                foreach (JsonObject RuntimeDependencyObject in RuntimeDependencyObjects)
                {
                    string Path;
                    if (RuntimeDependencyObject.TryGetStringField("Path", out Path))
                    {
                        string StagePath;
                        if (!RuntimeDependencyObject.TryGetStringField("StagePath", out StagePath))
                        {
                            StagePath = null;
                        }
                        bool bIgnoreIfMissing;
                        if (!RuntimeDependencyObject.TryGetBoolField("IgnoreIfMissing", out bIgnoreIfMissing))
                        {
                            bIgnoreIfMissing = false;
                        }
                        Receipt.AddRuntimeDependency(Path, StagePath, bIgnoreIfMissing);
                    }
                }
            }

            // Read the additional properties
            JsonObject[] AdditionalPropertyObjects;
            if (RawObject.TryGetObjectArrayField("AdditionalProperties", out AdditionalPropertyObjects))
            {
                foreach (JsonObject AdditionalPropertyObject in AdditionalPropertyObjects)
                {
                    string Name;
                    if (AdditionalPropertyObject.TryGetStringField("Name", out Name))
                    {
                        string Value;
                        if (AdditionalPropertyObject.TryGetStringField("Value", out Value))
                        {
                            Receipt.AdditionalProperties.Add(new ReceiptProperty(Name, Value));
                        }
                    }
                }
            }

            return(Receipt);
        }
Beispiel #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Config"></param>
        /// <param name="ProjectFile"></param>
        /// <param name="InProjectName"></param>
        /// <param name="InProjectDirectory"></param>
        /// <param name="InExecutablePath"></param>
        /// <param name="InEngineDir"></param>
        /// <param name="bForDistribution"></param>
        /// <param name="CookFlavor"></param>
        /// <param name="bIsDataDeploy"></param>
        /// <param name="bCreateStubIPA"></param>
        /// <param name="BuildReceiptFileName"></param>
        /// <returns></returns>
        public static bool PrepForUATPackageOrDeploy(UnrealTargetConfiguration Config, FileReference ProjectFile, string InProjectName, DirectoryReference InProjectDirectory, string InExecutablePath, DirectoryReference InEngineDir, bool bForDistribution, string CookFlavor, bool bIsDataDeploy, bool bCreateStubIPA, FileReference BuildReceiptFileName)
        {
            TargetReceipt Receipt = TargetReceipt.Read(BuildReceiptFileName);

            return(new UEDeployIOS().PrepForUATPackageOrDeploy(Config, ProjectFile, InProjectName, InProjectDirectory.FullName, InExecutablePath, InEngineDir.FullName, bForDistribution, CookFlavor, bIsDataDeploy, bCreateStubIPA, Receipt));
        }
        /// <summary>
        /// Build a list of targets with a given set of makefiles.
        /// </summary>
        /// <param name="Makefiles">Makefiles created with CreateMakefiles</param>
        /// <param name="TargetDescriptors">Target descriptors</param>
        /// <param name="BuildConfiguration">Current build configuration</param>
        /// <param name="WorkingSet">The source file working set</param>
        /// <param name="Options">Additional options for the build</param>
        /// <param name="WriteOutdatedActionsFile">Files to write the list of outdated actions to (rather than building them)</param>
        /// <returns>Result from the compilation</returns>
        static void Build(TargetMakefile[] Makefiles, List <TargetDescriptor> TargetDescriptors, BuildConfiguration BuildConfiguration, ISourceFileWorkingSet WorkingSet, BuildOptions Options, FileReference WriteOutdatedActionsFile)
        {
            // Export the actions for each target
            for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
            {
                TargetDescriptor TargetDescriptor = TargetDescriptors[TargetIdx];
                foreach (FileReference WriteActionFile in TargetDescriptor.WriteActionFiles)
                {
                    Log.TraceInformation("Writing actions to {0}", WriteActionFile);
                    ActionGraph.ExportJson(Makefiles[TargetIdx].Actions, WriteActionFile);
                }
            }

            // Execute the build
            if ((Options & BuildOptions.SkipBuild) == 0)
            {
                // Make sure that none of the actions conflict with any other (producing output files differently, etc...)
                ActionGraph.CheckForConflicts(Makefiles.SelectMany(x => x.Actions));

                // Check we don't exceed the nominal max path length
                using (Timeline.ScopeEvent("ActionGraph.CheckPathLengths"))
                {
                    ActionGraph.CheckPathLengths(BuildConfiguration, Makefiles.SelectMany(x => x.Actions));
                }

                // Clean up any previous hot reload runs, and reapply the current state if it's already active
                for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
                {
                    HotReload.Setup(TargetDescriptors[TargetIdx], Makefiles[TargetIdx], BuildConfiguration);
                }

                // Merge the action graphs together
                List <Action> MergedActions;
                if (TargetDescriptors.Count == 1)
                {
                    MergedActions = new List <Action>(Makefiles[0].Actions);
                }
                else
                {
                    MergedActions = MergeActionGraphs(TargetDescriptors, Makefiles);
                }

                // Gather all the prerequisite actions that are part of the targets
                HashSet <FileItem> MergedOutputItems = new HashSet <FileItem>();
                for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
                {
                    GatherOutputItems(TargetDescriptors[TargetIdx], Makefiles[TargetIdx], MergedOutputItems);
                }

                // Link all the actions together
                ActionGraph.Link(MergedActions);

                // Get all the actions that are prerequisites for these targets. This forms the list of actions that we want executed.
                List <Action> PrerequisiteActions = ActionGraph.GatherPrerequisiteActions(MergedActions, MergedOutputItems);

                // Create the action history
                ActionHistory History = new ActionHistory();
                for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
                {
                    using (Timeline.ScopeEvent("Reading action history"))
                    {
                        TargetDescriptor TargetDescriptor = TargetDescriptors[TargetIdx];
                        if (TargetDescriptor.ProjectFile != null)
                        {
                            History.Mount(TargetDescriptor.ProjectFile.Directory);
                        }
                    }
                }

                // Figure out which actions need to be built
                Dictionary <Action, bool> ActionToOutdatedFlag = new Dictionary <Action, bool>();
                for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
                {
                    TargetDescriptor TargetDescriptor = TargetDescriptors[TargetIdx];

                    // Create the dependencies cache
                    CppDependencyCache CppDependencies;
                    using (Timeline.ScopeEvent("Reading dependency cache"))
                    {
                        CppDependencies = CppDependencyCache.CreateHierarchy(TargetDescriptor.ProjectFile, TargetDescriptor.Name, TargetDescriptor.Platform, TargetDescriptor.Configuration, Makefiles[TargetIdx].TargetType, TargetDescriptor.Architecture);
                    }

                    // Plan the actions to execute for the build. For single file compiles, always rebuild the source file regardless of whether it's out of date.
                    if (TargetDescriptor.SpecificFilesToCompile.Count == 0)
                    {
                        ActionGraph.GatherAllOutdatedActions(PrerequisiteActions, History, ActionToOutdatedFlag, CppDependencies, BuildConfiguration.bIgnoreOutdatedImportLibraries);
                    }
                    else
                    {
                        foreach (FileReference SpecificFile in TargetDescriptor.SpecificFilesToCompile)
                        {
                            foreach (Action PrerequisiteAction in PrerequisiteActions.Where(x => x.PrerequisiteItems.Any(y => y.Location == SpecificFile)))
                            {
                                ActionToOutdatedFlag[PrerequisiteAction] = true;
                            }
                        }
                    }
                }

                // Link the action graph again to sort it
                List <Action> MergedActionsToExecute = ActionToOutdatedFlag.Where(x => x.Value).Select(x => x.Key).ToList();
                ActionGraph.Link(MergedActionsToExecute);

                // Allow hot reload to override the actions
                int HotReloadTargetIdx = -1;
                for (int Idx = 0; Idx < TargetDescriptors.Count; Idx++)
                {
                    if (TargetDescriptors[Idx].HotReloadMode != HotReloadMode.Disabled)
                    {
                        if (HotReloadTargetIdx != -1)
                        {
                            throw new BuildException("Unable to perform hot reload with multiple targets.");
                        }
                        else
                        {
                            MergedActionsToExecute = HotReload.PatchActionsForTarget(BuildConfiguration, TargetDescriptors[Idx], Makefiles[Idx], PrerequisiteActions, MergedActionsToExecute);
                        }
                        HotReloadTargetIdx = Idx;
                    }
                }

                // Make sure we're not modifying any engine files
                if ((Options & BuildOptions.NoEngineChanges) != 0)
                {
                    List <FileItem> EngineChanges = MergedActionsToExecute.SelectMany(x => x.ProducedItems).Where(x => x.Location.IsUnderDirectory(UnrealBuildTool.EngineDirectory)).Distinct().OrderBy(x => x.FullName).ToList();
                    if (EngineChanges.Count > 0)
                    {
                        StringBuilder Result = new StringBuilder("Building would modify the following engine files:\n");
                        foreach (FileItem EngineChange in EngineChanges)
                        {
                            Result.AppendFormat("\n{0}", EngineChange.FullName);
                        }
                        Result.Append("\n\nPlease rebuild from an IDE instead.");
                        Log.TraceError("{0}", Result.ToString());
                        throw new CompilationResultException(CompilationResult.FailedDueToEngineChange);
                    }
                }

                // Make sure the appropriate executor is selected
                foreach (TargetDescriptor TargetDescriptor in TargetDescriptors)
                {
                    UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(TargetDescriptor.Platform);
                    BuildConfiguration.bAllowXGE    &= BuildPlatform.CanUseXGE();
                    BuildConfiguration.bAllowDistcc &= BuildPlatform.CanUseDistcc();
                    BuildConfiguration.bAllowSNDBS  &= BuildPlatform.CanUseSNDBS();
                }

                // Delete produced items that are outdated.
                ActionGraph.DeleteOutdatedProducedItems(MergedActionsToExecute);

                // Save all the action histories now that files have been removed. We have to do this after deleting produced items to ensure that any
                // items created during the build don't have the wrong command line.
                History.Save();

                // Create directories for the outdated produced items.
                ActionGraph.CreateDirectoriesForProducedItems(MergedActionsToExecute);

                // Execute the actions
                if ((Options & BuildOptions.XGEExport) != 0)
                {
                    OutputToolchainInfo(TargetDescriptors, Makefiles);

                    // Just export to an XML file
                    using (Timeline.ScopeEvent("XGE.ExportActions()"))
                    {
                        XGE.ExportActions(MergedActionsToExecute);
                    }
                }
                else if (WriteOutdatedActionsFile != null)
                {
                    OutputToolchainInfo(TargetDescriptors, Makefiles);

                    // Write actions to an output file
                    using (Timeline.ScopeEvent("ActionGraph.WriteActions"))
                    {
                        ActionGraph.ExportJson(MergedActionsToExecute, WriteOutdatedActionsFile);
                    }
                }
                else
                {
                    // Execute the actions
                    if (MergedActionsToExecute.Count == 0)
                    {
                        if (TargetDescriptors.Any(x => !x.bQuiet))
                        {
                            Log.TraceInformation((TargetDescriptors.Count == 1)? "Target is up to date" : "Targets are up to date");
                        }
                    }
                    else
                    {
                        if (TargetDescriptors.Any(x => !x.bQuiet))
                        {
                            Log.TraceInformation("Building {0}...", StringUtils.FormatList(TargetDescriptors.Select(x => x.Name).Distinct()));
                        }

                        OutputToolchainInfo(TargetDescriptors, Makefiles);

                        using (Timeline.ScopeEvent("ActionGraph.ExecuteActions()"))
                        {
                            ActionGraph.ExecuteActions(BuildConfiguration, MergedActionsToExecute);
                        }
                    }

                    // Run the deployment steps
                    foreach (TargetMakefile Makefile in Makefiles)
                    {
                        if (Makefile.bDeployAfterCompile)
                        {
                            TargetReceipt Receipt = TargetReceipt.Read(Makefile.ReceiptFile);
                            Log.TraceInformation("Deploying {0} {1} {2}...", Receipt.TargetName, Receipt.Platform, Receipt.Configuration);

                            UEBuildPlatform.GetBuildPlatform(Receipt.Platform).Deploy(Receipt);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Deploys the given target
 /// </summary>
 /// <param name="Receipt">Receipt for the target being deployed</param>
 public abstract void Deploy(TargetReceipt Receipt);
Beispiel #19
0
 /// <summary>
 /// Collect all the WinMD references
 /// </summary>
 /// <param name="Receipt"></param>
 /// <param name="SourceProjectDir"></param>
 /// <param name="DestPackageRoot"></param>
 public void AddWinMDReferencesFromReceipt(TargetReceipt Receipt, DirectoryReference SourceProjectDir, string DestPackageRoot)
 {
     InnerDeploy.AddWinMDReferencesFromReceipt(Receipt, SourceProjectDir, DestPackageRoot);
 }
Beispiel #20
0
		public override void AddFilesToReceipt(TargetReceipt Receipt, UEBuildBinary Binary)
		{
			if (Binary.Config.Type == UEBuildBinaryType.DynamicLinkLibrary)
			{
				Receipt.AddBuildProduct(Path.Combine(Binary.Config.IntermediateDirectory, Path.GetFileNameWithoutExtension(Binary.Config.OutputFilePath) + ".lib"), BuildProductType.ImportLibrary);
			}
		}
        /// <summary>
        /// Read a receipt from disk.
        /// </summary>
        /// <param name="Location">Filename to read from</param>
        /// <param name="EngineDir">Engine directory for expanded variables</param>
        public static TargetReceipt Read(FileReference Location, DirectoryReference EngineDir)
        {
            JsonObject RawObject = JsonObject.Read(Location);

            // Read the initial fields
            string                    TargetName    = RawObject.GetStringField("TargetName");
            TargetType                TargetType    = RawObject.GetEnumField <TargetType>("TargetType");
            UnrealTargetPlatform      Platform      = RawObject.GetEnumField <UnrealTargetPlatform>("Platform");
            UnrealTargetConfiguration Configuration = RawObject.GetEnumField <UnrealTargetConfiguration>("Configuration");

            // Try to read the build version
            BuildVersion Version;

            if (!BuildVersion.TryParse(RawObject.GetObjectField("Version"), out Version))
            {
                throw new JsonParseException("Invalid 'Version' field");
            }

            // Read the project path
            FileReference ProjectFile;

            string RelativeProjectFile;

            if (RawObject.TryGetStringField("Project", out RelativeProjectFile))
            {
                ProjectFile = FileReference.Combine(Location.Directory, RelativeProjectFile);
            }
            else
            {
                ProjectFile = null;
            }

            // Create the receipt
            TargetReceipt Receipt = new TargetReceipt(ProjectFile, TargetName, TargetType, Platform, Configuration, Version);

            // Get the project directory
            DirectoryReference ProjectDir = Receipt.ProjectDir;

            // Read the launch executable
            string Launch;

            if (RawObject.TryGetStringField("Launch", out Launch))
            {
                Receipt.Launch = ExpandPathVariables(Launch, EngineDir, ProjectDir);
            }

            // Read the build products
            JsonObject[] BuildProductObjects;
            if (RawObject.TryGetObjectArrayField("BuildProducts", out BuildProductObjects))
            {
                foreach (JsonObject BuildProductObject in BuildProductObjects)
                {
                    string           Path;
                    BuildProductType Type;
                    if (BuildProductObject.TryGetStringField("Path", out Path) && BuildProductObject.TryGetEnumField("Type", out Type))
                    {
                        FileReference File = ExpandPathVariables(Path, EngineDir, ProjectDir);

                        string Module;
                        BuildProductObject.TryGetStringField("Module", out Module);

                        Receipt.AddBuildProduct(File, Type);
                    }
                }
            }

            // Read the runtime dependencies
            JsonObject[] RuntimeDependencyObjects;
            if (RawObject.TryGetObjectArrayField("RuntimeDependencies", out RuntimeDependencyObjects))
            {
                foreach (JsonObject RuntimeDependencyObject in RuntimeDependencyObjects)
                {
                    string Path;
                    if (RuntimeDependencyObject.TryGetStringField("Path", out Path))
                    {
                        FileReference File = ExpandPathVariables(Path, EngineDir, ProjectDir);

                        StagedFileType Type;
                        if (!RuntimeDependencyObject.TryGetEnumField("Type", out Type))
                        {
                            // Previous format included an optional IgnoreIfMissing flag, which was only used for debug files. We can explicitly reference them as DebugNonUFS files now.
                            bool bIgnoreIfMissing;
                            if (RuntimeDependencyObject.TryGetBoolField("IgnoreIfMissing", out bIgnoreIfMissing))
                            {
                                bIgnoreIfMissing = false;
                            }
                            Type = bIgnoreIfMissing? StagedFileType.DebugNonUFS : StagedFileType.NonUFS;
                        }

                        Receipt.RuntimeDependencies.Add(File, Type);
                    }
                }
            }

            // Read the additional properties
            JsonObject[] AdditionalPropertyObjects;
            if (RawObject.TryGetObjectArrayField("AdditionalProperties", out AdditionalPropertyObjects))
            {
                foreach (JsonObject AdditionalPropertyObject in AdditionalPropertyObjects)
                {
                    string Name;
                    if (AdditionalPropertyObject.TryGetStringField("Name", out Name))
                    {
                        string Value;
                        if (AdditionalPropertyObject.TryGetStringField("Value", out Value))
                        {
                            Receipt.AdditionalProperties.Add(new ReceiptProperty(Name, Value));
                        }
                    }
                }
            }

            return(Receipt);
        }
		/// <summary>
		/// Checks if all the files in a receipt are present and that all the DLLs are at the same version
		/// </summary>
		/// <returns>
		/// True if all the files are valid.
		/// </returns>
		static DateTime GetTimestampFromBinaries(TargetReceipt Receipt)
		{
			DateTime LatestWriteTime = DateTime.MinValue;
			foreach(BuildProduct BuildProduct in Receipt.BuildProducts)
			{
				if(BuildProduct.Type == BuildProductType.Executable || BuildProduct.Type == BuildProductType.DynamicLibrary)
				{
					DateTime WriteTime = File.GetLastWriteTime(BuildProduct.Path);
					if(WriteTime > LatestWriteTime)
					{
						LatestWriteTime = WriteTime;
					}
				}
			}
			return LatestWriteTime;
		}
 /// <summary>
 /// Try to read a receipt from disk, failing gracefully if it can't be read.
 /// </summary>
 /// <param name="Location">Filename to read from</param>
 /// <param name="Receipt">If successful, the receipt that was read</param>
 /// <returns>True if successful</returns>
 public static bool TryRead(FileReference Location, out TargetReceipt Receipt)
 {
     return(TryRead(Location, UnrealBuildTool.EngineDirectory, out Receipt));
 }
	public void StageBuildProductsFromReceipt(TargetReceipt Receipt, bool RequireDependenciesToExist, bool TreatNonShippingBinariesAsDebugFiles)
	{
		// Stage all the build products needed at runtime
		foreach(BuildProduct BuildProduct in Receipt.BuildProducts)
		{
			// allow missing files if needed
			if (RequireDependenciesToExist == false && File.Exists(BuildProduct.Path) == false)
			{
				continue;
			}

			if(BuildProduct.Type == BuildProductType.Executable || BuildProduct.Type == BuildProductType.DynamicLibrary || BuildProduct.Type == BuildProductType.RequiredResource)
			{
				StagedFileType FileTypeToUse = StagedFileType.NonUFS;
				if (TreatNonShippingBinariesAsDebugFiles && Receipt.Configuration != UnrealTargetConfiguration.Shipping)
				{
					FileTypeToUse = StagedFileType.DebugNonUFS;
				}

				StageFile(FileTypeToUse, BuildProduct.Path);
			}
			else if(BuildProduct.Type == BuildProductType.SymbolFile || BuildProduct.Type == BuildProductType.MapFile)
			{
				// Symbol files aren't true dependencies so we can skip if they don't exist
				if (File.Exists(BuildProduct.Path))
				{
					StageFile(StagedFileType.DebugNonUFS, BuildProduct.Path);
				}
			}
		}
	}
        /// <summary>
        /// Try to read a receipt from disk, failing gracefully if it can't be read.
        /// </summary>
        /// <param name="Location">Filename to read from</param>
        /// <param name="EngineDir">Engine directory for expanded paths</param>
        /// <param name="Receipt">If successful, the receipt that was read</param>
        /// <returns>True if successful</returns>
        public static bool TryRead(FileReference Location, DirectoryReference EngineDir, out TargetReceipt Receipt)
        {
            if (!FileReference.Exists(Location))
            {
                Receipt = null;
                return(false);
            }

            try
            {
                Receipt = Read(Location, EngineDir);
                return(true);
            }
            catch (Exception)
            {
                Receipt = null;
                return(false);
            }
        }
Beispiel #26
0
		public virtual void AddFilesToReceipt(TargetReceipt Receipt, UEBuildBinary Binary)
		{
		}
Beispiel #27
0
 /// <summary>
 /// Deploys the given target
 /// </summary>
 /// <param name="Receipt">Information about the target being deployed</param>
 public override void Deploy(TargetReceipt Receipt)
 {
     new HoloLensDeploy().PrepTargetForDeployment(Receipt);
 }
Beispiel #28
0
        /// <summary>
        /// Execute the command, having obtained the appropriate mutex
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        private int ExecuteInternal(CommandLineArguments Arguments)
        {
            // Read the target info
            WriteMetadataTargetInfo TargetInfo = BinaryFormatterUtils.Load <WriteMetadataTargetInfo>(Arguments.GetFileReference("-Input="));
            bool bNoManifestChanges            = Arguments.HasOption("-NoManifestChanges");
            int  VersionNumber = Arguments.GetInteger("-Version=");

            Arguments.CheckAllArgumentsUsed();

            // Make sure the version number is correct
            if (VersionNumber != CurrentVersionNumber)
            {
                throw new BuildException("Version number to WriteMetadataMode is incorrect (expected {0}, got {1})", CurrentVersionNumber, VersionNumber);
            }

            // Check if we need to set a build id
            TargetReceipt Receipt = TargetInfo.Receipt;

            if (Receipt.Version.BuildId == null)
            {
                // Check if there's an exist version file. If it exists, try to merge in any manifests that are valid (and reuse the existing build id)
                BuildVersion PreviousVersion;
                if (TargetInfo.VersionFile != null && BuildVersion.TryRead(TargetInfo.VersionFile, out PreviousVersion))
                {
                    // Check if we can reuse the existing manifests. This prevents unnecessary builds when switching between projects.
                    Dictionary <FileReference, ModuleManifest> PreviousFileToManifest = new Dictionary <FileReference, ModuleManifest>();
                    if (TryRecyclingManifests(PreviousVersion.BuildId, TargetInfo.FileToManifest.Keys, PreviousFileToManifest))
                    {
                        // Merge files from the existing manifests with the new ones
                        foreach (KeyValuePair <FileReference, ModuleManifest> Pair in PreviousFileToManifest)
                        {
                            ModuleManifest TargetManifest = TargetInfo.FileToManifest[Pair.Key];
                            MergeManifests(Pair.Value, TargetManifest);
                        }

                        // Update the build id to use the current one
                        Receipt.Version.BuildId = PreviousVersion.BuildId;
                    }
                }

                // If the build id is still not set, generate a new one from a GUID
                if (Receipt.Version.BuildId == null)
                {
                    Receipt.Version.BuildId = Guid.NewGuid().ToString();
                }
            }
            else
            {
                // Read all the manifests and merge them into the new ones, if they have the same build id
                foreach (KeyValuePair <FileReference, ModuleManifest> Pair in TargetInfo.FileToManifest)
                {
                    ModuleManifest SourceManifest;
                    if (TryReadManifest(Pair.Key, out SourceManifest) && SourceManifest.BuildId == Receipt.Version.BuildId)
                    {
                        MergeManifests(SourceManifest, Pair.Value);
                    }
                }
            }

            // Update the build id in all the manifests, and write them out
            foreach (KeyValuePair <FileReference, ModuleManifest> Pair in TargetInfo.FileToManifest)
            {
                FileReference ManifestFile = Pair.Key;
                if (!UnrealBuildTool.IsFileInstalled(ManifestFile))
                {
                    ModuleManifest Manifest = Pair.Value;
                    Manifest.BuildId = Receipt.Version.BuildId;

                    if (!FileReference.Exists(ManifestFile))
                    {
                        // If the file doesn't already exist, just write it out
                        DirectoryReference.CreateDirectory(ManifestFile.Directory);
                        Manifest.Write(ManifestFile);
                    }
                    else
                    {
                        // Otherwise write it to a buffer first
                        string OutputText;
                        using (StringWriter Writer = new StringWriter())
                        {
                            Manifest.Write(Writer);
                            OutputText = Writer.ToString();
                        }

                        // And only write it to disk if it's been modified. Note that if a manifest is out of date, we should have generated a new build id causing the contents to differ.
                        string CurrentText = FileReference.ReadAllText(ManifestFile);
                        if (CurrentText != OutputText)
                        {
                            if (bNoManifestChanges)
                            {
                                Log.TraceError("Build modifies {0}. This is not permitted. Before:\n    {1}\nAfter:\n    {2}", ManifestFile, CurrentText.Replace("\n", "\n    "), OutputText.Replace("\n", "\n    "));
                            }
                            else
                            {
                                FileReference.WriteAllText(ManifestFile, OutputText);
                            }
                        }
                    }
                }
            }

            // Write out the version file, if it's changed. Since this file is next to the executable, it may be used by multiple targets, and we should avoid modifying it unless necessary.
            if (TargetInfo.VersionFile != null && !UnrealBuildTool.IsFileInstalled(TargetInfo.VersionFile))
            {
                DirectoryReference.CreateDirectory(TargetInfo.VersionFile.Directory);

                StringWriter Writer = new StringWriter();
                Receipt.Version.Write(Writer);

                string Text = Writer.ToString();
                if (!FileReference.Exists(TargetInfo.VersionFile) || File.ReadAllText(TargetInfo.VersionFile.FullName) != Text)
                {
                    File.WriteAllText(TargetInfo.VersionFile.FullName, Text);
                }
            }

            // Write out the receipt
            if (!UnrealBuildTool.IsFileInstalled(TargetInfo.ReceiptFile))
            {
                DirectoryReference.CreateDirectory(TargetInfo.ReceiptFile.Directory);
                Receipt.Write(TargetInfo.ReceiptFile);
            }

            return(0);
        }
	public void StageBuildProductsFromReceipt(TargetReceipt Receipt)
	{
		// Stage all the build products needed at runtime
		foreach(BuildProduct BuildProduct in Receipt.BuildProducts)
		{
			// allow missing files if needed
			if (Receipt.bRequireDependenciesToExist == false && File.Exists(BuildProduct.Path) == false)
			{
				continue;
			}

			if(BuildProduct.Type == BuildProductType.Executable || BuildProduct.Type == BuildProductType.DynamicLibrary || BuildProduct.Type == BuildProductType.RequiredResource)
			{
				StageFile(StagedFileType.NonUFS, BuildProduct.Path);
			}
			else if(BuildProduct.Type == BuildProductType.SymbolFile)
			{
				StageFile(StagedFileType.DebugNonUFS, BuildProduct.Path);
			}
		}
	}
Beispiel #30
0
		/// <summary>
		/// Adds a build product and its associated debug file to a receipt.
		/// </summary>
		/// <param name="OutputFile">Build product to add</param>
		/// <param name="DebugExtension">Extension for the matching debug file (may be null).</param>
		/// <param name="Receipt">Receipt to add to</param>
		static void AddBuildProductAndDebugFile(string OutputFile, BuildProductType OutputType, string DebugExtension, TargetReceipt Receipt, IUEToolChain ToolChain)
		{
			Receipt.AddBuildProduct(OutputFile, OutputType);

			if(!String.IsNullOrEmpty(DebugExtension) && ToolChain.ShouldAddDebugFileToReceipt(OutputFile, OutputType))
			{
				Receipt.AddBuildProduct(Path.ChangeExtension(OutputFile, DebugExtension), BuildProductType.SymbolFile);
			}
		}
	public void StageRuntimeDependenciesFromReceipt(TargetReceipt Receipt)
	{
		// Also stage any additional runtime dependencies, like ThirdParty DLLs
		foreach(RuntimeDependency RuntimeDependency in Receipt.RuntimeDependencies)
		{
			// allow missing files if needed
			if (Receipt.bRequireDependenciesToExist == false && File.Exists(RuntimeDependency.Path) == false)
			{
				continue;
			}

			StageFile(StagedFileType.NonUFS, RuntimeDependency.Path, RuntimeDependency.StagePath);
		}
	}
Beispiel #32
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ProjectFile"></param>
        /// <param name="Config"></param>
        /// <param name="ProjectDirectory"></param>
        /// <param name="bIsUE4Game"></param>
        /// <param name="GameName"></param>
        /// <param name="ProjectName"></param>
        /// <param name="InEngineDir"></param>
        /// <param name="AppDirectory"></param>
        /// <param name="BuildReceiptFileName"></param>
        /// <param name="bSupportsPortrait"></param>
        /// <param name="bSupportsLandscape"></param>
        /// <param name="bSkipIcons"></param>
        /// <returns></returns>
        public static bool GeneratePList(FileReference ProjectFile, UnrealTargetConfiguration Config, DirectoryReference ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, DirectoryReference InEngineDir, DirectoryReference AppDirectory, FileReference BuildReceiptFileName, out bool bSupportsPortrait, out bool bSupportsLandscape, out bool bSkipIcons)
        {
            TargetReceipt Receipt = TargetReceipt.Read(BuildReceiptFileName);

            return(new UEDeployIOS().GeneratePList(ProjectFile, Config, ProjectDirectory.FullName, bIsUE4Game, GameName, ProjectName, InEngineDir.FullName, AppDirectory.FullName, Receipt, out bSupportsPortrait, out bSupportsLandscape, out bSkipIcons));
        }
Beispiel #33
0
		public override void AddFilesToReceipt(TargetReceipt Receipt, UEBuildBinary Binary)
		{
			if (BuildConfiguration.bCreateStubIPA && Binary.Config.Type != UEBuildBinaryType.StaticLibrary)
			{
				string StubFile = Path.Combine (Path.GetDirectoryName (Binary.Config.OutputFilePath), Path.GetFileNameWithoutExtension (Binary.Config.OutputFilePath) + ".stub");
				Receipt.AddBuildProduct(StubFile, BuildProductType.Executable);
			}
		}
Beispiel #34
0
        /// <summary>
        /// Build a list of targets
        /// </summary>
        /// <param name="TargetDescriptors">Target descriptors</param>
        /// <param name="BuildConfiguration">Current build configuration</param>
        /// <param name="WorkingSet">The source file working set</param>
        /// <param name="Options">Additional options for the build</param>
        /// <returns>Result from the compilation</returns>
        public static void Build(List <TargetDescriptor> TargetDescriptors, BuildConfiguration BuildConfiguration, ISourceFileWorkingSet WorkingSet, BuildOptions Options)
        {
            // Create a makefile for each target
            TargetMakefile[] Makefiles = new TargetMakefile[TargetDescriptors.Count];
            for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
            {
                Makefiles[TargetIdx] = CreateMakefile(BuildConfiguration, TargetDescriptors[TargetIdx], WorkingSet);
            }

            // Output the manifest
            for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
            {
                TargetDescriptor TargetDescriptor = TargetDescriptors[TargetIdx];
                if (TargetDescriptor.LiveCodingManifest != null)
                {
                    TargetMakefile Makefile = Makefiles[TargetIdx];
                    HotReload.WriteLiveCodingManifest(TargetDescriptor.LiveCodingManifest, Makefile.Actions);
                }
            }

            // Execute the build
            if ((Options & BuildOptions.SkipBuild) == 0)
            {
                // Make sure that none of the actions conflict with any other (producing output files differently, etc...)
                ActionGraph.CheckForConflicts(Makefiles.SelectMany(x => x.Actions));

                // Find all the actions to be executed
                HashSet <Action>[] ActionsToExecute = new HashSet <Action> [TargetDescriptors.Count];
                for (int TargetIdx = 0; TargetIdx < TargetDescriptors.Count; TargetIdx++)
                {
                    ActionsToExecute[TargetIdx] = GetActionsForTarget(BuildConfiguration, TargetDescriptors[TargetIdx], Makefiles[TargetIdx]);
                }

                // If there are multiple targets being built, merge the actions together
                List <Action> MergedActionsToExecute;
                if (TargetDescriptors.Count == 1)
                {
                    MergedActionsToExecute = new List <Action>(ActionsToExecute[0]);
                }
                else
                {
                    MergedActionsToExecute = MergeActionGraphs(TargetDescriptors, ActionsToExecute);
                }

                // Link all the actions together
                ActionGraph.Link(MergedActionsToExecute);

                // Make sure the appropriate executor is selected
                foreach (TargetDescriptor TargetDescriptor in TargetDescriptors)
                {
                    UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(TargetDescriptor.Platform);
                    BuildConfiguration.bAllowXGE    &= BuildPlatform.CanUseXGE();
                    BuildConfiguration.bAllowDistcc &= BuildPlatform.CanUseDistcc();
                    BuildConfiguration.bAllowSNDBS  &= BuildPlatform.CanUseSNDBS();
                }

                // Delete produced items that are outdated.
                ActionGraph.DeleteOutdatedProducedItems(MergedActionsToExecute);

                // Save all the action histories now that files have been removed. We have to do this after deleting produced items to ensure that any
                // items created during the build don't have the wrong command line.
                ActionHistory.SaveAll();

                // Create directories for the outdated produced items.
                ActionGraph.CreateDirectoriesForProducedItems(MergedActionsToExecute);

                // Execute the actions
                if ((Options & BuildOptions.XGEExport) != 0)
                {
                    // Just export to an XML file
                    using (Timeline.ScopeEvent("XGE.ExportActions()"))
                    {
                        XGE.ExportActions(MergedActionsToExecute);
                    }
                }
                else
                {
                    // Execute the actions
                    if (MergedActionsToExecute.Count == 0)
                    {
                        if ((Options & BuildOptions.Quiet) == 0)
                        {
                            Log.TraceInformation((TargetDescriptors.Count == 1)? "Target is up to date" : "Targets are up to date");
                        }
                    }
                    else
                    {
                        if ((Options & BuildOptions.Quiet) != 0)
                        {
                            Log.TraceInformation("Building {0}...", StringUtils.FormatList(TargetDescriptors.Select(x => x.Name).Distinct()));
                        }

                        OutputToolchainInfo(TargetDescriptors, Makefiles);

                        using (Timeline.ScopeEvent("ActionGraph.ExecuteActions()"))
                        {
                            ActionGraph.ExecuteActions(BuildConfiguration, MergedActionsToExecute);
                        }
                    }

                    // Run the deployment steps
                    foreach (TargetMakefile Makefile in Makefiles)
                    {
                        if (Makefile.bDeployAfterCompile)
                        {
                            TargetReceipt Receipt = TargetReceipt.Read(Makefile.ReceiptFile);
                            Log.TraceInformation("Deploying {0} {1} {2}...", Receipt.TargetName, Receipt.Platform, Receipt.Configuration);
                            UEBuildPlatform.GetBuildPlatform(Receipt.Platform).Deploy(Receipt);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Prepare the target for deployment
 /// </summary>
 /// <param name="Receipt">Receipt for the target being deployed</param>
 /// <returns>True if successful, false if not</returns>
 public virtual bool PrepTargetForDeployment(TargetReceipt Receipt)
 {
     return(true);
 }
        /// <summary>
        /// Read a receipt from disk.
        /// </summary>
        /// <param name="FileName">Filename to read from</param>
        public static TargetReceipt Read(string FileName)
        {
            JsonObject RawObject = JsonObject.Read(FileName);

            // Read the initial fields
            string TargetName = RawObject.GetStringField("TargetName");
            UnrealTargetPlatform      Platform      = RawObject.GetEnumField <UnrealTargetPlatform>("Platform");
            UnrealTargetConfiguration Configuration = RawObject.GetEnumField <UnrealTargetConfiguration>("Configuration");
            string BuildId = RawObject.GetStringField("BuildId");

            // Try to read the build version
            BuildVersion Version;

            if (!BuildVersion.TryParse(RawObject.GetObjectField("Version"), out Version))
            {
                throw new JsonParseException("Invalid 'Version' field");
            }

            // Create the receipt
            TargetReceipt Receipt = new TargetReceipt(TargetName, Platform, Configuration, BuildId, Version);

            // Read the build products
            JsonObject[] BuildProductObjects;
            if (RawObject.TryGetObjectArrayField("BuildProducts", out BuildProductObjects))
            {
                foreach (JsonObject BuildProductObject in BuildProductObjects)
                {
                    string           Path;
                    BuildProductType Type;
                    if (BuildProductObject.TryGetStringField("Path", out Path) && BuildProductObject.TryGetEnumField("Type", out Type))
                    {
                        string Module;
                        BuildProductObject.TryGetStringField("Module", out Module);

                        BuildProduct NewBuildProduct = Receipt.AddBuildProduct(Path, Type);

                        bool IsPrecompiled;
                        if (BuildProductObject.TryGetBoolField("IsPrecompiled", out IsPrecompiled))
                        {
                            NewBuildProduct.IsPrecompiled = IsPrecompiled;
                        }
                    }
                }
            }

            // Read the runtime dependencies
            JsonObject[] RuntimeDependencyObjects;
            if (RawObject.TryGetObjectArrayField("RuntimeDependencies", out RuntimeDependencyObjects))
            {
                foreach (JsonObject RuntimeDependencyObject in RuntimeDependencyObjects)
                {
                    string Path;
                    if (RuntimeDependencyObject.TryGetStringField("Path", out Path))
                    {
                        StagedFileType Type;
                        if (!RuntimeDependencyObject.TryGetEnumField("Type", out Type))
                        {
                            // Previous format included an optional IgnoreIfMissing flag, which was only used for debug files. We can explicitly reference them as DebugNonUFS files now.
                            bool bIgnoreIfMissing;
                            if (RuntimeDependencyObject.TryGetBoolField("IgnoreIfMissing", out bIgnoreIfMissing))
                            {
                                bIgnoreIfMissing = false;
                            }
                            Type = bIgnoreIfMissing? StagedFileType.DebugNonUFS : StagedFileType.NonUFS;
                        }
                        Receipt.RuntimeDependencies.Add(Path, Type);
                    }
                }
            }

            // Read the additional properties
            JsonObject[] AdditionalPropertyObjects;
            if (RawObject.TryGetObjectArrayField("AdditionalProperties", out AdditionalPropertyObjects))
            {
                foreach (JsonObject AdditionalPropertyObject in AdditionalPropertyObjects)
                {
                    string Name;
                    if (AdditionalPropertyObject.TryGetStringField("Name", out Name))
                    {
                        string Value;
                        if (AdditionalPropertyObject.TryGetStringField("Value", out Value))
                        {
                            Receipt.AdditionalProperties.Add(new ReceiptProperty(Name, Value));
                        }
                    }
                }
            }

            // Read the precompiled dependencies
            string[] PrecompiledBuildDependencies;
            if (RawObject.TryGetStringArrayField("PrecompiledBuildDependencies", out PrecompiledBuildDependencies))
            {
                Receipt.PrecompiledBuildDependencies.UnionWith(PrecompiledBuildDependencies);
            }

            // Read the precompiled dependencies
            string[] PrecompiledRuntimeDependencies;
            if (RawObject.TryGetStringArrayField("PrecompiledRuntimeDependencies", out PrecompiledRuntimeDependencies))
            {
                Receipt.PrecompiledRuntimeDependencies.UnionWith(PrecompiledRuntimeDependencies);
            }

            return(Receipt);
        }
Beispiel #37
0
 public override bool PrepTargetForDeployment(TargetReceipt Receipt)
 {
     // @todo Lumin: Need to create a MabuFile with no data files - including the executable!!
     return(true);
 }
Beispiel #38
0
 /// <summary>
 /// Deploys the given target
 /// </summary>
 /// <param name="Receipt">Receipt for the target being deployed</param>
 public override void Deploy(TargetReceipt Receipt)
 {
     new UEDeployIOS().PrepTargetForDeployment(Receipt);
 }
		/// <summary>
		/// Checks if all the files in a receipt are present and that all the DLLs are at the same version
		/// </summary>
		/// <returns>
		/// True if all the files are valid.
		/// </returns>
		static bool CheckBinariesExist(TargetReceipt Receipt)
		{
			bool bExist = true;
			foreach(BuildProduct BuildProduct in Receipt.BuildProducts)
			{
				if(BuildProduct.Type == BuildProductType.Executable || BuildProduct.Type == BuildProductType.DynamicLibrary)
				{
					if(!File.Exists(BuildProduct.Path))
					{
						Log.TraceWarning("Missing binary: {0}", BuildProduct.Path);
						bExist = false;
					}
				}
			}
			return bExist;
		}
Beispiel #40
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="ProjectFile"></param>
 /// <param name="VersionFile"></param>
 /// <param name="ReceiptFile"></param>
 /// <param name="Receipt"></param>
 /// <param name="FileToManifest"></param>
 public WriteMetadataTargetInfo(FileReference ProjectFile, FileReference VersionFile, FileReference ReceiptFile, TargetReceipt Receipt, Dictionary <FileReference, ModuleManifest> FileToManifest)       //string EngineManifestName, string ProjectManifestName, Dictionary<string, FileReference> ModuleNameToLocation)
 {
     this.ProjectFile    = ProjectFile;
     this.VersionFile    = VersionFile;
     this.ReceiptFile    = ReceiptFile;
     this.Receipt        = Receipt;
     this.FileToManifest = FileToManifest;
 }
		/// <summary>
		/// Checks if all the files in a receipt have the same version
		/// </summary>
		/// <returns>
		/// True if all the files are valid.
		/// </returns>
		static bool CheckDynamicLibaryVersionsMatch(TargetReceipt Receipt)
		{
			List<Tuple<string, int>> BinaryVersions = new List<Tuple<string,int>>();
			foreach(BuildProduct BuildProduct in Receipt.BuildProducts)
			{
				if(BuildProduct.Type == BuildProductType.DynamicLibrary)
				{
					int Version = BuildHostPlatform.Current.GetDllApiVersion(BuildProduct.Path);
					BinaryVersions.Add(new Tuple<string,int>(BuildProduct.Path, Version));
				}
			}

			bool bMatch = true;
			if(BinaryVersions.Count > 0 && !BinaryVersions.All(x => x.Item2 == BinaryVersions[0].Item2))
			{
				Log.TraceWarning("Detected mismatch in binary versions:");
				foreach(Tuple<string, int> BinaryVersion in BinaryVersions)
				{
					Log.TraceWarning("  {0} has API version {1}", BinaryVersion.Item1, BinaryVersion.Item2);
					File.Delete(BinaryVersion.Item1);
				}
				bMatch = false;
			}
			return bMatch;
		}
		public override void AddFilesToReceipt(TargetReceipt Receipt, UEBuildBinary Binary)
		{
			// the binary will have all of the .so's in the output files, we need to trim down to the shared apk (which is what needs to go into the manifest)
			if (Binary.Config.Type != UEBuildBinaryType.StaticLibrary)
			{
				foreach (string BinaryPath in Binary.Config.OutputFilePaths)
				{
					string ApkFile = Path.ChangeExtension(BinaryPath, ".apk");
					Receipt.AddBuildProduct(ApkFile, BuildProductType.Executable);
				}
			}
		}
Beispiel #43
0
		/// <summary>
		/// Copy constructor
		/// </summary>
		/// <param name="InOther">Receipt to copy from</param>
		public TargetReceipt(TargetReceipt Other)
		{ 
			foreach(BuildProduct OtherBuildProduct in Other.BuildProducts)
			{
				BuildProducts.Add(new BuildProduct(OtherBuildProduct));
			}
			foreach(RuntimeDependency OtherRuntimeDependency in Other.RuntimeDependencies)
			{
				RuntimeDependencies.Add(new RuntimeDependency(OtherRuntimeDependency));
			}
		}