コード例 #1
0
        /// <summary>
        /// The main project directory and all found platform extension project directories
        /// </summary>
        public static DirectoryReference[] GetAllProjectDirectories(FileReference ProjectFile, string Suffix = "")
        {
            // project name may not match the directory name, so use the ProjectFile's name as ProjectName
            string ProjectName = ProjectFile.GetFileNameWithoutAnyExtensions();

            List <DirectoryReference> ProjectDirectories = new List <DirectoryReference>()
            {
                DirectoryReference.Combine(ProjectFile.Directory, Suffix)
            };

            if (DirectoryReference.Exists(PlatformExtensionsDirectory))
            {
                foreach (DirectoryReference PlatformDirectory in DirectoryReference.EnumerateDirectories(PlatformExtensionsDirectory))
                {
                    DirectoryReference PlatformEngineDirectory = DirectoryReference.Combine(PlatformDirectory, ProjectName, Suffix);
                    if (DirectoryReference.Exists(PlatformEngineDirectory))
                    {
                        ProjectDirectories.Add(PlatformEngineDirectory);
                    }
                }
            }
            return(ProjectDirectories.ToArray());
        }
コード例 #2
0
ファイル: UEBuildIOS.cs プロジェクト: eriser/epicgames
        protected IOSProvisioningData(IOSProjectSettings ProjectSettings, bool bIsTVOS, bool bForDistribtion)
        {
            SigningCertificate = ProjectSettings.SigningCertificate;
            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) || // 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
            {
                SigningCertificate = "";
                MobileProvision    = "";
                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);
                Log.TraceLog("Provision found for " + ((ProjectFile != null) ? ProjectFile.GetFileNameWithoutAnyExtensions() : "UE4Game") + ", Provision: " + MobileProvision + " Certificate: " + SigningCertificate);
            }
            // add to the dictionary
            SigningCertificate = SigningCertificate.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/")) + 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;
                        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);
                    }
                }
            }
            else
            {
                Log.TraceLog("No matching provision file was discovered. Please ensure you have a compatible provision installed.");
            }
        }
コード例 #3
0
ファイル: UEBuildIOS.cs プロジェクト: eriser/epicgames
 /// <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("_", "");
 }
コード例 #4
0
        private static Assembly CompileAssembly(FileReference OutputAssemblyPath, List <FileReference> SourceFileNames, List <string> ReferencedAssembies, List <string> PreprocessorDefines = null, bool TreatWarningsAsErrors = false)
        {
            CSharpParseOptions ParseOptions = new CSharpParseOptions(
                languageVersion: LanguageVersion.Latest,
                kind: SourceCodeKind.Regular,
                preprocessorSymbols: PreprocessorDefines
                );

            List <SyntaxTree> SyntaxTrees = new List <SyntaxTree>();

            foreach (FileReference SourceFileName in SourceFileNames)
            {
                SourceText Source = SourceText.From(File.ReadAllText(SourceFileName.FullName));
                SyntaxTree Tree   = CSharpSyntaxTree.ParseText(Source, ParseOptions, SourceFileName.FullName);

                IEnumerable <Diagnostic> Diagnostics = Tree.GetDiagnostics();
                if (Diagnostics.Count() > 0)
                {
                    Log.TraceWarning($"Errors generated while parsing '{SourceFileName.FullName}'");
                    LogDiagnostics(Tree.GetDiagnostics());
                    return(null);
                }

                SyntaxTrees.Add(Tree);
            }

            // Create the output directory if it doesn't exist already
            DirectoryInfo DirInfo = new DirectoryInfo(OutputAssemblyPath.Directory.FullName);

            if (!DirInfo.Exists)
            {
                try
                {
                    DirInfo.Create();
                }
                catch (Exception Ex)
                {
                    throw new BuildException(Ex, "Unable to create directory '{0}' for intermediate assemblies (Exception: {1})", OutputAssemblyPath, Ex.Message);
                }
            }

            List <MetadataReference> MetadataReferences = new List <MetadataReference>();

            if (ReferencedAssembies != null)
            {
                foreach (string Reference in ReferencedAssembies)
                {
                    MetadataReferences.Add(MetadataReference.CreateFromFile(Reference));
                }
            }

            MetadataReferences.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Collections").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.IO").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.IO.FileSystem").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Console").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("System.Runtime.Extensions").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(Assembly.Load("Microsoft.Win32.Registry").Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(typeof(UnrealBuildTool).Assembly.Location));
            MetadataReferences.Add(MetadataReference.CreateFromFile(typeof(FileReference).Assembly.Location));

            CSharpCompilationOptions CompilationOptions = new CSharpCompilationOptions(
                outputKind: OutputKind.DynamicallyLinkedLibrary,
                optimizationLevel: OptimizationLevel.Release,
                warningLevel: 4,
                assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default,
                reportSuppressedDiagnostics: true
                );

            CSharpCompilation Compilation = CSharpCompilation.Create(
                assemblyName: OutputAssemblyPath.GetFileNameWithoutAnyExtensions(),
                syntaxTrees: SyntaxTrees,
                references: MetadataReferences,
                options: CompilationOptions
                );

            using (FileStream AssemblyStream = FileReference.Open(OutputAssemblyPath, FileMode.Create))
            {
                EmitOptions EmitOptions = new EmitOptions(
                    includePrivateMembers: true
                    );

                EmitResult Result = Compilation.Emit(
                    peStream: AssemblyStream,
                    options: EmitOptions);

                if (!Result.Success)
                {
                    LogDiagnostics(Result.Diagnostics);
                    return(null);
                }
            }

            return(Assembly.LoadFile(OutputAssemblyPath.FullName));
        }
