Exemple #1
0
        /// <summary>
        /// Setup the target environment for building
        /// </summary>
        /// <param name="Target">Settings for the target being compiled</param>
        /// <param name="CompileEnvironment">The compile environment for this target</param>
        /// <param name="LinkEnvironment">The link environment for this target</param>
        public override void SetUpEnvironment(ReadOnlyTargetRules Target, CppCompileEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment)
        {
            // During the native builds, check the system includes as well (check toolchain when cross-compiling?)
            string BaseLinuxPath = SDK.GetBaseLinuxPathForArchitecture(Target.Architecture);

            if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Linux && String.IsNullOrEmpty(BaseLinuxPath))
            {
                CompileEnvironment.SystemIncludePaths.Add(new DirectoryReference("/usr/include"));
            }

            if (CompileEnvironment.bPGOOptimize != LinkEnvironment.bPGOOptimize)
            {
                throw new BuildException("Inconsistency between PGOOptimize settings in Compile ({0}) and Link ({1}) environments",
                                         CompileEnvironment.bPGOOptimize,
                                         LinkEnvironment.bPGOOptimize
                                         );
            }

            if (CompileEnvironment.bPGOProfile != LinkEnvironment.bPGOProfile)
            {
                throw new BuildException("Inconsistency between PGOProfile settings in Compile ({0}) and Link ({1}) environments",
                                         CompileEnvironment.bPGOProfile,
                                         LinkEnvironment.bPGOProfile
                                         );
            }

            if (CompileEnvironment.bPGOOptimize)
            {
                DirectoryReference BaseDir = UnrealBuildTool.EngineDirectory;
                if (Target.ProjectFile != null)
                {
                    BaseDir = DirectoryReference.FromFile(Target.ProjectFile);
                }
                CompileEnvironment.PGODirectory      = Path.Combine(BaseDir.FullName, "Build", Target.Platform.ToString(), "PGO").Replace('\\', '/') + "/";
                CompileEnvironment.PGOFilenamePrefix = "profile.profdata";

                LinkEnvironment.PGODirectory      = CompileEnvironment.PGODirectory;
                LinkEnvironment.PGOFilenamePrefix = CompileEnvironment.PGOFilenamePrefix;
            }

            // For consistency with other platforms, also enable LTO whenever doing profile-guided optimizations.
            // Obviously both PGI (instrumented) and PGO (optimized) binaries need to have that
            if (CompileEnvironment.bPGOProfile || CompileEnvironment.bPGOOptimize)
            {
                CompileEnvironment.bAllowLTCG = true;
                LinkEnvironment.bAllowLTCG    = true;
            }

            if (CompileEnvironment.bAllowLTCG != LinkEnvironment.bAllowLTCG)
            {
                throw new BuildException("Inconsistency between LTCG settings in Compile ({0}) and Link ({1}) environments",
                                         CompileEnvironment.bAllowLTCG,
                                         LinkEnvironment.bAllowLTCG
                                         );
            }

            // link with Linux libraries.
            LinkEnvironment.AdditionalLibraries.Add("pthread");

            // let this class or a sub class do settings specific to that class
            SetUpSpecificEnvironment(Target, CompileEnvironment, LinkEnvironment);
        }
Exemple #2
0
        /// <summary>
        /// Whether the path contains a valid clang version
        /// </summary>
        private static bool IsValidClangPath(DirectoryReference BaseLinuxPath)
        {
            FileReference ClangPath = FileReference.Combine(BaseLinuxPath, @"bin", (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64) ? "clang++.exe" : "clang++");

            return(FileReference.Exists(ClangPath));
        }
Exemple #3
0
        /// <summary>
        /// Setup the target environment for building
        /// </summary>
        /// <param name="InBuildTarget"> The target being built</param>
        public override void SetUpEnvironment(UEBuildTarget InBuildTarget)
        {
            InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("PLATFORM_IOS=1");
            InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("PLATFORM_APPLE=1");

            InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_TTS=0");
            InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_SPEECH_RECOGNITION=0");
            InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_DATABASE_SUPPORT=0");
            InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_EDITOR=0");
            InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("USE_NULL_RHI=0");
            InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("REQUIRES_ALIGNED_INT_ACCESS");

            ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", DirectoryReference.FromFile(ProjectFile));

            Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableRemoteNotificationsSupport", out bNotificationsEnabled);
            if (bNotificationsEnabled)
            {
                InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("NOTIFICATIONS_ENABLED");
            }

            if (GetActiveArchitecture() == "-simulator")
            {
                InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WITH_SIMULATOR=1");
            }

            // we assume now we are building with IOS8 or later
            if (UEBuildConfiguration.bCompileAgainstEngine)
            {
                InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("HAS_METAL=1");
                InBuildTarget.ExtraModuleNames.Add("MetalRHI");
            }
            else
            {
                InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("HAS_METAL=0");
            }

            InBuildTarget.GlobalLinkEnvironment.Config.AdditionalFrameworks.Add(new UEBuildFramework("GameKit"));
            InBuildTarget.GlobalLinkEnvironment.Config.AdditionalFrameworks.Add(new UEBuildFramework("StoreKit"));
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="Type">The hierarchy type</param>
 /// <param name="ProjectDir">The project directory to read from</param>
 /// <param name="Platform">Which platform-specific files to read</param>
 public ConfigHierarchyKey(ConfigHierarchyType Type, DirectoryReference ProjectDir, UnrealTargetPlatform Platform)
 {
     this.Type       = Type;
     this.ProjectDir = ProjectDir;
     this.Platform   = Platform;
 }
Exemple #5
0
 /// <summary>
 /// Tries to get the directory for an installed Visual Studio version
 /// </summary>
 /// <param name="Compiler">The compiler version</param>
 /// <param name="InstallDir">Receives the install directory on success</param>
 /// <returns>True if successful</returns>
 public static bool TryGetVSInstallDir(WindowsCompiler Compiler, out DirectoryReference InstallDir)
 {
     return(WindowsPlatform.TryGetVSInstallDir(Compiler, out InstallDir));
 }
Exemple #6
0
        public static FileReference GetUBTMakefilePath(FileReference ProjectFile, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, string TargetName, bool bForHotReload)
        {
            DirectoryReference BaseDir = GetUBTMakefileDirectory(ProjectFile, Platform, Configuration, TargetName);

            return(FileReference.Combine(BaseDir, bForHotReload ? "HotReloadMakefile.ubt" : "Makefile.ubt"));
        }
        public override void CleanProjectFiles(DirectoryReference InMasterProjectDirectory, string InMasterProjectName, DirectoryReference InIntermediateProjectFilesDirectory)
        {
            FileReference MasterProjectFile = FileReference.Combine(InMasterProjectDirectory, "CMakeLists.txt");

            if (MasterProjectFile.Exists())
            {
                MasterProjectFile.Delete();
            }
        }
        /// <summary>
        /// Write a Module to a JSON writer. If array is empty, don't write anything
        /// </summary>
        /// <param name="BinaryOutputDir"></param>
        /// <param name="TargetOutputDir"></param>
        /// <param name="Writer">Writer for the array data</param>
        /// <param name="Module"></param>
        private static void ExportModule(UEBuildModule Module, DirectoryReference BinaryOutputDir, DirectoryReference TargetOutputDir, JsonWriter Writer)
        {
            Writer.WriteValue("Name", Module.Name);
            Writer.WriteValue("Directory", Module.ModuleDirectory.FullName);
            Writer.WriteValue("Rules", Module.RulesFile.FullName);
            Writer.WriteValue("PCHUsage", Module.Rules.PCHUsage.ToString());

            if (Module.Rules.PrivatePCHHeaderFile != null)
            {
                Writer.WriteValue("PrivatePCH", FileReference.Combine(Module.ModuleDirectory, Module.Rules.PrivatePCHHeaderFile).FullName);
            }

            if (Module.Rules.SharedPCHHeaderFile != null)
            {
                Writer.WriteValue("SharedPCH", FileReference.Combine(Module.ModuleDirectory, Module.Rules.SharedPCHHeaderFile).FullName);
            }

            ExportJsonModuleArray(Writer, "PublicDependencyModules", Module.PublicDependencyModules);
            ExportJsonModuleArray(Writer, "PublicIncludePathModules", Module.PublicIncludePathModules);
            ExportJsonModuleArray(Writer, "PrivateDependencyModules", Module.PrivateDependencyModules);
            ExportJsonModuleArray(Writer, "PrivateIncludePathModules", Module.PrivateIncludePathModules);
            ExportJsonModuleArray(Writer, "DynamicallyLoadedModules", Module.DynamicallyLoadedModules);

            ExportJsonStringArray(Writer, "PublicSystemIncludePaths", Module.PublicSystemIncludePaths.Select(x => x.FullName));
            ExportJsonStringArray(Writer, "PublicIncludePaths", Module.PublicIncludePaths.Select(x => x.FullName));

            ExportJsonStringArray(Writer, "LegacyPublicIncludePaths", Module.LegacyPublicIncludePaths.Select(x => x.FullName));

            ExportJsonStringArray(Writer, "PrivateIncludePaths", Module.PrivateIncludePaths.Select(x => x.FullName));
            ExportJsonStringArray(Writer, "PublicLibraryPaths", Module.PublicSystemLibraryPaths.Select(x => x.FullName));
            ExportJsonStringArray(Writer, "PublicAdditionalLibraries", Module.PublicSystemLibraries.Concat(Module.PublicAdditionalLibraries));
            ExportJsonStringArray(Writer, "PublicFrameworks", Module.PublicFrameworks);
            ExportJsonStringArray(Writer, "PublicWeakFrameworks", Module.PublicWeakFrameworks);
            ExportJsonStringArray(Writer, "PublicDelayLoadDLLs", Module.PublicDelayLoadDLLs);
            ExportJsonStringArray(Writer, "PublicDefinitions", Module.PublicDefinitions);
            ExportJsonStringArray(Writer, "PrivateDefinitions", Module.Rules.PrivateDefinitions);
            ExportJsonStringArray(Writer, "ProjectDefinitions", /* TODO: Add method ShouldAddProjectDefinitions */ !Module.Rules.bTreatAsEngineModule ? Module.Rules.Target.ProjectDefinitions : new string[0]);
            ExportJsonStringArray(Writer, "ApiDefinitions", Module.GetEmptyApiMacros());
            Writer.WriteValue("ShouldAddLegacyPublicIncludePaths", Module.Rules.bLegacyPublicIncludePaths);

            if (Module.Rules.CircularlyReferencedDependentModules.Any())
            {
                Writer.WriteArrayStart("CircularlyReferencedModules");
                foreach (string ModuleName in Module.Rules.CircularlyReferencedDependentModules)
                {
                    Writer.WriteValue(ModuleName);
                }
                Writer.WriteArrayEnd();
            }

            if (Module.Rules.RuntimeDependencies.Inner.Any())
            {
                // We don't use info from RuntimeDependencies for code analyzes (at the moment)
                // So we're OK with skipping some values if they are not presented
                Writer.WriteArrayStart("RuntimeDependencies");
                foreach (ModuleRules.RuntimeDependency RuntimeDependency in Module.Rules.RuntimeDependencies.Inner)
                {
                    Writer.WriteObjectStart();

                    try
                    {
                        Writer.WriteValue("Path",
                                          Module.ExpandPathVariables(RuntimeDependency.Path, BinaryOutputDir, TargetOutputDir));
                    }
                    catch (BuildException buildException)
                    {
                        Log.TraceVerbose("Value {0} for module {1} will not be stored. Reason: {2}", "Path", Module.Name, buildException);
                    }

                    if (RuntimeDependency.SourcePath != null)
                    {
                        try
                        {
                            Writer.WriteValue("SourcePath",
                                              Module.ExpandPathVariables(RuntimeDependency.SourcePath, BinaryOutputDir,
                                                                         TargetOutputDir));
                        }
                        catch (BuildException buildException)
                        {
                            Log.TraceVerbose("Value {0} for module {1} will not be stored. Reason: {2}", "SourcePath", Module.Name, buildException);
                        }
                    }

                    Writer.WriteValue("Type", RuntimeDependency.Type.ToString());

                    Writer.WriteObjectEnd();
                }
                Writer.WriteArrayEnd();
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="InName">Name of the module</param>
        /// <param name="InType">Type of the module, for UHT</param>
        /// <param name="InModuleDirectory">Base directory for the module</param>
        /// <param name="InRules">Rules for this module</param>
        /// <param name="InRulesFile">Path to the rules file</param>
        /// <param name="InRuntimeDependencies">List of runtime dependencies</param>
        public UEBuildModule(string InName, UHTModuleType InType, DirectoryReference InModuleDirectory, ModuleRules InRules, FileReference InRulesFile, List <RuntimeDependency> InRuntimeDependencies)
        {
            Name            = InName;
            Type            = InType;
            ModuleDirectory = InModuleDirectory;
            Rules           = InRules;
            RulesFile       = InRulesFile;

            NormalizedModuleIncludePath = Utils.CleanDirectorySeparators(ModuleDirectory.MakeRelativeTo(UnrealBuildTool.EngineSourceDirectory), '/');
            ModuleApiDefine             = Name.ToUpperInvariant() + "_API";

            PublicDefinitions               = HashSetFromOptionalEnumerableStringParameter(InRules.Definitions);
            PublicIncludePaths              = HashSetFromOptionalEnumerableStringParameter(InRules.PublicIncludePaths);
            PublicSystemIncludePaths        = HashSetFromOptionalEnumerableStringParameter(InRules.PublicSystemIncludePaths);
            PublicLibraryPaths              = HashSetFromOptionalEnumerableStringParameter(InRules.PublicLibraryPaths);
            PublicAdditionalLibraries       = HashSetFromOptionalEnumerableStringParameter(InRules.PublicAdditionalLibraries);
            PublicFrameworks                = HashSetFromOptionalEnumerableStringParameter(InRules.PublicFrameworks);
            PublicWeakFrameworks            = HashSetFromOptionalEnumerableStringParameter(InRules.PublicWeakFrameworks);
            PublicAdditionalFrameworks      = InRules.PublicAdditionalFrameworks == null ? new HashSet <UEBuildFramework>() : new HashSet <UEBuildFramework>(InRules.PublicAdditionalFrameworks);
            PublicAdditionalShadowFiles     = HashSetFromOptionalEnumerableStringParameter(InRules.PublicAdditionalShadowFiles);
            PublicAdditionalBundleResources = InRules.AdditionalBundleResources == null ? new HashSet <UEBuildBundleResource>() : new HashSet <UEBuildBundleResource>(InRules.AdditionalBundleResources);
            PublicDelayLoadDLLs             = HashSetFromOptionalEnumerableStringParameter(InRules.PublicDelayLoadDLLs);
            PrivateIncludePaths             = HashSetFromOptionalEnumerableStringParameter(InRules.PrivateIncludePaths);
            RuntimeDependencies             = InRuntimeDependencies;
            IsRedistributableOverride       = InRules.IsRedistributableOverride;

            WhitelistRestrictedFolders = new HashSet <DirectoryReference>(InRules.WhitelistRestrictedFolders.Select(x => DirectoryReference.Combine(ModuleDirectory, x)));
        }
        /// <summary>
        /// Determines the distribution level of a module based on its directory and includes.
        /// </summary>
        /// <param name="ProjectDir">The project directory, if available</param>
        /// <returns>Map of the restricted folder types to the first found instance</returns>
        public Dictionary <RestrictedFolder, DirectoryReference> FindRestrictedFolderReferences(DirectoryReference ProjectDir)
        {
            Dictionary <RestrictedFolder, DirectoryReference> References = new Dictionary <RestrictedFolder, DirectoryReference>();

            if (!Rules.bOutputPubliclyDistributable)
            {
                // Find all the directories that this module references
                HashSet <DirectoryReference> ReferencedDirs = new HashSet <DirectoryReference>();
                GetReferencedDirectories(ReferencedDirs);

                // Remove all the whitelisted folders
                ReferencedDirs.ExceptWith(WhitelistRestrictedFolders);
                ReferencedDirs.ExceptWith(PublicDependencyModules.SelectMany(x => x.WhitelistRestrictedFolders));
                ReferencedDirs.ExceptWith(PrivateDependencyModules.SelectMany(x => x.WhitelistRestrictedFolders));

                // Add flags for each of them
                foreach (DirectoryReference ReferencedDir in ReferencedDirs)
                {
                    // Find the base directory containing this reference
                    DirectoryReference BaseDir;
                    if (ReferencedDir.IsUnderDirectory(UnrealBuildTool.EngineDirectory))
                    {
                        BaseDir = UnrealBuildTool.EngineDirectory;
                    }
                    else if (ProjectDir != null && ReferencedDir.IsUnderDirectory(ProjectDir))
                    {
                        BaseDir = ProjectDir;
                    }
                    else
                    {
                        continue;
                    }

                    // Add references to each of the restricted folders
                    List <RestrictedFolder> Folders = RestrictedFolders.FindRestrictedFolders(BaseDir, ReferencedDir);
                    foreach (RestrictedFolder Folder in Folders)
                    {
                        if (!References.ContainsKey(Folder))
                        {
                            References.Add(Folder, ReferencedDir);
                        }
                    }
                }
            }
            return(References);
        }
Exemple #11
0
 /// <summary>
 /// Allow various platform project generators to generate any special project properties if required
 /// </summary>
 /// <param name="InPlatform"></param>
 /// <param name="Configuration"></param>
 /// <param name="TargetType"></param>
 /// <param name="VCProjectFileContent"></param>
 /// <param name="RootDirectory"></param>
 /// <param name="TargetFilePath"></param>
 /// <returns></returns>
 public bool GenerateGamePlatformSpecificProperties(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration Configuration, TargetType TargetType, StringBuilder VCProjectFileContent, DirectoryReference RootDirectory, FileReference TargetFilePath)
 {
     if (ProjectGeneratorDictionary.ContainsKey(InPlatform) == true)
     {
         ProjectGeneratorDictionary[InPlatform].GenerateGameProperties(Configuration, VCProjectFileContent, TargetType, RootDirectory, TargetFilePath);;
     }
     return(true);
 }
Exemple #12
0
 /// <summary>
 /// Check for the build requirement due to platform requirements
 /// return true if the project requires a build
 /// </summary>
 public override bool RequiresBuild(UnrealTargetPlatform Platform, DirectoryReference ProjectDirectoryName)
 {
     // check for custom icons
     return(HasCustomIcons(ProjectDirectoryName));
 }
Exemple #13
0
        protected IOSProvisioningData(IOSProjectSettings ProjectSettings, bool bIsTVOS, bool bForDistribtion)
        {
            SigningCertificate = ProjectSettings.SigningCertificate;
            string MobileProvision = ProjectSettings.MobileProvision;

            FileReference ProjectFile = ProjectSettings.ProjectFile;

            if (!string.IsNullOrEmpty(SigningCertificate))
            {
                // verify the certificate
                Process IPPProcess = new Process();
                if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                {
                    string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + ProjectSettings.BundleIdentifier + (bForDistribtion ? " -distribution" : "");
                    IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
                    IPPProcess.StartInfo.FileName         = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh";
                    IPPProcess.StartInfo.Arguments        = IPPCmd;
                    IPPProcess.OutputDataReceived        += new DataReceivedEventHandler(IPPDataReceivedHandler);
                    IPPProcess.ErrorDataReceived         += new DataReceivedEventHandler(IPPDataReceivedHandler);
                }
                else
                {
                    string IPPCmd = "certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + ProjectSettings.BundleIdentifier + (bForDistribtion ? " -distribution" : "");
                    IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
                    IPPProcess.StartInfo.FileName         = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe";
                    IPPProcess.StartInfo.Arguments        = IPPCmd;
                    IPPProcess.OutputDataReceived        += new DataReceivedEventHandler(IPPDataReceivedHandler);
                    IPPProcess.ErrorDataReceived         += new DataReceivedEventHandler(IPPDataReceivedHandler);
                }
                Utils.RunLocalProcess(IPPProcess);
            }
            else
            {
                SigningCertificate = bForDistribtion ? "iPhone Distribution" : "iPhone Developer";
                bHaveCertificate   = true;
            }

            if (!string.IsNullOrEmpty(MobileProvision))
            {
                DirectoryReference MobileProvisionDir;
                if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                {
                    MobileProvisionDir = DirectoryReference.Combine(new DirectoryReference(Environment.GetEnvironmentVariable("HOME")), "Library", "MobileDevice", "Provisioning Profiles");
                }
                else
                {
                    MobileProvisionDir = DirectoryReference.Combine(DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.LocalApplicationData), "Apple Computer", "MobileDevice", "Provisioning Profiles");
                }

                FileReference PossibleMobileProvisionFile = FileReference.Combine(MobileProvisionDir, MobileProvision);
                if (FileReference.Exists(PossibleMobileProvisionFile))
                {
                    MobileProvisionFile = PossibleMobileProvisionFile;
                }
            }

            if (MobileProvisionFile == null || !bHaveCertificate)
            {
                SigningCertificate  = "";
                MobileProvision     = "";
                MobileProvisionFile = null;
                Log.TraceLog("Provision not specified or not found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", searching for compatible match...");
                Process IPPProcess = new Process();
                if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                {
                    string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + ProjectSettings.BundleIdentifier + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : "");
                    IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
                    IPPProcess.StartInfo.FileName         = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh";
                    IPPProcess.StartInfo.Arguments        = IPPCmd;
                    IPPProcess.OutputDataReceived        += new DataReceivedEventHandler(IPPDataReceivedHandler);
                    IPPProcess.ErrorDataReceived         += new DataReceivedEventHandler(IPPDataReceivedHandler);
                }
                else
                {
                    string IPPCmd = "signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + ProjectSettings.BundleIdentifier + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : "");
                    IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
                    IPPProcess.StartInfo.FileName         = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe";
                    IPPProcess.StartInfo.Arguments        = IPPCmd;
                    IPPProcess.OutputDataReceived        += new DataReceivedEventHandler(IPPDataReceivedHandler);
                    IPPProcess.ErrorDataReceived         += new DataReceivedEventHandler(IPPDataReceivedHandler);
                }
                Utils.RunLocalProcess(IPPProcess);
                if (MobileProvisionFile != null)
                {
                    Log.TraceLog("Provision found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", Provision: " + MobileProvisionFile + " Certificate: " + SigningCertificate);
                }
            }

            // add to the dictionary
            SigningCertificate = SigningCertificate.Replace("\"", "");

            // read the provision to get the UUID
            if (MobileProvisionFile == null)
            {
                Log.TraceLog("No matching provision file was discovered for {0}. Please ensure you have a compatible provision installed.", ProjectFile);
            }
            else if (!FileReference.Exists(MobileProvisionFile))
            {
                Log.TraceLog("Selected mobile provision for {0} ({1}) was not found. Please ensure you have a compatible provision installed.", ProjectFile, MobileProvisionFile);
            }
            else
            {
                byte[] AllBytes = FileReference.ReadAllBytes(MobileProvisionFile);

                uint StartIndex = (uint)AllBytes.Length;
                uint EndIndex   = (uint)AllBytes.Length;

                for (uint i = 0; i + 4 < AllBytes.Length; i++)
                {
                    if (AllBytes[i] == '<' && AllBytes[i + 1] == '?' && AllBytes[i + 2] == 'x' && AllBytes[i + 3] == 'm' && AllBytes[i + 4] == 'l')
                    {
                        StartIndex = i;
                        break;
                    }
                }

                if (StartIndex < AllBytes.Length)
                {
                    for (uint i = StartIndex; i + 7 < AllBytes.Length; i++)
                    {
                        if (AllBytes[i] == '<' && AllBytes[i + 1] == '/' && AllBytes[i + 2] == 'p' && AllBytes[i + 3] == 'l' && AllBytes[i + 4] == 'i' && AllBytes[i + 5] == 's' && AllBytes[i + 6] == 't' && AllBytes[i + 7] == '>')
                        {
                            EndIndex = i + 7;
                            break;
                        }
                    }
                }

                if (StartIndex < AllBytes.Length && EndIndex < AllBytes.Length)
                {
                    byte[] TextBytes = new byte[EndIndex - StartIndex];
                    Buffer.BlockCopy(AllBytes, (int)StartIndex, TextBytes, 0, (int)(EndIndex - StartIndex));

                    string AllText = Encoding.UTF8.GetString(TextBytes);
                    int    idx     = AllText.IndexOf("<key>UUID</key>");
                    if (idx > 0)
                    {
                        idx = AllText.IndexOf("<string>", idx);
                        if (idx > 0)
                        {
                            idx += "<string>".Length;
                            MobileProvisionUUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx);
                        }
                    }
                    idx = AllText.IndexOf("<key>com.apple.developer.team-identifier</key>");
                    if (idx > 0)
                    {
                        idx = AllText.IndexOf("<string>", idx);
                        if (idx > 0)
                        {
                            idx     += "<string>".Length;
                            TeamUUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx);
                        }
                    }
                    idx = AllText.IndexOf("<key>Name</key>");
                    if (idx > 0)
                    {
                        idx = AllText.IndexOf("<string>", idx);
                        if (idx > 0)
                        {
                            idx += "<string>".Length;
                            MobileProvisionName = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx);
                        }
                    }
                }

                if (string.IsNullOrEmpty(MobileProvisionUUID) || string.IsNullOrEmpty(TeamUUID))
                {
                    MobileProvision    = null;
                    SigningCertificate = null;
                    Log.TraceLog("Failed to parse the mobile provisioning profile.");
                }
            }
        }