コード例 #5
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.");
                }
            }
        }
コード例 #6
0
        protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
        {
            bool bSuccess = true;

            string SolutionFileName = MasterProjectName + ".sln";

            // Setup solution file content
            StringBuilder VCSolutionFileContent = new StringBuilder();

            // Solution file header
            if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2017)
            {
                VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00");
                VCSolutionFileContent.AppendLine("# Visual Studio 15");
                VCSolutionFileContent.AppendLine("VisualStudioVersion = 15.0.25807.0");
                VCSolutionFileContent.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1");
            }
            else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2015)
            {
                VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00");
                VCSolutionFileContent.AppendLine("# Visual Studio 14");
                VCSolutionFileContent.AppendLine("VisualStudioVersion = 14.0.22310.1");
                VCSolutionFileContent.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1");
            }
            else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2013)
            {
                VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00");
                VCSolutionFileContent.AppendLine("# Visual Studio 2013");
            }
            else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2012)
            {
                VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00");
                VCSolutionFileContent.AppendLine("# Visual Studio 2012");
            }
            else
            {
                throw new BuildException("Unexpected ProjectFileFormat");
            }

            // Find the projects for ShaderCompileWorker and UnrealLightmass
            ProjectFile ShaderCompileWorkerProject = null;
            ProjectFile UnrealLightmassProject     = null;

            foreach (ProjectFile Project in AllProjectFiles)
            {
                if (Project.ProjectTargets.Count == 1)
                {
                    FileReference TargetFilePath = Project.ProjectTargets[0].TargetFilePath;
                    if (TargetFilePath != null)
                    {
                        string TargetFileName = TargetFilePath.GetFileNameWithoutAnyExtensions();
                        if (TargetFileName.Equals("ShaderCompileWorker", StringComparison.InvariantCultureIgnoreCase))
                        {
                            ShaderCompileWorkerProject = Project;
                        }
                        else if (TargetFileName.Equals("UnrealLightmass", StringComparison.InvariantCultureIgnoreCase))
                        {
                            UnrealLightmassProject = Project;
                        }
                    }
                    if (ShaderCompileWorkerProject != null &&
                        UnrealLightmassProject != null)
                    {
                        break;
                    }
                }
            }

            // Solution folders, files and project entries
            {
                // This the GUID that Visual Studio uses to identify a solution folder
                string SolutionFolderEntryGUID = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}";

                // Solution folders
                {
                    List <MasterProjectFolder> AllSolutionFolders = new List <MasterProjectFolder>();
                    System.Action <List <MasterProjectFolder> /* Folders */> GatherFoldersFunction = null;
                    GatherFoldersFunction = FolderList =>
                    {
                        AllSolutionFolders.AddRange(FolderList);
                        foreach (MasterProjectFolder CurSubFolder in FolderList)
                        {
                            GatherFoldersFunction(CurSubFolder.SubFolders);
                        }
                    };
                    GatherFoldersFunction(RootFolder.SubFolders);

                    foreach (VisualStudioSolutionFolder CurFolder in AllSolutionFolders)
                    {
                        string FolderGUIDString = CurFolder.FolderGUID.ToString("B").ToUpperInvariant();
                        VCSolutionFileContent.AppendLine("Project(\"" + SolutionFolderEntryGUID + "\") = \"" + CurFolder.FolderName + "\", \"" + CurFolder.FolderName + "\", \"" + FolderGUIDString + "\"");

                        // Add any files that are inlined right inside the solution folder
                        if (CurFolder.Files.Count > 0)
                        {
                            VCSolutionFileContent.AppendLine("	ProjectSection(SolutionItems) = preProject");
                            foreach (string CurFile in CurFolder.Files)
                            {
                                // Syntax is:  <relative file path> = <relative file path>
                                VCSolutionFileContent.AppendLine("		"+ CurFile + " = " + CurFile);
                            }
                            VCSolutionFileContent.AppendLine("	EndProjectSection");
                        }

                        VCSolutionFileContent.AppendLine("EndProject");
                    }
                }


                // Project files
                foreach (MSBuildProjectFile CurProject in AllProjectFiles)
                {
                    // Visual Studio uses different GUID types depending on the project type
                    string ProjectTypeGUID = CurProject.ProjectTypeGUID;

                    // NOTE: The project name in the solution doesn't actually *have* to match the project file name on disk.  However,
                    //       we prefer it when it does match so we use the actual file name here.
                    string ProjectNameInSolution = CurProject.ProjectFilePath.GetFileNameWithoutExtension();

                    // Use the existing project's GUID that's already known to us
                    string ProjectGUID = CurProject.ProjectGUID.ToString("B").ToUpperInvariant();

                    VCSolutionFileContent.AppendLine("Project(\"" + ProjectTypeGUID + "\") = \"" + ProjectNameInSolution + "\", \"" + CurProject.ProjectFilePath.MakeRelativeTo(ProjectFileGenerator.MasterProjectPath) + "\", \"" + ProjectGUID + "\"");

                    // Setup dependency on UnrealBuildTool, if we need that.  This makes sure that UnrealBuildTool is
                    // freshly compiled before kicking off any build operations on this target project
                    if (!CurProject.IsStubProject)
                    {
                        List <ProjectFile> Dependencies = new List <ProjectFile>();
                        if (CurProject.IsGeneratedProject && UBTProject != null && CurProject != UBTProject)
                        {
                            Dependencies.Add(UBTProject);
                            Dependencies.AddRange(UBTProject.DependsOnProjects);
                        }
                        if (bEditorDependsOnShaderCompileWorker && !bUsePrecompiled && CurProject.IsGeneratedProject && ShaderCompileWorkerProject != null && CurProject.ProjectTargets.Any(x => x.TargetRules != null && x.TargetRules.Type == TargetType.Editor))
                        {
                            Dependencies.Add(ShaderCompileWorkerProject);
                        }
                        Dependencies.AddRange(CurProject.DependsOnProjects);

                        if (Dependencies.Count > 0)
                        {
                            VCSolutionFileContent.AppendLine("\tProjectSection(ProjectDependencies) = postProject");

                            // Setup any addition dependencies this project has...
                            foreach (ProjectFile DependsOnProject in Dependencies)
                            {
                                string DependsOnProjectGUID = ((MSBuildProjectFile)DependsOnProject).ProjectGUID.ToString("B").ToUpperInvariant();
                                VCSolutionFileContent.AppendLine("\t\t" + DependsOnProjectGUID + " = " + DependsOnProjectGUID);
                            }

                            VCSolutionFileContent.AppendLine("\tEndProjectSection");
                        }
                    }

                    VCSolutionFileContent.AppendLine("EndProject");
                }

                // Add the visualizers at the solution level. Doesn't seem to be picked up from a makefile project in VS2017 15.8.5.
                VCSolutionFileContent.AppendLine(String.Format("Project(\"{{2150E333-8FDC-42A3-9474-1A3956D46DE8}}\") = \"Visualizers\", \"Visualizers\", \"{0}\"", Guid.NewGuid().ToString()));
                VCSolutionFileContent.AppendLine("\tProjectSection(SolutionItems) = preProject");
                VCSolutionFileContent.AppendLine("\t\tEngine\\Extras\\VisualStudioDebugging\\UE4.natvis = Engine\\Extras\\VisualStudioDebugging\\UE4.natvis");
                VCSolutionFileContent.AppendLine("\tEndProjectSection");
                VCSolutionFileContent.AppendLine("EndProject");
            }

            // Solution configuration platforms.  This is just a list of all of the platforms and configurations that
            // appear in Visual Studio's build configuration selector.
            List <VCSolutionConfigCombination> SolutionConfigCombinations = new List <VCSolutionConfigCombination>();

            // The "Global" section has source control, solution configurations, project configurations,
            // preferences, and project hierarchy data
            {
                VCSolutionFileContent.AppendLine("Global");
                {
                    {
                        VCSolutionFileContent.AppendLine("	GlobalSection(SolutionConfigurationPlatforms) = preSolution");

                        Dictionary <string, Tuple <UnrealTargetConfiguration, TargetType> > SolutionConfigurationsValidForProjects = new Dictionary <string, Tuple <UnrealTargetConfiguration, TargetType> >();
                        HashSet <UnrealTargetPlatform> PlatformsValidForProjects = new HashSet <UnrealTargetPlatform>();

                        foreach (UnrealTargetConfiguration CurConfiguration in SupportedConfigurations)
                        {
                            if (InstalledPlatformInfo.IsValidConfiguration(CurConfiguration, EProjectType.Code))
                            {
                                foreach (UnrealTargetPlatform CurPlatform in SupportedPlatforms)
                                {
                                    if (InstalledPlatformInfo.IsValidPlatform(CurPlatform, EProjectType.Code))
                                    {
                                        foreach (ProjectFile CurProject in AllProjectFiles)
                                        {
                                            if (!CurProject.IsStubProject)
                                            {
                                                if (CurProject.ProjectTargets.Count == 0)
                                                {
                                                    throw new BuildException("Expecting project '" + CurProject.ProjectFilePath + "' to have at least one ProjectTarget associated with it!");
                                                }

                                                // Figure out the set of valid target configuration names
                                                foreach (ProjectTarget ProjectTarget in CurProject.ProjectTargets)
                                                {
                                                    if (VCProjectFile.IsValidProjectPlatformAndConfiguration(ProjectTarget, CurPlatform, CurConfiguration))
                                                    {
                                                        PlatformsValidForProjects.Add(CurPlatform);

                                                        // Default to a target configuration name of "Game", since that will collapse down to an empty string
                                                        TargetType TargetType = TargetType.Game;
                                                        if (ProjectTarget.TargetRules != null)
                                                        {
                                                            TargetType = ProjectTarget.TargetRules.Type;
                                                        }

                                                        string SolutionConfigName = MakeSolutionConfigurationName(CurConfiguration, TargetType);
                                                        SolutionConfigurationsValidForProjects[SolutionConfigName] = new Tuple <UnrealTargetConfiguration, TargetType>(CurConfiguration, TargetType);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach (UnrealTargetPlatform CurPlatform in PlatformsValidForProjects)
                        {
                            foreach (KeyValuePair <string, Tuple <UnrealTargetConfiguration, TargetType> > SolutionConfigKeyValue in SolutionConfigurationsValidForProjects)
                            {
                                // e.g.  "Development|Win64 = Development|Win64"
                                string SolutionConfigName = SolutionConfigKeyValue.Key;
                                UnrealTargetConfiguration Configuration = SolutionConfigKeyValue.Value.Item1;
                                TargetType TargetType = SolutionConfigKeyValue.Value.Item2;

                                string SolutionPlatformName = CurPlatform.ToString();

                                string SolutionConfigAndPlatformPair = SolutionConfigName + "|" + SolutionPlatformName;
                                SolutionConfigCombinations.Add(
                                    new VCSolutionConfigCombination
                                {
                                    VCSolutionConfigAndPlatformName = SolutionConfigAndPlatformPair,
                                    Configuration           = Configuration,
                                    Platform                = CurPlatform,
                                    TargetConfigurationName = TargetType
                                }
                                    );
                            }
                        }

                        // Sort the list of solution platform strings alphabetically (Visual Studio prefers it)
                        SolutionConfigCombinations.Sort(
                            new Comparison <VCSolutionConfigCombination>(
                                (x, y) => { return(String.Compare(x.VCSolutionConfigAndPlatformName, y.VCSolutionConfigAndPlatformName, StringComparison.InvariantCultureIgnoreCase)); }
                                )
                            );

                        HashSet <string> AppendedSolutionConfigAndPlatformNames = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase);
                        foreach (VCSolutionConfigCombination SolutionConfigCombination in SolutionConfigCombinations)
                        {
                            // We alias "Game" and "Program" to both have the same solution configuration, so we're careful not to add the same combination twice.
                            if (!AppendedSolutionConfigAndPlatformNames.Contains(SolutionConfigCombination.VCSolutionConfigAndPlatformName))
                            {
                                VCSolutionFileContent.AppendLine("		"+ SolutionConfigCombination.VCSolutionConfigAndPlatformName + " = " + SolutionConfigCombination.VCSolutionConfigAndPlatformName);
                                AppendedSolutionConfigAndPlatformNames.Add(SolutionConfigCombination.VCSolutionConfigAndPlatformName);
                            }
                        }

                        VCSolutionFileContent.AppendLine("	EndGlobalSection");
                    }


                    // Assign each project's "project configuration" to our "solution platform + configuration" pairs.  This
                    // also sets up which projects are actually built when building the solution.
                    {
                        VCSolutionFileContent.AppendLine("	GlobalSection(ProjectConfigurationPlatforms) = postSolution");

                        foreach (MSBuildProjectFile CurProject in AllProjectFiles)
                        {
                            // NOTE: We don't emit solution configuration entries for "stub" projects.  Those projects are only
                            // built using UnrealBuildTool and don't require a presence in the solution project list

                            // NOTE: We also process projects that were "imported" here, hoping to match those to our solution
                            //       configurations.  In some cases this may not be successful though.  Imported projects
                            //       should always be carefully setup to match our project generator's solution configs.
                            if (!CurProject.IsStubProject)
                            {
                                if (CurProject.ProjectTargets.Count == 0)
                                {
                                    throw new BuildException("Expecting project '" + CurProject.ProjectFilePath + "' to have at least one ProjectTarget associated with it!");
                                }

                                foreach (VCSolutionConfigCombination SolutionConfigCombination in SolutionConfigCombinations)
                                {
                                    // Get the context for the current solution context
                                    MSBuildProjectContext ProjectContext = CurProject.GetMatchingProjectContext(SolutionConfigCombination.TargetConfigurationName, SolutionConfigCombination.Configuration, SolutionConfigCombination.Platform);

                                    // Write the solution mapping (e.g.  "{4232C52C-680F-4850-8855-DC39419B5E9B}.Debug|iOS.ActiveCfg = iOS_Debug|Win32")
                                    string CurProjectGUID = CurProject.ProjectGUID.ToString("B").ToUpperInvariant();
                                    VCSolutionFileContent.AppendLine("		{0}.{1}.ActiveCfg = {2}", CurProjectGUID, SolutionConfigCombination.VCSolutionConfigAndPlatformName, ProjectContext.Name);
                                    if (ProjectContext.bBuildByDefault)
                                    {
                                        VCSolutionFileContent.AppendLine("		{0}.{1}.Build.0 = {2}", CurProjectGUID, SolutionConfigCombination.VCSolutionConfigAndPlatformName, ProjectContext.Name);
                                        if (ProjectContext.bDeployByDefault)
                                        {
                                            VCSolutionFileContent.AppendLine("		{0}.{1}.Deploy.0 = {2}", CurProjectGUID, SolutionConfigCombination.VCSolutionConfigAndPlatformName, ProjectContext.Name);
                                        }
                                    }
                                }
                            }
                        }

                        VCSolutionFileContent.AppendLine("	EndGlobalSection");
                    }


                    // Setup other solution properties
                    {
                        // HideSolutionNode sets whether or not the top-level solution entry is completely hidden in the UI.
                        // We don't want that, as we need users to be able to right click on the solution tree item.
                        VCSolutionFileContent.AppendLine("	GlobalSection(SolutionProperties) = preSolution");
                        VCSolutionFileContent.AppendLine("		HideSolutionNode = FALSE");
                        VCSolutionFileContent.AppendLine("	EndGlobalSection");
                    }



                    // Solution directory hierarchy
                    {
                        VCSolutionFileContent.AppendLine("	GlobalSection(NestedProjects) = preSolution");

                        // Every entry in this section is in the format "Guid1 = Guid2".  Guid1 is the child project (or solution
                        // filter)'s GUID, and Guid2 is the solution filter directory to parent the child project (or solution
                        // filter) to.  This sets up the hierarchical solution explorer tree for all solution folders and projects.

                        System.Action <StringBuilder /* VCSolutionFileContent */, List <MasterProjectFolder> /* Folders */> FolderProcessorFunction = null;
                        FolderProcessorFunction = (LocalVCSolutionFileContent, LocalMasterProjectFolders) =>
                        {
                            foreach (VisualStudioSolutionFolder CurFolder in LocalMasterProjectFolders)
                            {
                                string CurFolderGUIDString = CurFolder.FolderGUID.ToString("B").ToUpperInvariant();

                                foreach (MSBuildProjectFile ChildProject in CurFolder.ChildProjects)
                                {
                                    //	e.g. "{BF6FB09F-A2A6-468F-BE6F-DEBE07EAD3EA} = {C43B6BB5-3EF0-4784-B896-4099753BCDA9}"
                                    LocalVCSolutionFileContent.AppendLine("		"+ ChildProject.ProjectGUID.ToString("B").ToUpperInvariant() + " = " + CurFolderGUIDString);
                                }

                                foreach (VisualStudioSolutionFolder SubFolder in CurFolder.SubFolders)
                                {
                                    //	e.g. "{BF6FB09F-A2A6-468F-BE6F-DEBE07EAD3EA} = {C43B6BB5-3EF0-4784-B896-4099753BCDA9}"
                                    LocalVCSolutionFileContent.AppendLine("		"+ SubFolder.FolderGUID.ToString("B").ToUpperInvariant() + " = " + CurFolderGUIDString);
                                }

                                // Recurse into subfolders
                                FolderProcessorFunction(LocalVCSolutionFileContent, CurFolder.SubFolders);
                            }
                        };
                        FolderProcessorFunction(VCSolutionFileContent, RootFolder.SubFolders);

                        VCSolutionFileContent.AppendLine("	EndGlobalSection");
                    }
                }

                VCSolutionFileContent.AppendLine("EndGlobal");
            }


            // Save the solution file
            if (bSuccess)
            {
                string SolutionFilePath = FileReference.Combine(MasterProjectPath, SolutionFileName).FullName;
                bSuccess = WriteFileIfChanged(SolutionFilePath, VCSolutionFileContent.ToString());
            }


            // Save a solution config file which selects the development editor configuration by default.
            if (bSuccess && bWriteSolutionOptionFile)
            {
                // Figure out the filename for the SUO file. VS will automatically import the options from earlier versions if necessary.
                FileReference SolutionOptionsFileName;
                switch (ProjectFileFormat)
                {
                case VCProjectFileFormat.VisualStudio2012:
                    SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, Path.ChangeExtension(SolutionFileName, "v11.suo"));
                    break;

                case VCProjectFileFormat.VisualStudio2013:
                    SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, Path.ChangeExtension(SolutionFileName, "v12.suo"));
                    break;

                case VCProjectFileFormat.VisualStudio2015:
                    SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, ".vs", Path.GetFileNameWithoutExtension(SolutionFileName), "v14", ".suo");
                    break;

                case VCProjectFileFormat.VisualStudio2017:
                    SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, ".vs", Path.GetFileNameWithoutExtension(SolutionFileName), "v15", ".suo");
                    break;

                default:
                    throw new BuildException("Unsupported Visual Studio version");
                }

                // Check it doesn't exist before overwriting it. Since these files store the user's preferences, it'd be bad form to overwrite them.
                if (!FileReference.Exists(SolutionOptionsFileName))
                {
                    DirectoryReference.CreateDirectory(SolutionOptionsFileName.Directory);

                    VCSolutionOptions Options = new VCSolutionOptions(ProjectFileFormat);

                    // Set the default configuration and startup project
                    VCSolutionConfigCombination DefaultConfig = SolutionConfigCombinations.Find(x => x.Configuration == UnrealTargetConfiguration.Development && x.Platform == UnrealTargetPlatform.Win64 && x.TargetConfigurationName == TargetType.Editor);
                    if (DefaultConfig != null)
                    {
                        List <VCBinarySetting> Settings = new List <VCBinarySetting>();
                        Settings.Add(new VCBinarySetting("ActiveCfg", DefaultConfig.VCSolutionConfigAndPlatformName));
                        if (DefaultProject != null)
                        {
                            Settings.Add(new VCBinarySetting("StartupProject", ((MSBuildProjectFile)DefaultProject).ProjectGUID.ToString("B")));
                        }
                        Options.SetConfiguration(Settings);
                    }

                    // Mark all the projects as closed by default, apart from the startup project
                    VCSolutionExplorerState ExplorerState = new VCSolutionExplorerState();
                    if (ProjectFileFormat >= VCProjectFileFormat.VisualStudio2017)
                    {
                        BuildSolutionExplorerState_VS2017(RootFolder, "", ExplorerState, DefaultProject);
                    }
                    else
                    {
                        BuildSolutionExplorerState_VS2015(AllProjectFiles, ExplorerState, DefaultProject, IncludeEnginePrograms);
                    }
                    Options.SetExplorerState(ExplorerState);

                    // Write the file
                    if (Options.Sections.Count > 0)
                    {
                        Options.Write(SolutionOptionsFileName.FullName);
                    }
                }
            }

            return(bSuccess);
        }
コード例 #7
0
        /// <summary>
        ///  Attempt to merge a child plugin up into a parent plugin (via file naming scheme). Very little merging happens
        ///  but it does allow for platform extensions to extend a plugin with module files
        /// </summary>
        /// <param name="Child">Child plugin that needs to merge to a main, parent plugin</param>
        /// <param name="Filename">Child plugin's filename, used to determine the parent's name</param>
        private static void TryMergeWithParent(PluginInfo Child, FileReference Filename)
        {
            // find the parent
            PluginInfo Parent = null;

            string[] Tokens = Filename.GetFileNameWithoutAnyExtensions().Split("_".ToCharArray());
            if (Tokens.Length == 2)
            {
                string ParentPluginName = Tokens[0];
                foreach (KeyValuePair <DirectoryReference, List <PluginInfo> > Pair in PluginInfoCache)
                {
                    Parent = Pair.Value.FirstOrDefault(x => x.Name.Equals(ParentPluginName, StringComparison.InvariantCultureIgnoreCase));
                    if (Parent != null)
                    {
                        break;
                    }
                }
            }

            // did we find a parent plugin?
            if (Parent == null)
            {
                throw new BuildException("Child plugin {0} was not named properly. It should be in the form <ParentPlugin>_<Platform>.uplugin", Filename);
            }

            // validate child plugin file name
            string PlatformName = Tokens[1];

            if (!IsValidChildPluginSuffix(PlatformName))
            {
                Log.TraceWarning("Ignoring child plugin: {0} - Unknown suffix \"{1}\". Expected valid platform or group", Child.File.GetFileName(), PlatformName);
                return;
            }

            // add our uplugin file to the existing plugin to be used to search for modules later
            Parent.ChildFiles.Add(Child.File);

            // merge the supported platforms
            Parent.Descriptor.MergeSupportedTargetPlatforms(Child.Descriptor.SupportedTargetPlatforms);

            // make sure we are whitelisted for any modules we list, if the parent had a whitelist
            if (Child.Descriptor.Modules != null)
            {
                // this should cause an error if it's invalid platform name
                UnrealTargetPlatform Platform = UnrealTargetPlatform.Parse(PlatformName);

                foreach (ModuleDescriptor ChildModule in Child.Descriptor.Modules)
                {
                    ModuleDescriptor ParentModule = Parent.Descriptor.Modules.FirstOrDefault(x => x.Name.Equals(ChildModule.Name) && x.Type == ChildModule.Type);
                    if (ParentModule != null)
                    {
                        // merge white/blacklists (if the parent had a list, and child didn't specify a list, just add the child platform to the parent list - for white and black!)
                        if (ParentModule.WhitelistPlatforms != null && ParentModule.WhitelistPlatforms.Length > 0)
                        {
                            List <UnrealTargetPlatform> Whitelist = ParentModule.WhitelistPlatforms.ToList();
                            if (ChildModule.WhitelistPlatforms != null && ChildModule.WhitelistPlatforms.Length > 0)
                            {
                                Whitelist.AddRange(ChildModule.WhitelistPlatforms);
                            }
                            else
                            {
                                Whitelist.Add(Platform);
                            }
                            ParentModule.WhitelistPlatforms = Whitelist.ToArray();
                        }
                        if (ParentModule.BlacklistPlatforms != null && ParentModule.BlacklistPlatforms.Length > 0)
                        {
                            if (ChildModule.BlacklistPlatforms != null && ChildModule.BlacklistPlatforms.Length > 0)
                            {
                                List <UnrealTargetPlatform> Blacklist = ParentModule.BlacklistPlatforms.ToList();
                                Blacklist.AddRange(ChildModule.BlacklistPlatforms);
                                ParentModule.BlacklistPlatforms = Blacklist.ToArray();
                            }
                        }
                    }
                }
            }
            // @todo platplug: what else do we want to support merging?!?
        }
コード例 #8
0
        private FileReference GetExecutableFilename(ProjectFile Project, ProjectTarget Target, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration)
        {
            TargetRules   TargetRulesObject = Target.TargetRules;
            FileReference TargetFilePath    = Target.TargetFilePath;
            string        TargetName        = TargetFilePath == null?Project.ProjectFilePath.GetFileNameWithoutExtension() : TargetFilePath.GetFileNameWithoutAnyExtensions();

            string UBTPlatformName      = Platform.ToString();
            string UBTConfigurationName = Configuration.ToString();

            string ProjectName = Project.ProjectFilePath.GetFileNameWithoutExtension();

            // Setup output path
            UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform);

            // Figure out if this is a monolithic build
            bool bShouldCompileMonolithic = BuildPlatform.ShouldCompileMonolithicBinary(Platform);

            if (TargetRulesObject != null)
            {
                bShouldCompileMonolithic |= (Target.CreateRulesDelegate(Platform, Configuration).GetLegacyLinkType(Platform, Configuration) == TargetLinkType.Monolithic);
            }

            TargetType TargetRulesType = Target.TargetRules == null ? TargetType.Program : Target.TargetRules.Type;

            // Get the output directory
            DirectoryReference RootDirectory = UnrealBuildTool.EngineDirectory;

            if (TargetRulesType != TargetType.Program && (bShouldCompileMonolithic || TargetRulesObject.BuildEnvironment == TargetBuildEnvironment.Unique) && !TargetRulesObject.bOutputToEngineBinaries)
            {
                if (OnlyGameProject != null && TargetFilePath.IsUnderDirectory(OnlyGameProject.Directory))
                {
                    RootDirectory = OnlyGameProject.Directory;
                }
                else
                {
                    FileReference ProjectFileName;
                    if (UProjectInfo.TryGetProjectFileName(ProjectName, out ProjectFileName))
                    {
                        RootDirectory = ProjectFileName.Directory;
                    }
                }
            }

            if (TargetRulesType == TargetType.Program && (TargetRulesObject == null || !TargetRulesObject.bOutputToEngineBinaries))
            {
                FileReference ProjectFileName;
                if (UProjectInfo.TryGetProjectForTarget(TargetName, out ProjectFileName))
                {
                    RootDirectory = ProjectFileName.Directory;
                }
            }

            // Get the output directory
            DirectoryReference OutputDirectory = DirectoryReference.Combine(RootDirectory, "Binaries", UBTPlatformName);

            // Get the executable name (minus any platform or config suffixes)
            string BaseExeName = TargetName;

            if (!bShouldCompileMonolithic && TargetRulesType != TargetType.Program)
            {
                // Figure out what the compiled binary will be called so that we can point the IDE to the correct file
                string TargetConfigurationName = TargetRulesType.ToString();
                if (TargetConfigurationName != TargetType.Game.ToString() && TargetConfigurationName != TargetType.Program.ToString())
                {
                    BaseExeName = "UE4" + TargetConfigurationName;
                }
            }

            // Make the output file path
            string ExecutableFilename = FileReference.Combine(OutputDirectory, BaseExeName).ToString();

            if ((Configuration != UnrealTargetConfiguration.DebugGame || bShouldCompileMonolithic))
            {
                ExecutableFilename += "-" + UBTPlatformName + "-" + UBTConfigurationName;
            }
            ExecutableFilename += TargetRulesObject.Architecture;
            ExecutableFilename += BuildPlatform.GetBinaryExtension(UEBuildBinaryType.Executable);

            return(FileReference.MakeFromNormalizedFullPath(ExecutableFilename));
        }
コード例 #9
0
        /// <summary>
        ///  Attempt to merge a child plugin up into a parent plugin (via file naming scheme). Very little merging happens
        ///  but it does allow for platform extensions to extend a plugin with module files
        /// </summary>
        /// <param name="Child">Child plugin that needs to merge to a main, parent plugin</param>
        /// <param name="Filename">Child plugin's filename, used to determine the parent's name</param>
        private static void TryMergeWithParent(PluginInfo Child, FileReference Filename)
        {
            // find the parent
            PluginInfo Parent = null;

            string[] Tokens = Filename.GetFileNameWithoutAnyExtensions().Split("_".ToCharArray());
            if (Tokens.Length == 2)
            {
                string ParentPluginName = Tokens[0];
                foreach (KeyValuePair <DirectoryReference, List <PluginInfo> > Pair in PluginInfoCache)
                {
                    Parent = Pair.Value.FirstOrDefault(x => x.Name.Equals(ParentPluginName, StringComparison.InvariantCultureIgnoreCase));
                    if (Parent != null)
                    {
                        break;
                    }
                }
            }
            else
            {
                throw new BuildException("Platform extension plugin {0} was named improperly. It must be in the form <ParentPlugin>_<Platform>.uplugin", Filename);
            }

            // did we find a parent plugin?
            if (Parent == null)
            {
                throw new BuildException("Unable to find parent plugin {0} for platform extension plugin {1}. Make sure {0}.uplugin exists.", Tokens[0], Filename);
            }

            // validate child plugin file name
            string PlatformName = Tokens[1];

            if (!IsValidChildPluginSuffix(PlatformName))
            {
                Log.TraceWarning("Ignoring child plugin: {0} - Unknown suffix \"{1}\". Expected valid platform or group", Child.File.GetFileName(), PlatformName);
                return;
            }

            // add our uplugin file to the existing plugin to be used to search for modules later
            Parent.ChildFiles.Add(Child.File);

            // this should cause an error if it's invalid platform name
            //UnrealTargetPlatform Platform = UnrealTargetPlatform.Parse(PlatformName);

            // merge the supported platforms
            if (Child.Descriptor.SupportedTargetPlatforms != null)
            {
                if (Parent.Descriptor.SupportedTargetPlatforms == null)
                {
                    Parent.Descriptor.SupportedTargetPlatforms = Child.Descriptor.SupportedTargetPlatforms;
                }
                else
                {
                    Parent.Descriptor.SupportedTargetPlatforms = Parent.Descriptor.SupportedTargetPlatforms.Union(Child.Descriptor.SupportedTargetPlatforms).ToList();
                }
            }

            // make sure we are whitelisted for any modules we list
            if (Child.Descriptor.Modules != null)
            {
                if (Parent.Descriptor.Modules == null)
                {
                    Parent.Descriptor.Modules = Child.Descriptor.Modules;
                }
                else
                {
                    foreach (ModuleDescriptor ChildModule in Child.Descriptor.Modules)
                    {
                        ModuleDescriptor ParentModule = Parent.Descriptor.Modules.FirstOrDefault(x => x.Name.Equals(ChildModule.Name) && x.Type == ChildModule.Type);
                        if (ParentModule != null)
                        {
                            // merge white/blacklists (if the parent had a list, and child didn't specify a list, just add the child platform to the parent list - for white and black!)
                            if (ChildModule.WhitelistPlatforms != null)
                            {
                                if (ParentModule.WhitelistPlatforms == null)
                                {
                                    ParentModule.WhitelistPlatforms = ChildModule.WhitelistPlatforms;
                                }
                                else
                                {
                                    ParentModule.WhitelistPlatforms = ParentModule.WhitelistPlatforms.Union(ChildModule.WhitelistPlatforms).ToList();
                                }
                            }
                            if (ChildModule.BlacklistPlatforms != null)
                            {
                                if (ParentModule.BlacklistPlatforms == null)
                                {
                                    ParentModule.BlacklistPlatforms = ChildModule.BlacklistPlatforms;
                                }
                                else
                                {
                                    ParentModule.BlacklistPlatforms = ParentModule.BlacklistPlatforms.Union(ChildModule.BlacklistPlatforms).ToList();
                                }
                            }
                        }
                        else
                        {
                            Parent.Descriptor.Modules.Add(ChildModule);
                        }
                    }
                }
            }

            // make sure we are whitelisted for any plugins we list
            if (Child.Descriptor.Plugins != null)
            {
                if (Parent.Descriptor.Plugins == null)
                {
                    Parent.Descriptor.Plugins = Child.Descriptor.Plugins;
                }
                else
                {
                    foreach (PluginReferenceDescriptor ChildPluginReference in Child.Descriptor.Plugins)
                    {
                        PluginReferenceDescriptor ParentPluginReference = Parent.Descriptor.Plugins.FirstOrDefault(x => x.Name.Equals(ChildPluginReference.Name));
                        if (ParentPluginReference != null)
                        {
                            // we only need to whitelist the platform if the parent had a whitelist (otherwise, we could mistakenly remove all other platforms)
                            if (ParentPluginReference.WhitelistPlatforms != null)
                            {
                                if (ChildPluginReference.WhitelistPlatforms != null)
                                {
                                    ParentPluginReference.WhitelistPlatforms = ParentPluginReference.WhitelistPlatforms.Union(ChildPluginReference.WhitelistPlatforms).ToList();
                                }
                            }

                            // if we want to blacklist a platform, add it even if the parent didn't have a blacklist. this won't cause problems with other platforms
                            if (ChildPluginReference.BlacklistPlatforms != null)
                            {
                                if (ParentPluginReference.BlacklistPlatforms == null)
                                {
                                    ParentPluginReference.BlacklistPlatforms = ChildPluginReference.BlacklistPlatforms;
                                }
                                else
                                {
                                    ParentPluginReference.BlacklistPlatforms = ParentPluginReference.BlacklistPlatforms.Union(ChildPluginReference.BlacklistPlatforms).ToList();
                                }
                            }
                        }
                        else
                        {
                            Parent.Descriptor.Plugins.Add(ChildPluginReference);
                        }
                    }
                }
            }
            // @todo platplug: what else do we want to support merging?!?
        }