Exemple #14
0
        /// <summary>
        /// Returns a list of INI filenames for the given project
        /// </summary>
        public static IEnumerable <FileReference> EnumerateGeneratedConfigFileLocations(ConfigHierarchyType Type, DirectoryReference ProjectDir, UnrealTargetPlatform Platform)
        {
            string BaseIniName  = Enum.GetName(typeof(ConfigHierarchyType), Type);
            string PlatformName = GetIniPlatformName(Platform);

            // Get the generated config file too. EditorSettings overrides this from
            if (Type == ConfigHierarchyType.EditorSettings)
            {
                yield return(FileReference.Combine(GetGameAgnosticSavedDir(), "Config", PlatformName, BaseIniName + ".ini"));
            }
            else
            {
                yield return(FileReference.Combine(GetGeneratedConfigDir(ProjectDir), PlatformName, BaseIniName + ".ini"));
            }
        }
Exemple #15
0
 /// <summary>
 /// Protected constructor. Used by TVOSProjectSettings.
 /// </summary>
 /// <param name="ProjectFile">The project file to read settings for</param>
 /// <param name="Platform">The platform to read settings for</param>
 protected IOSProjectSettings(FileReference ProjectFile, UnrealTargetPlatform Platform)
 {
     this.ProjectFile = ProjectFile;
     ConfigCache.ReadSettings(DirectoryReference.FromFile(ProjectFile), Platform, this);
     BundleIdentifier = BundleIdentifier.Replace("[PROJECT_NAME]", ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game")).Replace("_", "");
 }
Exemple #16
0
        public virtual void SetUpSpecificEnvironment(ReadOnlyTargetRules Target, CppCompileEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment)
        {
            string NDKPath = Environment.GetEnvironmentVariable("NDKROOT");

            NDKPath = NDKPath.Replace("\"", "");

            AndroidToolChain ToolChain = new AndroidToolChain(Target.ProjectFile, false, Target.AndroidPlatform.Architectures, Target.AndroidPlatform.GPUArchitectures);

            // figure out the NDK version
            string NDKToolchainVersion = ToolChain.NDKToolchainVersion;
            string NDKDefine           = ToolChain.NDKDefine;

            string GccVersion = "4.9";

            // PLATFORM_ANDROID_NDK_VERSION is in the form 150100, where 15 is major version, 01 is the letter (1 is 'a'), 00 indicates beta revision if letter is 00
            Log.TraceInformation("PLATFORM_ANDROID_NDK_VERSION = {0}", NDKDefine);
            CompileEnvironment.Definitions.Add("PLATFORM_ANDROID_NDK_VERSION=" + NDKDefine);

            int NDKVersionInt = ToolChain.GetNdkApiLevelInt();

            Log.TraceInformation("NDK toolchain: {0}, NDK version: {1}, GccVersion: {2}, ClangVersion: {3}", NDKToolchainVersion, NDKVersionInt.ToString(), GccVersion, ToolChain.GetClangVersionString());
            ToolChain.ShowNDKWarnings();

            CompileEnvironment.Definitions.Add("PLATFORM_DESKTOP=0");
            CompileEnvironment.Definitions.Add("PLATFORM_CAN_SUPPORT_EDITORONLY_DATA=0");

            CompileEnvironment.Definitions.Add("WITH_OGGVORBIS=1");

            CompileEnvironment.Definitions.Add("UNICODE");
            CompileEnvironment.Definitions.Add("_UNICODE");

            CompileEnvironment.Definitions.Add("PLATFORM_ANDROID=1");
            CompileEnvironment.Definitions.Add("ANDROID=1");

            CompileEnvironment.Definitions.Add("WITH_EDITOR=0");
            CompileEnvironment.Definitions.Add("USE_NULL_RHI=0");

            DirectoryReference NdkDir = new DirectoryReference(NDKPath);

            //CompileEnvironment.SystemIncludePaths.Add(DirectoryReference.Combine(NdkDir, "sources/cxx-stl/llvm-libc++/include"));

            // the toolchain will actually filter these out
            LinkEnvironment.SystemLibraryPaths.Add(DirectoryReference.Combine(NdkDir, "sources/cxx-stl/llvm-libc++/libs/armeabi-v7a"));
            LinkEnvironment.SystemLibraryPaths.Add(DirectoryReference.Combine(NdkDir, "sources/cxx-stl/llvm-libc++/libs/arm64-v8a"));
            LinkEnvironment.SystemLibraryPaths.Add(DirectoryReference.Combine(NdkDir, "sources/cxx-stl/llvm-libc++/libs/x86"));
            LinkEnvironment.SystemLibraryPaths.Add(DirectoryReference.Combine(NdkDir, "sources/cxx-stl/llvm-libc++/libs/x86_64"));

            CompileEnvironment.SystemIncludePaths.Add(DirectoryReference.Combine(NdkDir, "sources/android/native_app_glue"));
            CompileEnvironment.SystemIncludePaths.Add(DirectoryReference.Combine(NdkDir, "sources/android/cpufeatures"));

            //@TODO: Tegra Gfx Debugger - standardize locations - for now, change the hardcoded paths and force this to return true to test
            if (UseTegraGraphicsDebugger(Target))
            {
                //LinkEnvironment.LibraryPaths.Add("ThirdParty/NVIDIA/TegraGfxDebugger");
                //LinkEnvironment.LibraryPaths.Add("F:/NVPACK/android-kk-egl-t124-a32/stub");
                //LinkEnvironment.AdditionalLibraries.Add("Nvidia_gfx_debugger_stub");
            }

            if (!UseTegraGraphicsDebugger(Target))
            {
                LinkEnvironment.SystemLibraries.Add("GLESv3");
                LinkEnvironment.SystemLibraries.Add("EGL");
            }
            LinkEnvironment.SystemLibraries.Add("android");
            LinkEnvironment.SystemLibraries.Add("OpenSLES");
        }
Exemple #17
0
        /// <summary>
        /// Combine several fragments with a base directory, to form a new filename
        /// </summary>
        /// <param name="BaseDirectory">The base directory</param>
        /// <param name="Fragments">Fragments to combine with the base directory</param>
        /// <returns>The new file name</returns>
        public static FileReference Combine(DirectoryReference BaseDirectory, params string[] Fragments)
        {
            string FullName = FileSystemReference.CombineStrings(BaseDirectory, Fragments);

            return(new FileReference(FullName, FullName.ToLowerInvariant()));
        }
        /// <summary>
        /// Write project file info in JSON file.
        /// For every combination of <c>UnrealTargetPlatform</c>, <c>UnrealTargetConfiguration</c> and <c>TargetType</c>
        /// will be generated separate JSON file.
        /// Project file will be stored:
        /// For UE4:  {UE4Root}/Engine/Intermediate/ProjectFiles/.Rider/{Platform}/{Configuration}/{TargetType}/{ProjectName}.json
        /// For game: {GameRoot}/Intermediate/ProjectFiles/.Rider/{Platform}/{Configuration}/{TargetType}/{ProjectName}.json
        /// </summary>
        /// <remarks>
        /// * <c>UnrealTargetPlatform.Win32</c> will be always ignored.
        /// * <c>TargetType.Editor</c> will be generated for current platform only and will ignore <c>UnrealTargetConfiguration.Test</c> and <c>UnrealTargetConfiguration.Shipping</c> configurations
        /// * <c>TargetType.Program</c>  will be generated for current platform only and <c>UnrealTargetConfiguration.Development</c> configuration only
        /// </remarks>
        /// <param name="InPlatforms"></param>
        /// <param name="InConfigurations"></param>
        /// <param name="PlatformProjectGenerators"></param>
        /// <returns></returns>
        public override bool WriteProjectFile(List <UnrealTargetPlatform> InPlatforms,
                                              List <UnrealTargetConfiguration> InConfigurations,
                                              PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            string             ProjectName       = ProjectFilePath.GetFileNameWithoutAnyExtensions();
            DirectoryReference ProjectRootFolder = DirectoryReference.Combine(RootPath, ".Rider");
            List <Tuple <FileReference, UEBuildTarget> > FileToTarget = new List <Tuple <FileReference, UEBuildTarget> >();

            foreach (UnrealTargetPlatform Platform in InPlatforms)
            {
                foreach (UnrealTargetConfiguration Configuration in InConfigurations)
                {
                    foreach (ProjectTarget ProjectTarget in ProjectTargets)
                    {
                        if (TargetTypes.Any() && !TargetTypes.Contains(ProjectTarget.TargetRules.Type))
                        {
                            continue;
                        }

                        // Skip Programs for all configs except for current platform + Development configuration
                        if (ProjectTarget.TargetRules.Type == TargetType.Program && (BuildHostPlatform.Current.Platform != Platform || Configuration != UnrealTargetConfiguration.Development))
                        {
                            continue;
                        }

                        // Skip Editor for all platforms except for current platform
                        if (ProjectTarget.TargetRules.Type == TargetType.Editor && (BuildHostPlatform.Current.Platform != Platform || (Configuration == UnrealTargetConfiguration.Test || Configuration == UnrealTargetConfiguration.Shipping)))
                        {
                            continue;
                        }

                        DirectoryReference ConfigurationFolder = DirectoryReference.Combine(ProjectRootFolder, Platform.ToString(), Configuration.ToString());

                        DirectoryReference TargetFolder =
                            DirectoryReference.Combine(ConfigurationFolder, ProjectTarget.TargetRules.Type.ToString());

                        string DefaultArchitecture = UEBuildPlatform
                                                     .GetBuildPlatform(Platform)
                                                     .GetDefaultArchitecture(ProjectTarget.UnrealProjectFilePath);
                        TargetDescriptor TargetDesc = new TargetDescriptor(ProjectTarget.UnrealProjectFilePath, ProjectTarget.Name,
                                                                           Platform, Configuration, DefaultArchitecture, Arguments);
                        try
                        {
                            UEBuildTarget BuildTarget = UEBuildTarget.Create(TargetDesc, false, false);

                            FileReference OutputFile = FileReference.Combine(TargetFolder, $"{ProjectName}.json");
                            FileToTarget.Add(Tuple.Create(OutputFile, BuildTarget));
                        }
                        catch (Exception Ex)
                        {
                            Log.TraceWarning("Exception while generating include data for Target:{0}, Platform: {1}, Configuration: {2}", TargetDesc.Name, Platform.ToString(), Configuration.ToString());
                            Log.TraceWarning(Ex.ToString());
                        }
                    }
                }
            }
            foreach (Tuple <FileReference, UEBuildTarget> tuple in FileToTarget)
            {
                SerializeTarget(tuple.Item1, tuple.Item2);
            }

            return(true);
        }
        /// <summary>
        /// Builds the binary.
        /// </summary>
        /// <param name="Target">Rules for the target being built</param>
        /// <param name="ToolChain">The toolchain which to use for building</param>
        /// <param name="CompileEnvironment">The environment to compile the binary in</param>
        /// <param name="LinkEnvironment">The environment to link the binary in</param>
        /// <param name="SpecificFilesToCompile">If non-empty, specifies individual cpp files to be compiled</param>
        /// <param name="WorkingSet">The working set of source files</param>
        /// <param name="ExeDir">Directory containing the output executable</param>
        /// <param name="Graph">The graph being built</param>
        /// <returns>Set of built products</returns>
        public List <FileItem> Build(ReadOnlyTargetRules Target, UEToolChain ToolChain, CppCompileEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment, List <FileReference> SpecificFilesToCompile, ISourceFileWorkingSet WorkingSet, DirectoryReference ExeDir, IActionGraphBuilder Graph)
        {
            // Return nothing if we're using precompiled binaries. If we're not linking, we might want just one module to be compiled (eg. a foreign plugin), so allow any actions to run.
            if (bUsePrecompiled && !(Target.LinkType == TargetLinkType.Monolithic && Target.bDisableLinking))
            {
                return(new List <FileItem>());
            }

            // Setup linking environment.
            LinkEnvironment BinaryLinkEnvironment = SetupBinaryLinkEnvironment(Target, ToolChain, LinkEnvironment, CompileEnvironment, SpecificFilesToCompile, WorkingSet, ExeDir, Graph);

            // If we're generating projects, we only need include paths and definitions, there is no need to run the linking logic.
            if (ProjectFileGenerator.bGenerateProjectFiles)
            {
                return(BinaryLinkEnvironment.InputFiles);
            }

            // If linking is disabled, our build products are just the compiled object files
            if (Target.bDisableLinking)
            {
                return(BinaryLinkEnvironment.InputFiles);
            }

            // Generate import libraries as a separate step
            List <FileItem> OutputFiles = new List <FileItem>();

            if (bCreateImportLibrarySeparately)
            {
                // Mark the link environment as cross-referenced.
                BinaryLinkEnvironment.bIsCrossReferenced = true;

                if (BinaryLinkEnvironment.Platform != UnrealTargetPlatform.Mac &&
                    BinaryLinkEnvironment.Platform != UnrealTargetPlatform.Linux &&
                    BinaryLinkEnvironment.Platform != UnrealTargetPlatform.LinuxAArch64)
                {
                    // Create the import library.
                    OutputFiles.AddRange(ToolChain.LinkAllFiles(BinaryLinkEnvironment, true, Graph));
                }
            }

            // Link the binary.
            FileItem[] Executables = ToolChain.LinkAllFiles(BinaryLinkEnvironment, false, Graph);
            OutputFiles.AddRange(Executables);

            // Save all the output items for this binary. This is used for hot-reload, and excludes any items added in PostBuild (such as additional files copied into the app).
            if (Target.LinkType == TargetLinkType.Modular)
            {
                Graph.SetOutputItemsForModule(PrimaryModule.Name, OutputFiles.ToArray());
            }

            // Produce additional console app if requested
            if (bBuildAdditionalConsoleApp)
            {
                // Produce additional binary but link it as a console app
                LinkEnvironment ConsoleAppLinkEvironment = new LinkEnvironment(BinaryLinkEnvironment);
                ConsoleAppLinkEvironment.bIsBuildingConsoleApplication = true;
                ConsoleAppLinkEvironment.WindowsEntryPointOverride     = "WinMainCRTStartup";                           // For WinMain() instead of "main()" for Launch module
                ConsoleAppLinkEvironment.OutputFilePaths = ConsoleAppLinkEvironment.OutputFilePaths.Select(Path => GetAdditionalConsoleAppPath(Path)).ToList();

                // Link the console app executable
                FileItem[] ConsoleAppOutputFiles = ToolChain.LinkAllFiles(ConsoleAppLinkEvironment, false, Graph);
                OutputFiles.AddRange(ConsoleAppOutputFiles);

                foreach (FileItem Executable in ConsoleAppOutputFiles)
                {
                    OutputFiles.AddRange(ToolChain.PostBuild(Executable, ConsoleAppLinkEvironment, Graph));
                }
            }

            foreach (FileItem Executable in Executables)
            {
                OutputFiles.AddRange(ToolChain.PostBuild(Executable, BinaryLinkEnvironment, Graph));
            }

            return(OutputFiles);
        }
Exemple #20
0
        /// <summary>
        /// Loads a UBTMakefile from disk
        /// </summary>
        /// <param name="MakefilePath">Path to the makefile to load</param>
        /// <param name="ProjectFile">Path to the project file</param>
        /// <param name="ReasonNotLoaded">If the function returns null, this string will contain the reason why</param>
        /// <param name="WorkingSet">Interface to query which source files are in the working set</param>
        /// <returns>The loaded makefile, or null if it failed for some reason.  On failure, the 'ReasonNotLoaded' variable will contain information about why</returns>
        public static UBTMakefile LoadUBTMakefile(FileReference MakefilePath, FileReference ProjectFile, ISourceFileWorkingSet WorkingSet, out string ReasonNotLoaded)
        {
            // Check the directory timestamp on the project files directory.  If the user has generated project files more
            // recently than the UBTMakefile, then we need to consider the file to be out of date
            FileInfo UBTMakefileInfo = new FileInfo(MakefilePath.FullName);

            if (!UBTMakefileInfo.Exists)
            {
                // UBTMakefile doesn't even exist, so we won't bother loading it
                ReasonNotLoaded = "no existing makefile";
                return(null);
            }

            // Check the build version
            FileInfo BuildVersionFileInfo = new FileInfo(BuildVersion.GetDefaultFileName().FullName);

            if (BuildVersionFileInfo.Exists && UBTMakefileInfo.LastWriteTime.CompareTo(BuildVersionFileInfo.LastWriteTime) < 0)
            {
                Log.TraceVerbose("Existing makefile is older than Build.version, ignoring it");
                ReasonNotLoaded = "Build.version is newer";
                return(null);
            }

            // @todo ubtmake: This will only work if the directory timestamp actually changes with every single GPF.  Force delete existing files before creating new ones?  Eh... really we probably just want to delete + create a file in that folder
            //			-> UPDATE: Seems to work OK right now though on Windows platform, maybe due to GUID changes
            // @todo ubtmake: Some platforms may not save any files into this folder.  We should delete + generate a "touch" file to force the directory timestamp to be updated (or just check the timestamp file itself.  We could put it ANYWHERE, actually)

            // Installed Build doesn't need to check engine projects for outdatedness
            if (!UnrealBuildTool.IsEngineInstalled())
            {
                if (DirectoryReference.Exists(ProjectFileGenerator.IntermediateProjectFilesPath))
                {
                    DateTime EngineProjectFilesLastUpdateTime = new FileInfo(ProjectFileGenerator.ProjectTimestampFile).LastWriteTime;
                    if (UBTMakefileInfo.LastWriteTime.CompareTo(EngineProjectFilesLastUpdateTime) < 0)
                    {
                        // Engine project files are newer than UBTMakefile
                        Log.TraceVerbose("Existing makefile is older than generated engine project files, ignoring it");
                        ReasonNotLoaded = "project files are newer";
                        return(null);
                    }
                }
            }

            // Check the game project directory too
            if (ProjectFile != null)
            {
                string   ProjectFilename = ProjectFile.FullName;
                FileInfo ProjectFileInfo = new FileInfo(ProjectFilename);
                if (!ProjectFileInfo.Exists || UBTMakefileInfo.LastWriteTime.CompareTo(ProjectFileInfo.LastWriteTime) < 0)
                {
                    // .uproject file is newer than UBTMakefile
                    Log.TraceVerbose("Makefile is older than .uproject file, ignoring it");
                    ReasonNotLoaded = ".uproject file is newer";
                    return(null);
                }

                DirectoryReference MasterProjectRelativePath        = ProjectFile.Directory;
                string             GameIntermediateProjectFilesPath = Path.Combine(MasterProjectRelativePath.FullName, "Intermediate", "ProjectFiles");
                if (Directory.Exists(GameIntermediateProjectFilesPath))
                {
                    DateTime GameProjectFilesLastUpdateTime = new DirectoryInfo(GameIntermediateProjectFilesPath).LastWriteTime;
                    if (UBTMakefileInfo.LastWriteTime.CompareTo(GameProjectFilesLastUpdateTime) < 0)
                    {
                        // Game project files are newer than UBTMakefile
                        Log.TraceVerbose("Makefile is older than generated game project files, ignoring it");
                        ReasonNotLoaded = "game project files are newer";
                        return(null);
                    }
                }
            }

            // Check to see if UnrealBuildTool.exe was compiled more recently than the UBTMakefile
            DateTime UnrealBuildToolTimestamp = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime;

            if (UBTMakefileInfo.LastWriteTime.CompareTo(UnrealBuildToolTimestamp) < 0)
            {
                // UnrealBuildTool.exe was compiled more recently than the UBTMakefile
                Log.TraceVerbose("Makefile is older than UnrealBuildTool.exe, ignoring it");
                ReasonNotLoaded = "UnrealBuildTool.exe is newer";
                return(null);
            }

            // Check to see if any BuildConfiguration files have changed since the last build
            List <XmlConfig.InputFile> InputFiles = XmlConfig.FindInputFiles();

            foreach (XmlConfig.InputFile InputFile in InputFiles)
            {
                FileInfo InputFileInfo = new FileInfo(InputFile.Location.FullName);
                if (InputFileInfo.LastWriteTime > UBTMakefileInfo.LastWriteTime)
                {
                    Log.TraceVerbose("Makefile is older than BuildConfiguration.xml, ignoring it");
                    ReasonNotLoaded = "BuildConfiguration.xml is newer";
                    return(null);
                }
            }

            UBTMakefile LoadedUBTMakefile = null;

            try
            {
                DateTime LoadUBTMakefileStartTime = DateTime.UtcNow;

                using (FileStream Stream = new FileStream(UBTMakefileInfo.FullName, FileMode.Open, FileAccess.Read))
                {
                    BinaryFormatter Formatter = new BinaryFormatter();
                    LoadedUBTMakefile = Formatter.Deserialize(Stream) as UBTMakefile;
                }

                if (UnrealBuildTool.bPrintPerformanceInfo)
                {
                    double LoadUBTMakefileTime = (DateTime.UtcNow - LoadUBTMakefileStartTime).TotalSeconds;
                    Log.TraceInformation("LoadUBTMakefile took " + LoadUBTMakefileTime + "s");
                }
            }
            catch (Exception Ex)
            {
                Log.TraceWarning("Failed to read makefile: {0}", Ex.Message);
                Log.TraceLog("Exception: {0}", Ex.ToString());
                ReasonNotLoaded = "couldn't read existing makefile";
                return(null);
            }

            if (!LoadedUBTMakefile.IsValidMakefile())
            {
                Log.TraceWarning("Loaded makefile appears to have invalid contents, ignoring it ({0})", UBTMakefileInfo.FullName);
                ReasonNotLoaded = "existing makefile appears to be invalid";
                return(null);
            }

            // Check if any of the target's Build.cs files are newer than the makefile
            foreach (UEBuildTarget Target in LoadedUBTMakefile.Targets)
            {
                string TargetCsFilename = Target.TargetRulesFile.FullName;
                if (TargetCsFilename != null)
                {
                    FileInfo TargetCsFile        = new FileInfo(TargetCsFilename);
                    bool     bTargetCsFileExists = TargetCsFile.Exists;
                    if (!bTargetCsFileExists || TargetCsFile.LastWriteTime > UBTMakefileInfo.LastWriteTime)
                    {
                        Log.TraceVerbose("{0} has been {1} since makefile was built, ignoring it ({2})", TargetCsFilename, bTargetCsFileExists ? "changed" : "deleted", UBTMakefileInfo.FullName);
                        ReasonNotLoaded = string.Format("changes to target files");
                        return(null);
                    }
                }

                IEnumerable <string> BuildCsFilenames = Target.GetAllModuleBuildCsFilenames();
                foreach (string BuildCsFilename in BuildCsFilenames)
                {
                    if (BuildCsFilename != null)
                    {
                        FileInfo BuildCsFile        = new FileInfo(BuildCsFilename);
                        bool     bBuildCsFileExists = BuildCsFile.Exists;
                        if (!bBuildCsFileExists || BuildCsFile.LastWriteTime > UBTMakefileInfo.LastWriteTime)
                        {
                            Log.TraceVerbose("{0} has been {1} since makefile was built, ignoring it ({2})", BuildCsFilename, bBuildCsFileExists ? "changed" : "deleted", UBTMakefileInfo.FullName);
                            ReasonNotLoaded = string.Format("changes to module files");
                            return(null);
                        }
                    }
                }

                foreach (FlatModuleCsDataType FlatCsModuleData in Target.FlatModuleCsData)
                {
                    if (FlatCsModuleData.BuildCsFilename != null && FlatCsModuleData.ExternalDependencies.Count > 0)
                    {
                        string BaseDir = Path.GetDirectoryName(FlatCsModuleData.BuildCsFilename);
                        foreach (string ExternalDependency in FlatCsModuleData.ExternalDependencies)
                        {
                            FileInfo DependencyFile        = new FileInfo(Path.Combine(BaseDir, ExternalDependency));
                            bool     bDependencyFileExists = DependencyFile.Exists;
                            if (!bDependencyFileExists || DependencyFile.LastWriteTime > UBTMakefileInfo.LastWriteTime)
                            {
                                Log.TraceVerbose("{0} has been {1} since makefile was built, ignoring it ({2})", DependencyFile.FullName, bDependencyFileExists ? "changed" : "deleted", UBTMakefileInfo.FullName);
                                ReasonNotLoaded = string.Format("changes to external dependency");
                                return(null);
                            }
                        }
                    }
                }
            }

            // We do a check to see if any modules' headers have changed which have
            // acquired or lost UHT types.  If so, which should be rare,
            // we'll just invalidate the entire makefile and force it to be rebuilt.
            foreach (UEBuildTarget Target in LoadedUBTMakefile.Targets)
            {
                // Get all H files in processed modules newer than the makefile itself
                HashSet <string> HFilesNewerThanMakefile =
                    new HashSet <string>(
                        Target.FlatModuleCsData
                        .SelectMany(x => x.ModuleSourceFolder != null ? Directory.EnumerateFiles(x.ModuleSourceFolder.FullName, "*.h", SearchOption.AllDirectories) : Enumerable.Empty <string>())
                        .Where(y => Directory.GetLastWriteTimeUtc(y) > UBTMakefileInfo.LastWriteTimeUtc)
                        .OrderBy(z => z).Distinct()
                        );

                // Get all H files in all modules processed in the last makefile build
                HashSet <string> AllUHTHeaders = new HashSet <string>(Target.FlatModuleCsData.SelectMany(x => x.UHTHeaderNames));

                // Check whether any headers have been deleted. If they have, we need to regenerate the makefile since the module might now be empty. If we don't,
                // and the file has been moved to a different module, we may include stale generated headers.
                foreach (string FileName in AllUHTHeaders)
                {
                    if (!File.Exists(FileName))
                    {
                        Log.TraceVerbose("File processed by UHT was deleted ({0}); invalidating makefile", FileName);
                        ReasonNotLoaded = string.Format("UHT file was deleted");
                        return(null);
                    }
                }

                // Makefile is invalid if:
                // * There are any newer files which contain no UHT data, but were previously in the makefile
                // * There are any newer files contain data which needs processing by UHT, but weren't not previously in the makefile
                foreach (string Filename in HFilesNewerThanMakefile)
                {
                    bool bContainsUHTData = CPPHeaders.DoesFileContainUObjects(Filename);
                    bool bWasProcessed    = AllUHTHeaders.Contains(Filename);
                    if (bContainsUHTData != bWasProcessed)
                    {
                        Log.TraceVerbose("{0} {1} contain UHT types and now {2} , ignoring it ({3})", Filename, bWasProcessed ? "used to" : "didn't", bWasProcessed ? "doesn't" : "does", UBTMakefileInfo.FullName);
                        ReasonNotLoaded = string.Format("new files with reflected types");
                        return(null);
                    }
                }
            }

            // If adaptive unity build is enabled, do a check to see if there are any source files that became part of the
            // working set since the Makefile was created (or, source files were removed from the working set.)  If anything
            // changed, then we'll force a new Makefile to be created so that we have fresh unity build blobs.  We always
            // want to make sure that source files in the working set are excluded from those unity blobs (for fastest possible
            // iteration times.)
            if (LoadedUBTMakefile.bUseAdaptiveUnityBuild)
            {
                // Check if any source files in the working set no longer belong in it
                foreach (FileItem SourceFile in LoadedUBTMakefile.SourceFileWorkingSet)
                {
                    if (!WorkingSet.Contains(SourceFile.Location) && File.GetLastWriteTimeUtc(SourceFile.AbsolutePath) > UBTMakefileInfo.LastWriteTimeUtc)
                    {
                        Log.TraceVerbose("{0} was part of source working set and now is not; invalidating makefile ({1})", SourceFile.AbsolutePath, UBTMakefileInfo.FullName);
                        ReasonNotLoaded = string.Format("working set of source files changed");
                        return(null);
                    }
                }

                // Check if any source files that are eligible for being in the working set have been modified
                foreach (FileItem SourceFile in LoadedUBTMakefile.CandidateSourceFilesForWorkingSet)
                {
                    if (WorkingSet.Contains(SourceFile.Location) && File.GetLastWriteTimeUtc(SourceFile.AbsolutePath) > UBTMakefileInfo.LastWriteTimeUtc)
                    {
                        Log.TraceVerbose("{0} was part of source working set and now is not; invalidating makefile ({1})", SourceFile.AbsolutePath, UBTMakefileInfo.FullName);
                        ReasonNotLoaded = string.Format("working set of source files changed");
                        return(null);
                    }
                }
            }

            ReasonNotLoaded = null;
            return(LoadedUBTMakefile);
        }
        /// <summary>
        /// Gets all the runtime dependencies Copies all the runtime dependencies from any modules in
        /// </summary>
        /// <param name="RuntimeDependencies">The output list of runtime dependencies, mapping target file to type</param>
        /// <param name="TargetFileToSourceFile">Map of target files to source files that need to be copied</param>
        /// <param name="ExeDir">Output directory for the executable</param>
        public void PrepareRuntimeDependencies(List <RuntimeDependency> RuntimeDependencies, Dictionary <FileReference, FileReference> TargetFileToSourceFile, DirectoryReference ExeDir)
        {
            foreach (UEBuildModule Module in Modules)
            {
                foreach (ModuleRules.RuntimeDependency Dependency in Module.Rules.RuntimeDependencies.Inner)
                {
                    if (Dependency.SourcePath == null)
                    {
                        // Expand the target path
                        string ExpandedPath = Module.ExpandPathVariables(Dependency.Path, OutputDir, ExeDir);
                        if (FileFilter.FindWildcardIndex(ExpandedPath) == -1)
                        {
                            RuntimeDependencies.Add(new RuntimeDependency(new FileReference(ExpandedPath), Dependency.Type));
                        }
                        else
                        {
                            RuntimeDependencies.AddRange(FileFilter.ResolveWildcard(ExpandedPath).Select(x => new RuntimeDependency(x, Dependency.Type)));
                        }
                    }
                    else
                    {
                        // Parse the source and target patterns
                        FilePattern SourcePattern = new FilePattern(UnrealBuildTool.EngineSourceDirectory, Module.ExpandPathVariables(Dependency.SourcePath, OutputDir, ExeDir));
                        FilePattern TargetPattern = new FilePattern(UnrealBuildTool.EngineSourceDirectory, Module.ExpandPathVariables(Dependency.Path, OutputDir, ExeDir));

                        // Skip non-essential single files if they do not exist
                        if (Dependency.Type == StagedFileType.DebugNonUFS && !SourcePattern.ContainsWildcards() && !FileReference.Exists(SourcePattern.GetSingleFile()))
                        {
                            continue;
                        }

                        // Resolve all the wildcards between the source and target paths
                        Dictionary <FileReference, FileReference> Mapping;
                        try
                        {
                            Mapping = FilePattern.CreateMapping(null, ref SourcePattern, ref TargetPattern);
                        }
                        catch (FilePatternException Ex)
                        {
                            ExceptionUtils.AddContext(Ex, "while creating runtime dependencies for module '{0}'", Module.Name);
                            throw;
                        }

                        // Add actions to copy everything
                        foreach (KeyValuePair <FileReference, FileReference> Pair in Mapping)
                        {
                            FileReference ExistingSourceFile;
                            if (!TargetFileToSourceFile.TryGetValue(Pair.Key, out ExistingSourceFile))
                            {
                                TargetFileToSourceFile[Pair.Key] = Pair.Value;
                                RuntimeDependencies.Add(new RuntimeDependency(Pair.Key, Dependency.Type));
                            }
                            else if (ExistingSourceFile != Pair.Value)
                            {
                                throw new BuildException("Runtime dependency '{0}' is configured to be staged from '{1}' and '{2}'", Pair.Key, Pair.Value, ExistingSourceFile);
                            }
                        }
                    }
                }
            }
        }
Exemple #22
0
        public override void SetUpProjectEnvironment(UnrealTargetConfiguration Configuration, TargetInfo Target = null)
        {
            if (!bInitializedProject)
            {
                base.SetUpProjectEnvironment(Configuration, Target);

                // update the configuration based on the project file
                // look in ini settings for what platforms to compile for
                ConfigCacheIni Ini        = ConfigCacheIni.CreateConfigCacheIni(Platform, "Engine", DirectoryReference.FromFile(ProjectFile));
                string         MinVersion = "IOS_8";
                if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion))
                {
                    switch (MinVersion)
                    {
                    case "IOS_61":
                        Log.TraceWarningOnce("IOS 6 is no longer supported in UE4 as 4.11");
                        RunTimeIOSVersion = "8.0";
                        break;

                    case "IOS_7":
                        Log.TraceWarningOnce("IOS 7 is no longer supported in UE4 as 4.14");
                        RunTimeIOSVersion = "8.0";
                        break;

                    case "IOS_8":
                        RunTimeIOSVersion = "8.0";
                        break;

                    case "IOS_9":
                        RunTimeIOSVersion = "9.0";
                        break;

                    case "IOS_10":
                        RunTimeIOSVersion = "10.0";
                        break;
                    }
                }

                bool biPhoneAllowed = true;
                bool biPadAllowed   = true;
                Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPhone", out biPhoneAllowed);
                Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsIPad", out biPadAllowed);
                if (biPhoneAllowed && biPadAllowed)
                {
                    RunTimeIOSDevices = "1,2";
                }
                else if (biPadAllowed)
                {
                    RunTimeIOSDevices = "2";
                }
                else if (biPhoneAllowed)
                {
                    RunTimeIOSDevices = "1";
                }

                ProjectArches = new List <string>();
                bool bBuild = true;
                if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7", out bBuild) && bBuild)
                {
                    ProjectArches.Add("armv7");
                }
                if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArm64", out bBuild) && bBuild)
                {
                    ProjectArches.Add("arm64");
                }
                if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDevForArmV7S", out bBuild) && bBuild)
                {
                    ProjectArches.Add("armv7s");
                }

                // force armv7 if something went wrong
                if (ProjectArches.Count == 0)
                {
                    ProjectArches.Add("armv7");
                }
                NonShippingArchitectures = ProjectArches[0];
                for (int Index = 1; Index < ProjectArches.Count; ++Index)
                {
                    NonShippingArchitectures += "," + ProjectArches[Index];
                }

                ProjectArches.Clear();
                if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7", out bBuild) && bBuild)
                {
                    ProjectArches.Add("armv7");
                }
                if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArm64", out bBuild) && bBuild)
                {
                    ProjectArches.Add("arm64");
                }
                if (Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForArmV7S", out bBuild) && bBuild)
                {
                    ProjectArches.Add("armv7s");
                }

                // force armv7 if something went wrong
                if (ProjectArches.Count == 0)
                {
                    ProjectArches.Add("armv7");
                    ProjectArches.Add("arm64");
                }
                ShippingArchitectures = ProjectArches[0];
                for (int Index = 1; Index < ProjectArches.Count; ++Index)
                {
                    ShippingArchitectures += "," + ProjectArches[Index];
                }

                // determine if we need to generate the dsym
                Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMFile", out BuildConfiguration.bGeneratedSYMFile);
                Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGeneratedSYMBundle", out BuildConfiguration.bGeneratedSYMBundle);

                // determie if bitcode should be generated for the shipping code
                Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bShipForBitcode", out bShipForBitcode);

                // @todo tvos: We probably want to handle TVOS versions here
                Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalLinkerFlags", out AdditionalLinkerFlags);
                Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalShippingLinkerFlags", out AdditionalShippingLinkerFlags);

                Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MobileProvision", out MobileProvision);
                Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SigningCertificate", out SigningCertificate);

                // bundle identifier
                Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier);

                bInitializedProject = true;
            }

            ProvisionData Data     = new ProvisionData();
            string        BundleId = BundleIdentifier.Replace("[PROJECT_NAME]", ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game")).Replace("_", "");
            bool          bIsTVOS  = GetCodesignPlatformName() == "appletvos";

            if (!ProvisionCache.ContainsKey(BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString()))
            {
                Certificate = SigningCertificate;
                Provision   = MobileProvision;
                if (!string.IsNullOrEmpty(SigningCertificate))
                {
                    // verify the certificate
                    Process IPPProcess = new Process();
                    if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                    {
                        string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bForDistribtion ? " -distribution" : "");
                        IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
                        IPPProcess.StartInfo.FileName         = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh";
                        IPPProcess.StartInfo.Arguments        = IPPCmd;
                        IPPProcess.OutputDataReceived        += new DataReceivedEventHandler(IPPDataReceivedHandler);
                        IPPProcess.ErrorDataReceived         += new DataReceivedEventHandler(IPPDataReceivedHandler);
                    }
                    else
                    {
                        string IPPCmd = "certificates " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bForDistribtion ? " -distribution" : "");
                        IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
                        IPPProcess.StartInfo.FileName         = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe";
                        IPPProcess.StartInfo.Arguments        = IPPCmd;
                        IPPProcess.OutputDataReceived        += new DataReceivedEventHandler(IPPDataReceivedHandler);
                        IPPProcess.ErrorDataReceived         += new DataReceivedEventHandler(IPPDataReceivedHandler);
                    }
                    Utils.RunLocalProcess(IPPProcess);
                }
                else
                {
                    Certificate      = bForDistribtion ? "iPhone Distribution" : "iPhone Developer";
                    bHaveCertificate = true;
                }

                if (string.IsNullOrEmpty(MobileProvision) || // no provision specified
                    !File.Exists((BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac ? (Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/") : (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/")) + MobileProvision) || // file doesn't exist
                    !bHaveCertificate)    // certificate doesn't exist
                {
                    Certificate = "";
                    Provision   = "";
                    Log.TraceLog("Provision not specified or not found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", searching for compatible match...");
                    Process IPPProcess = new Process();
                    if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                    {
                        string IPPCmd = "\"" + UnrealBuildTool.EngineDirectory + "/Binaries/DotNET/IOS/IPhonePackager.exe\" signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : "");
                        IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
                        IPPProcess.StartInfo.FileName         = UnrealBuildTool.EngineDirectory + "/Build/BatchFiles/Mac/RunMono.sh";
                        IPPProcess.StartInfo.Arguments        = IPPCmd;
                        IPPProcess.OutputDataReceived        += new DataReceivedEventHandler(IPPDataReceivedHandler);
                        IPPProcess.ErrorDataReceived         += new DataReceivedEventHandler(IPPDataReceivedHandler);
                    }
                    else
                    {
                        string IPPCmd = "signing_match " + ((ProjectFile != null) ? ("\"" + ProjectFile.ToString() + "\"") : "Engine") + " -bundlename " + BundleId + (bIsTVOS ? " -tvos" : "") + (bForDistribtion ? " -distribution" : "");
                        IPPProcess.StartInfo.WorkingDirectory = UnrealBuildTool.EngineDirectory.ToString();
                        IPPProcess.StartInfo.FileName         = UnrealBuildTool.EngineDirectory + "\\Binaries\\DotNET\\IOS\\IPhonePackager.exe";
                        IPPProcess.StartInfo.Arguments        = IPPCmd;
                        IPPProcess.OutputDataReceived        += new DataReceivedEventHandler(IPPDataReceivedHandler);
                        IPPProcess.ErrorDataReceived         += new DataReceivedEventHandler(IPPDataReceivedHandler);
                    }
                    Utils.RunLocalProcess(IPPProcess);
                    Log.TraceLog("Provision found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", Provision: " + Provision + " Certificate: " + Certificate);
                }
                // add to the dictionary
                Data.MobileProvision = Provision;
                Data.Certificate     = Certificate.Replace("\"", "");

                // read the provision to get the UUID
                string filename = (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac ? (Environment.GetEnvironmentVariable("HOME") + "/Library/MobileDevice/Provisioning Profiles/") : (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Apple Computer/MobileDevice/Provisioning Profiles/")) + Data.MobileProvision;
                if (File.Exists(filename))
                {
                    string AllText = File.ReadAllText(filename);
                    int    idx     = AllText.IndexOf("<key>UUID</key>");
                    if (idx > 0)
                    {
                        idx = AllText.IndexOf("<string>", idx);
                        if (idx > 0)
                        {
                            idx      += "<string>".Length;
                            Data.UUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx);
                        }
                    }
                    idx = AllText.IndexOf("<key>com.apple.developer.team-identifier</key>");
                    if (idx > 0)
                    {
                        idx = AllText.IndexOf("<string>", idx);
                        if (idx > 0)
                        {
                            idx          += "<string>".Length;
                            Data.TeamUUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx);
                        }
                    }
                }
                else
                {
                    Log.TraceLog("No matching provision file was discovered. Please ensure you have a compatible provision installed.");
                }
                ProvisionCache.Add(BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString(), Data);
            }
            else
            {
                Data = ProvisionCache[BundleId + " " + bIsTVOS.ToString() + " " + bForDistribtion.ToString()];
            }
            MobileProvision     = Data.MobileProvision;
            SigningCertificate  = Data.Certificate;
            MobileProvisionUUID = Data.UUID;
            TeamUUID            = Data.TeamUUID;
        }
        /// <summary>
        /// Gets all build products produced by this binary
        /// </summary>
        /// <param name="Target">The target being built</param>
        /// <param name="ToolChain">The platform toolchain</param>
        /// <param name="BuildProducts">Mapping of produced build product to type</param>
        /// <param name="bCreateDebugInfo">Whether debug info is enabled for this binary</param>
        public void GetBuildProducts(ReadOnlyTargetRules Target, UEToolChain ToolChain, Dictionary <FileReference, BuildProductType> BuildProducts, bool bCreateDebugInfo)
        {
            // Add all the precompiled outputs
            foreach (UEBuildModuleCPP Module in Modules.OfType <UEBuildModuleCPP>())
            {
                if (Module.Rules.bPrecompile)
                {
                    if (Module.GeneratedCodeDirectory != null && DirectoryReference.Exists(Module.GeneratedCodeDirectory))
                    {
                        foreach (FileReference GeneratedCodeFile in DirectoryReference.EnumerateFiles(Module.GeneratedCodeDirectory))
                        {
                            // Exclude timestamp files, since they're always updated and cause collisions between builds
                            if (!GeneratedCodeFile.GetFileName().Equals("Timestamp", StringComparison.OrdinalIgnoreCase) && !GeneratedCodeFile.HasExtension(".cpp"))
                            {
                                BuildProducts.Add(GeneratedCodeFile, BuildProductType.BuildResource);
                            }
                        }
                    }
                    if (Target.LinkType == TargetLinkType.Monolithic)
                    {
                        FileReference PrecompiledManifestLocation = Module.PrecompiledManifestLocation;
                        BuildProducts.Add(PrecompiledManifestLocation, BuildProductType.BuildResource);

                        PrecompiledManifest ModuleManifest = PrecompiledManifest.Read(PrecompiledManifestLocation);
                        foreach (FileReference OutputFile in ModuleManifest.OutputFiles)
                        {
                            if (!BuildProducts.ContainsKey(OutputFile))
                            {
                                BuildProducts.Add(OutputFile, BuildProductType.BuildResource);
                            }
                        }
                    }
                }
            }

            // Add all the binary outputs
            if (!Target.bDisableLinking)
            {
                // Get the type of build products we're creating
                BuildProductType OutputType = BuildProductType.RequiredResource;
                switch (Type)
                {
                case UEBuildBinaryType.Executable:
                    OutputType = BuildProductType.Executable;
                    break;

                case UEBuildBinaryType.DynamicLinkLibrary:
                    OutputType = BuildProductType.DynamicLibrary;
                    break;

                case UEBuildBinaryType.StaticLibrary:
                    OutputType = BuildProductType.BuildResource;
                    break;
                }

                // Add the primary build products
                string[] DebugExtensions = UEBuildPlatform.GetBuildPlatform(Target.Platform).GetDebugInfoExtensions(Target, Type);
                foreach (FileReference OutputFilePath in OutputFilePaths)
                {
                    AddBuildProductAndDebugFiles(OutputFilePath, OutputType, DebugExtensions, BuildProducts, ToolChain, bCreateDebugInfo);
                }

                // Add the console app, if there is one
                if (Type == UEBuildBinaryType.Executable && bBuildAdditionalConsoleApp)
                {
                    foreach (FileReference OutputFilePath in OutputFilePaths)
                    {
                        AddBuildProductAndDebugFiles(GetAdditionalConsoleAppPath(OutputFilePath), OutputType, DebugExtensions, BuildProducts, ToolChain, bCreateDebugInfo);
                    }
                }

                // Add any additional build products from the modules in this binary, including additional bundle resources/dylibs on Mac.
                List <string> Libraries = new List <string>();
                List <UEBuildBundleResource> BundleResources = new List <UEBuildBundleResource>();
                GatherAdditionalResources(Libraries, BundleResources);

                // Add any extra files from the toolchain
                ToolChain.ModifyBuildProducts(Target, this, Libraries, BundleResources, BuildProducts);
            }
        }
        /// <summary>
        /// Reads a config hierarchy (or retrieve it from the cache)
        /// </summary>
        /// <param name="Type">The type of hierarchy to read</param>
        /// <param name="ProjectDir">The project directory to read the hierarchy for</param>
        /// <param name="Platform">Which platform to read platform-specific config files for</param>
        /// <param name="GeneratedConfigDir">Base directory for generated configs</param>
        /// <returns>The requested config hierarchy</returns>
        public static ConfigHierarchy ReadHierarchy(ConfigHierarchyType Type, DirectoryReference ProjectDir, UnrealTargetPlatform Platform, DirectoryReference GeneratedConfigDir = null)
        {
            // Get the key to use for the cache. It cannot be null, so we use the engine directory if a project directory is not given.
            ConfigHierarchyKey Key = new ConfigHierarchyKey(Type, ProjectDir, Platform);

            // Try to get the cached hierarchy with this key
            ConfigHierarchy Hierarchy;

            lock (HierarchyKeyToHierarchy)
            {
                if (!HierarchyKeyToHierarchy.TryGetValue(Key, out Hierarchy))
                {
                    List <ConfigFile> Files = new List <ConfigFile>();
                    foreach (FileReference IniFileName in ConfigHierarchy.EnumerateConfigFileLocations(Type, ProjectDir, Platform))
                    {
                        ConfigFile File;
                        if (TryReadFile(IniFileName, out File))
                        {
                            Files.Add(File);
                        }
                    }

                    // If we haven't been given a generated project dir, but we do have a project then the generated configs
                    // should go into ProjectDir/Saved
                    if (GeneratedConfigDir == null && ProjectDir != null)
                    {
                        GeneratedConfigDir = DirectoryReference.Combine(ProjectDir, "Saved");
                    }

                    if (GeneratedConfigDir != null)
                    {
                        // We know where the generated version of this config file lives, so we can read it back in
                        // and include any user settings from there in our hierarchy
                        string        BaseIniName            = Enum.GetName(typeof(ConfigHierarchyType), Type);
                        string        PlatformName           = ConfigHierarchy.GetIniPlatformName(Platform);
                        FileReference DestinationIniFilename = FileReference.Combine(GeneratedConfigDir, "Config", PlatformName, BaseIniName + ".ini");
                        ConfigFile    File;
                        if (TryReadFile(DestinationIniFilename, out File))
                        {
                            Files.Add(File);
                        }
                    }

                    // Handle command line overrides
                    string[] CmdLine            = Environment.GetCommandLineArgs();
                    string   IniConfigArgPrefix = "-ini:" + Enum.GetName(typeof(ConfigHierarchyType), Type) + ":";
                    foreach (string CmdLineArg in CmdLine)
                    {
                        if (CmdLineArg.StartsWith(IniConfigArgPrefix))
                        {
                            ConfigFile OverrideFile = new ConfigFile(CmdLineArg.Substring(IniConfigArgPrefix.Length));
                            Files.Add(OverrideFile);
                        }
                    }

                    Hierarchy = new ConfigHierarchy(Files);
                    HierarchyKeyToHierarchy.Add(Key, Hierarchy);
                }
            }
            return(Hierarchy);
        }
        /// <summary>
        /// Checks whether the binary output paths are appropriate for the distribution
        /// level of its direct module dependencies
        /// </summary>
        public bool CheckRestrictedFolders(List <DirectoryReference> RootDirectories, Dictionary <UEBuildModule, Dictionary <RestrictedFolder, DirectoryReference> > ModuleRestrictedFolderCache)
        {
            // Find all the modules we depend on
            Dictionary <UEBuildModule, UEBuildModule> ModuleReferencedBy = new Dictionary <UEBuildModule, UEBuildModule>();

            FindModuleReferences(ModuleReferencedBy);

            // Loop through each of the output binaries and check them separately
            bool bResult = true;

            foreach (FileReference OutputFilePath in OutputFilePaths)
            {
                // Find the base directory for this binary
                DirectoryReference BaseDir = RootDirectories.FirstOrDefault(x => OutputFilePath.IsUnderDirectory(x));
                if (BaseDir == null)
                {
                    continue;
                }

                // Find the permitted restricted folder references under the base directory
                List <RestrictedFolder> BinaryFolders = RestrictedFolders.FindPermittedRestrictedFolderReferences(BaseDir, OutputFilePath.Directory);

                List <RestrictedFolder> AliasedBinaryFolders = new List <RestrictedFolder>();
                foreach (RestrictedFolder BinaryFolder in BinaryFolders)
                {
                    string Alias;
                    if (PrimaryModule.AliasRestrictedFolders.TryGetValue(BinaryFolder.ToString(), out Alias))
                    {
                        foreach (RestrictedFolder Folder in RestrictedFolder.GetValues())
                        {
                            if (Folder.ToString().Equals(Alias))
                            {
                                AliasedBinaryFolders.Add(Folder);
                            }
                        }
                    }
                }
                BinaryFolders.AddRange(AliasedBinaryFolders);

                // Check all the dependent modules
                foreach (UEBuildModule Module in ModuleReferencedBy.Keys)
                {
                    // Find the restricted folders for this module
                    Dictionary <RestrictedFolder, DirectoryReference> ModuleRestrictedFolders;
                    if (!ModuleRestrictedFolderCache.TryGetValue(Module, out ModuleRestrictedFolders))
                    {
                        ModuleRestrictedFolders = Module.FindRestrictedFolderReferences(RootDirectories);
                        ModuleRestrictedFolderCache.Add(Module, ModuleRestrictedFolders);
                    }

                    // Write errors for any missing paths in the output files
                    foreach (KeyValuePair <RestrictedFolder, DirectoryReference> Pair in ModuleRestrictedFolders)
                    {
                        if (!BinaryFolders.Contains(Pair.Key))
                        {
                            List <string> ReferenceChain = new List <string>();
                            for (UEBuildModule ReferencedModule = Module; ReferencedModule != null; ReferencedModule = ModuleReferencedBy[ReferencedModule])
                            {
                                ReferenceChain.Insert(0, ReferencedModule.Name);
                            }
                            Log.TraceError("Output binary \"{0}\" is not in a {1} folder, but references \"{2}\" via {3}.", OutputFilePath, Pair.Key.ToString(), Pair.Value, String.Join(" -> ", ReferenceChain));
                            bResult = false;
                        }
                    }
                }
            }
            return(bResult);
        }
Exemple #26
0
        /// <summary>
        /// Given a set of C++ files, generates another set of C++ files that #include all the original
        /// files, the goal being to compile the same code in fewer translation units.
        /// The "unity" files are written to the CompileEnvironment's OutputDirectory.
        /// </summary>
        /// <param name="Target">The target we're building</param>
        /// <param name="CPPFiles">The C++ files to #include.</param>
        /// <param name="CompileEnvironment">The environment that is used to compile the C++ files.</param>
        /// <param name="WorkingSet">Interface to query files which belong to the working set</param>
        /// <param name="BaseName">Base name to use for the Unity files</param>
        /// <param name="IntermediateDirectory">Intermediate directory for unity cpp files</param>
        /// <param name="Graph">The makefile being built</param>
        /// <param name="SourceFileToUnityFile">Receives a mapping of source file to unity file</param>
        /// <returns>The "unity" C++ files.</returns>
        public static List <FileItem> GenerateUnityCPPs(
            ReadOnlyTargetRules Target,
            List <FileItem> CPPFiles,
            CppCompileEnvironment CompileEnvironment,
            ISourceFileWorkingSet WorkingSet,
            string BaseName,
            DirectoryReference IntermediateDirectory,
            IActionGraphBuilder Graph,
            Dictionary <FileItem, FileItem> SourceFileToUnityFile
            )
        {
            List <FileItem> NewCPPFiles = new List <FileItem>();

            //UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(CompileEnvironment.Platform);

            // Figure out size of all input files combined. We use this to determine whether to use larger unity threshold or not.
            long TotalBytesInCPPFiles = CPPFiles.Sum(F => F.Length);

            // We have an increased threshold for unity file size if, and only if, all files fit into the same unity file. This
            // is beneficial when dealing with PCH files. The default PCH creation limit is X unity files so if we generate < X
            // this could be fairly slow and we'd rather bump the limit a bit to group them all into the same unity file.


            // When enabled, UnrealBuildTool will try to determine source files that you are actively iteratively changing, and break those files
            // out of their unity blobs so that you can compile them as individual translation units, much faster than recompiling the entire
            // unity blob each time.
            bool bUseAdaptiveUnityBuild = Target.bUseAdaptiveUnityBuild && !Target.bStressTestUnity;

            // Optimization only makes sense if PCH files are enabled.
            bool bForceIntoSingleUnityFile = Target.bStressTestUnity || (TotalBytesInCPPFiles < Target.NumIncludedBytesPerUnityCPP * 2 && Target.bUsePCHFiles);

            // Build the list of unity files.
            List <FileCollection> AllUnityFiles;
            {
                // Sort the incoming file paths alphabetically, so there will be consistency in unity blobs across multiple machines.
                // Note that we're relying on this not only sorting files within each directory, but also the directories
                // themselves, so the whole list of file paths is the same across computers.
                List <FileItem> SortedCPPFiles = CPPFiles.GetRange(0, CPPFiles.Count);
                {
                    // Case-insensitive file path compare, because you never know what is going on with local file systems
                    Comparison <FileItem> FileItemComparer = (FileA, FileB) => { return(FileA.AbsolutePath.ToLowerInvariant().CompareTo(FileB.AbsolutePath.ToLowerInvariant())); };
                    SortedCPPFiles.Sort(FileItemComparer);
                }


                // Figure out whether we REALLY want to use adaptive unity for this module.  If nearly every file in the module appears in the working
                // set, we'll just go ahead and let unity build do its thing.
                HashSet <FileItem> FilesInWorkingSet = new HashSet <FileItem>();
                if (bUseAdaptiveUnityBuild)
                {
                    int CandidateWorkingSetSourceFileCount = 0;
                    int WorkingSetSourceFileCount          = 0;
                    foreach (FileItem CPPFile in SortedCPPFiles)
                    {
                        ++CandidateWorkingSetSourceFileCount;

                        // Don't include writable source files into unity blobs
                        if (WorkingSet.Contains(CPPFile))
                        {
                            ++WorkingSetSourceFileCount;

                            // Mark this file as part of the working set.  This will be saved into the UBT Makefile so that
                            // the assembler can automatically invalidate the Makefile when the working set changes (allowing this
                            // code to run again, to build up new unity blobs.)
                            FilesInWorkingSet.Add(CPPFile);
                            Graph.AddFileToWorkingSet(CPPFile);
                        }
                    }

                    if (WorkingSetSourceFileCount >= CandidateWorkingSetSourceFileCount)
                    {
                        // Every single file in the module appears in the working set, so don't bother using adaptive unity for this
                        // module.  Otherwise it would make full builds really slow.
                        bUseAdaptiveUnityBuild = false;
                    }
                }

                UnityFileBuilder CPPUnityFileBuilder          = new UnityFileBuilder(bForceIntoSingleUnityFile ? -1 : Target.NumIncludedBytesPerUnityCPP);
                StringBuilder    AdaptiveUnityBuildInfoString = new StringBuilder();
                foreach (FileItem CPPFile in SortedCPPFiles)
                {
                    if (!bForceIntoSingleUnityFile && CPPFile.AbsolutePath.IndexOf(".GeneratedWrapper.", StringComparison.InvariantCultureIgnoreCase) != -1)
                    {
                        NewCPPFiles.Add(CPPFile);
                    }

                    // When adaptive unity is enabled, go ahead and exclude any source files that we're actively working with
                    if (bUseAdaptiveUnityBuild && FilesInWorkingSet.Contains(CPPFile))
                    {
                        // Just compile this file normally, not as part of the unity blob
                        NewCPPFiles.Add(CPPFile);

                        // Let the unity file builder know about the file, so that we can retain the existing size of the unity blobs.
                        // This won't actually make the source file part of the unity blob, but it will keep track of how big the
                        // file is so that other existing unity blobs from the same module won't be invalidated.  This prevents much
                        // longer compile times the first time you build after your working file set changes.
                        CPPUnityFileBuilder.AddVirtualFile(CPPFile);

                        string CPPFileName = Path.GetFileName(CPPFile.AbsolutePath);
                        if (AdaptiveUnityBuildInfoString.Length == 0)
                        {
                            AdaptiveUnityBuildInfoString.Append(String.Format("[Adaptive unity build] Excluded from {0} unity file: {1}", BaseName, CPPFileName));
                        }
                        else
                        {
                            AdaptiveUnityBuildInfoString.Append(", " + CPPFileName);
                        }
                    }
                    else
                    {
                        // If adaptive unity build is enabled for this module, add this source file to the set that will invalidate the makefile
                        if (bUseAdaptiveUnityBuild)
                        {
                            Graph.AddCandidateForWorkingSet(CPPFile);
                        }

                        // Compile this file as part of the unity blob
                        CPPUnityFileBuilder.AddFile(CPPFile);
                    }
                }

                if (AdaptiveUnityBuildInfoString.Length > 0)
                {
                    if (Target.bAdaptiveUnityCreatesDedicatedPCH)
                    {
                        Graph.AddDiagnostic("[Adaptive unity build] Creating dedicated PCH for each excluded file. Set bAdaptiveUnityCreatesDedicatedPCH to false in BuildConfiguration.xml to change this behavior.");
                    }
                    else if (Target.bAdaptiveUnityDisablesPCH)
                    {
                        Graph.AddDiagnostic("[Adaptive unity build] Disabling PCH for excluded files. Set bAdaptiveUnityDisablesPCH to false in BuildConfiguration.xml to change this behavior.");
                    }

                    if (Target.bAdaptiveUnityDisablesOptimizations)
                    {
                        Graph.AddDiagnostic("[Adaptive unity build] Disabling optimizations for excluded files. Set bAdaptiveUnityDisablesOptimizations to false in BuildConfiguration.xml to change this behavior.");
                    }
                    if (Target.bAdaptiveUnityEnablesEditAndContinue)
                    {
                        Graph.AddDiagnostic("[Adaptive unity build] Enabling Edit & Continue for excluded files. Set bAdaptiveUnityEnablesEditAndContinue to false in BuildConfiguration.xml to change this behavior.");
                    }

                    Graph.AddDiagnostic(AdaptiveUnityBuildInfoString.ToString());
                }

                AllUnityFiles = CPPUnityFileBuilder.GetUnityFiles();
            }

            // Create a set of CPP files that combine smaller CPP files into larger compilation units, along with the corresponding
            // actions to compile them.
            int CurrentUnityFileCount = 0;

            foreach (FileCollection UnityFile in AllUnityFiles)
            {
                ++CurrentUnityFileCount;

                StringWriter OutputUnityCPPWriter = new StringWriter();

                OutputUnityCPPWriter.WriteLine("// This file is automatically generated at compile-time to include some subset of the user-created cpp files.");

                // Add source files to the unity file
                foreach (FileItem CPPFile in UnityFile.Files)
                {
                    OutputUnityCPPWriter.WriteLine("#include \"{0}\"", CPPFile.AbsolutePath.Replace('\\', '/'));
                }

                // Determine unity file path name
                string UnityCPPFileName;
                if (AllUnityFiles.Count > 1)
                {
                    UnityCPPFileName = string.Format("{0}{1}.{2}_of_{3}.cpp", ModulePrefix, BaseName, CurrentUnityFileCount, AllUnityFiles.Count);
                }
                else
                {
                    UnityCPPFileName = string.Format("{0}{1}.cpp", ModulePrefix, BaseName);
                }
                FileReference UnityCPPFilePath = FileReference.Combine(IntermediateDirectory, UnityCPPFileName);

                // Write the unity file to the intermediate folder.
                FileItem UnityCPPFile = Graph.CreateIntermediateTextFile(UnityCPPFilePath, OutputUnityCPPWriter.ToString());
                NewCPPFiles.Add(UnityCPPFile);

                // Store the mapping of source files to unity files in the makefile
                foreach (FileItem SourceFile in UnityFile.Files)
                {
                    SourceFileToUnityFile[SourceFile] = UnityCPPFile;
                }
                foreach (FileItem SourceFile in UnityFile.VirtualFiles)
                {
                    SourceFileToUnityFile[SourceFile] = UnityCPPFile;
                }
            }

            return(NewCPPFiles);
        }
        private LinkEnvironment SetupBinaryLinkEnvironment(ReadOnlyTargetRules Target, UEToolChain ToolChain, LinkEnvironment LinkEnvironment, CppCompileEnvironment CompileEnvironment, List <FileReference> SpecificFilesToCompile, ISourceFileWorkingSet WorkingSet, DirectoryReference ExeDir, IActionGraphBuilder Graph)
        {
            LinkEnvironment         BinaryLinkEnvironment         = new LinkEnvironment(LinkEnvironment);
            HashSet <UEBuildModule> LinkEnvironmentVisitedModules = new HashSet <UEBuildModule>();
            List <UEBuildBinary>    BinaryDependencies            = new List <UEBuildBinary>();

            CppCompileEnvironment BinaryCompileEnvironment = CreateBinaryCompileEnvironment(CompileEnvironment);

            if (BinaryCompileEnvironment.bUseSharedBuildEnvironment && Target.ProjectFile != null && IntermediateDirectory.IsUnderDirectory(Target.ProjectFile.Directory))
            {
                BinaryCompileEnvironment.bUseSharedBuildEnvironment = false;
            }

            foreach (UEBuildModule Module in Modules)
            {
                List <FileItem> LinkInputFiles;
                if (Module.Binary == null || Module.Binary == this)
                {
                    // Compile each module.
                    Log.TraceVerbose("Compile module: " + Module.Name);
                    LinkInputFiles = Module.Compile(Target, ToolChain, BinaryCompileEnvironment, SpecificFilesToCompile, WorkingSet, Graph);

                    // Save the module outputs. In monolithic builds, this is just the object files.
                    if (Target.LinkType == TargetLinkType.Monolithic)
                    {
                        Graph.SetOutputItemsForModule(Module.Name, LinkInputFiles.ToArray());
                    }

                    // NOTE: Because of 'Shared PCHs', in monolithic builds the same PCH file may appear as a link input
                    // multiple times for a single binary.  We'll check for that here, and only add it once.  This avoids
                    // a linker warning about redundant .obj files.
                    foreach (FileItem LinkInputFile in LinkInputFiles)
                    {
                        if (!BinaryLinkEnvironment.InputFiles.Contains(LinkInputFile))
                        {
                            BinaryLinkEnvironment.InputFiles.Add(LinkInputFile);
                        }
                    }

                    // Force a reference to initialize module for this binary
                    if (Module.Rules.bRequiresImplementModule.Value)
                    {
                        BinaryLinkEnvironment.IncludeFunctions.Add(String.Format("IMPLEMENT_MODULE_{0}", Module.Name));
                    }
                }
                else
                {
                    BinaryDependencies.Add(Module.Binary);
                }

                // Allow the module to modify the link environment for the binary.
                Module.SetupPrivateLinkEnvironment(this, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules, ExeDir);
            }


            // Allow the binary dependencies to modify the link environment.
            foreach (UEBuildBinary BinaryDependency in BinaryDependencies)
            {
                BinaryDependency.SetupDependentLinkEnvironment(BinaryLinkEnvironment);
            }

            // Set the link output file.
            BinaryLinkEnvironment.OutputFilePaths = OutputFilePaths.ToList();

            // Set whether the link is allowed to have exports.
            BinaryLinkEnvironment.bHasExports = bAllowExports;

            // Set the output folder for intermediate files
            BinaryLinkEnvironment.IntermediateDirectory = IntermediateDirectory;

            // Put the non-executable output files (PDB, import library, etc) in the same directory as the production
            BinaryLinkEnvironment.OutputDirectory = OutputFilePaths[0].Directory;

            // Setup link output type
            BinaryLinkEnvironment.bIsBuildingDLL     = IsBuildingDll(Type);
            BinaryLinkEnvironment.bIsBuildingLibrary = IsBuildingLibrary(Type);

            // If we don't have any resource file, use the default or compile a custom one for this module
            if (BinaryLinkEnvironment.Platform.IsInGroup(UnrealPlatformGroup.Windows))
            {
                // Figure out if this binary has any custom resource files. Hacky check to ignore the resource file in the Launch module, since it contains dialogs that the engine needs and always needs to be included.
                FileItem[] CustomResourceFiles = BinaryLinkEnvironment.InputFiles.Where(x => x.Location.HasExtension(".res") && !x.Location.FullName.EndsWith("\\Launch\\PCLaunch.rc.res", StringComparison.OrdinalIgnoreCase)).ToArray();
                if (CustomResourceFiles.Length == 0)
                {
                    if (BinaryLinkEnvironment.DefaultResourceFiles.Count > 0)
                    {
                        // Use the default resource file if possible
                        BinaryLinkEnvironment.InputFiles.AddRange(BinaryLinkEnvironment.DefaultResourceFiles);
                    }
                    else
                    {
                        // Get the intermediate directory
                        DirectoryReference ResourceIntermediateDirectory = BinaryLinkEnvironment.IntermediateDirectory;

                        // Create a compile environment for resource files
                        CppCompileEnvironment ResourceCompileEnvironment = new CppCompileEnvironment(BinaryCompileEnvironment);

                        // @todo: This should be in some Windows code somewhere...
                        // Set the original file name macro; used in Default.rc2 to set the binary metadata fields.
                        ResourceCompileEnvironment.Definitions.Add("ORIGINAL_FILE_NAME=\"" + OutputFilePaths[0].GetFileName() + "\"");

                        // Set the other version fields
                        ResourceCompileEnvironment.Definitions.Add(String.Format("BUILT_FROM_CHANGELIST={0}", Target.Version.Changelist));
                        ResourceCompileEnvironment.Definitions.Add(String.Format("BUILD_VERSION={0}", Target.BuildVersion));

                        // Otherwise compile the default resource file per-binary, so that it gets the correct ORIGINAL_FILE_NAME macro.
                        FileItem  DefaultResourceFile   = FileItem.GetItemByFileReference(FileReference.Combine(UnrealBuildTool.EngineDirectory, "Build", "Windows", "Resources", "Default.rc2"));
                        CPPOutput DefaultResourceOutput = ToolChain.CompileRCFiles(ResourceCompileEnvironment, new List <FileItem> {
                            DefaultResourceFile
                        }, ResourceIntermediateDirectory, Graph);
                        BinaryLinkEnvironment.InputFiles.AddRange(DefaultResourceOutput.ObjectFiles);
                    }
                }
            }

            // Add all the common resource files
            BinaryLinkEnvironment.InputFiles.AddRange(BinaryLinkEnvironment.CommonResourceFiles);

            return(BinaryLinkEnvironment);
        }
Exemple #28
0
 /// <summary>
 /// Returns the in-tree root for the Linux Toolchain for this host platform.
 /// </summary>
 private static DirectoryReference GetInTreeSDKRoot()
 {
     return(DirectoryReference.Combine(UnrealBuildTool.RootDirectory, "Engine/Extras/ThirdPartyNotUE/SDKs", "Host" + BuildHostPlatform.Current.Platform, TargetPlatformName));
 }
Exemple #29
0
        public virtual bool HasSpecificDefaultBuildConfig(UnrealTargetPlatform Platform, DirectoryReference ProjectPath)
        {
            string[] BoolKeys = new string[] {
                "bBuildForArmV7", "bBuildForArm64", "bBuildForX86", "bBuildForX8664",
                "bBuildForES31", "bBuildWithHiddenSymbolVisibility", "bUseNEONForArmV7", "bSaveSymbols"
            };
            string[] StringKeys = new string[] {
                "NDKAPILevelOverride"
            };

            // look up Android specific settings
            if (!DoProjectSettingsMatchDefault(Platform, ProjectPath, "/Script/AndroidRuntimeSettings.AndroidRuntimeSettings",
                                               BoolKeys, null, StringKeys))
            {
                return(false);
            }
            return(true);
        }
	private static UnrealBuildTool.DirectoryReference GetProjectDirectory(PhysXTargetLib TargetLib, TargetPlatformData TargetData, WindowsCompiler TargetWindowsCompiler = WindowsCompiler.VisualStudio2015)
	{
		UnrealBuildTool.DirectoryReference Directory = new UnrealBuildTool.DirectoryReference(GetTargetLibRootDirectory(TargetLib).ToString());

		switch(TargetLib)
		{
			case PhysXTargetLib.PhysX:
				Directory = UnrealBuildTool.DirectoryReference.Combine(Directory, "Source");
				break;
			case PhysXTargetLib.APEX:
				// APEX has its 'compiler' directory in a different location off the root of APEX
				break;
		}

		return UnrealBuildTool.DirectoryReference.Combine(Directory, "compiler", GetCMakeTargetDirectoryName(TargetData, TargetWindowsCompiler));
	}
Exemple #31
0
        /// <summary>
        /// Returns a list of INI filenames for the given project
        /// </summary>
        public static IEnumerable <FileReference> EnumerateConfigFileLocations(ConfigHierarchyType Type, DirectoryReference ProjectDir, UnrealTargetPlatform Platform)
        {
            string BaseIniName  = Enum.GetName(typeof(ConfigHierarchyType), Type);
            string PlatformName = GetIniPlatformName(Platform);

            // cache some platform extension information that can be used inside the loops
            string PlatformExtensionEngineConfigDir  = DirectoryReference.Combine(UnrealBuildTool.PlatformExtensionsDirectory, Platform.ToString(), "Engine").FullName;
            string PlatformExtensionProjectConfigDir = ProjectDir != null?DirectoryReference.Combine(UnrealBuildTool.PlatformExtensionsDirectory, Platform.ToString(), ProjectDir.GetDirectoryName()).FullName : null;

            bool bHasPlatformExtensionEngineConfigDir  = Directory.Exists(PlatformExtensionEngineConfigDir);
            bool bHasPlatformExtensionProjectConfigDir = PlatformExtensionProjectConfigDir != null && Directory.Exists(PlatformExtensionProjectConfigDir);


            foreach (ConfigLayer Layer in ConfigLayers)
            {
                bool bHasPlatformTag  = Layer.Path.Contains("{PLATFORM}");
                bool bHasProjectTag   = Layer.Path.Contains("{PROJECT}");
                bool bHasExpansionTag = Layer.Path.Contains("{ED}") || Layer.Path.Contains("{EF}");
                bool bHasUserTag      = Layer.Path.Contains("{USER}");

                // skip platform layers if we are "platform-less", or user layers without a user dir
                if (bHasPlatformTag && Platform == null ||
                    bHasProjectTag && ProjectDir == null ||
                    bHasUserTag && GetUserDir() == null)
                {
                    continue;
                }

                // basic replacements
                string LayerPath;
                // you can only have PROJECT or ENGINE, not both
                if (bHasProjectTag)
                {
                    if (bHasPlatformTag && bHasPlatformExtensionProjectConfigDir)
                    {
                        LayerPath = Layer.ExtProjectPath.Replace("{EXTPROJECT}", PlatformExtensionProjectConfigDir);
                    }
                    else
                    {
                        LayerPath = Layer.Path.Replace("{PROJECT}", ProjectDir.FullName);
                    }
                }
                else
                {
                    if (bHasPlatformTag && bHasPlatformExtensionEngineConfigDir)
                    {
                        LayerPath = Layer.ExtEnginePath.Replace("{EXTENGINE}", PlatformExtensionEngineConfigDir);
                    }
                    else
                    {
                        LayerPath = Layer.Path.Replace("{ENGINE}", UnrealBuildTool.EngineDirectory.FullName);
                    }
                }
                LayerPath = LayerPath.Replace("{TYPE}", BaseIniName);
                LayerPath = LayerPath.Replace("{USERSETTINGS}", Utils.GetUserSettingDirectory().FullName);
                if (bHasUserTag)
                {
                    LayerPath = LayerPath.Replace("{USER}", GetUserDir());
                }


                // handle expansion (and platform - the C++ code will validate that only expansion layers have platforms)
                if (bHasExpansionTag)
                {
                    foreach (ConfigLayerExpansion Expansion in ConfigLayerExpansions)
                    {
                        // expansion replacements
                        string ExpansionPath = LayerPath.Replace("{ED}", Expansion.DirectoryPrefix);
                        ExpansionPath = ExpansionPath.Replace("{EF}", Expansion.FilePrefix);

                        // now go up the ini parent chain
                        if (bHasPlatformTag)
                        {
                            DataDrivenPlatformInfo.ConfigDataDrivenPlatformInfo Info = DataDrivenPlatformInfo.GetDataDrivenInfoForPlatform(PlatformName);
                            if (Info != null && Info.IniParentChain != null)
                            {
                                // the IniParentChain
                                foreach (string ParentPlatform in Info.IniParentChain)
                                {
                                    yield return(new FileReference(ExpansionPath.Replace("{PLATFORM}", ParentPlatform)));
                                }
                            }
                            // always yield the active platform last
                            yield return(new FileReference(ExpansionPath.Replace("{PLATFORM}", PlatformName)));
                        }
                        else
                        {
                            yield return(new FileReference(ExpansionPath));
                        }
                    }
                }
                else
                {
                    yield return(new FileReference(LayerPath));
                }
            }

            // Find all the generated config files
            foreach (FileReference GeneratedConfigFile in EnumerateGeneratedConfigFileLocations(Type, ProjectDir, Platform))
            {
                yield return(GeneratedConfigFile);
            }
        }