Beispiel #1
0
        /// <summary>
        /// Copy the files always needed (even in a stub IPA)
        /// </summary>
        static public void CopyFilesNeededForMakeApp()
        {
            // Copy Info.plist over (modifiying it as needed)
            string SourcePListFilename = Utilities.GetPrecompileSourcePListFilename();

            Utilities.PListHelper Info = Utilities.PListHelper.CreateFromFile(SourcePListFilename);

            // Edit the plist
            CookTime.UpdateVersion(Info);

            // Write out the <GameName>-Info.plist file to the xcode staging directory
            string TargetPListFilename = Path.Combine(Config.PCXcodeStagingDir, Program.GameName + "-Info.plist");

            Directory.CreateDirectory(Path.GetDirectoryName(TargetPListFilename));
            string OutString = Info.SaveToString();

            OutString = OutString.Replace("${EXECUTABLE_NAME}", Program.GameName);
            OutString = OutString.Replace("${BUNDLE_IDENTIFIER}", Program.GameName.Replace("_", ""));

            // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist
            // eventually we want to generate this based on what the user has set in the project settings
            string[] IPhoneConfigs =
            {
                "Default-IPhone6",               "Landscape", "{375, 667}",
                "Default-IPhone6",               "Portrait",  "{375, 667}",
                "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}",
                "Default-IPhone6Plus-Portrait",  "Portrait",  "{414, 736}",
                "Default",                       "Landscape", "{320, 480}",
                "Default",                       "Portrait",  "{320, 480}",
                "Default-568h",                  "Landscape", "{320, 568}",
                "Default-568h",                  "Portrait",  "{320, 568}",
                "Default-IPhoneX-Landscape",     "Landscape", "{375, 812}",
                "Default-IPhoneX-Portrait",      "Portrait",  "{375, 812}",
            };

            StringBuilder NewLaunchImagesString = new StringBuilder("<key>UILaunchImages~iphone</key>\n\t\t<array>\n");

            for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3)
            {
                NewLaunchImagesString.Append("\t\t\t<dict>\n");
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageMinimumOSVersion</key>\n");
                NewLaunchImagesString.Append("\t\t\t\t<string>8.0</string>\n");
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageName</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 0]);
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageOrientation</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 1]);
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageSize</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 2]);
                NewLaunchImagesString.Append("\t\t\t</dict>\n");
            }

            // close it out
            NewLaunchImagesString.Append("\t\t\t</array>\n\t\t<key>UILaunchImages~ipad</key>");
            OutString = OutString.Replace("<key>UILaunchImages~ipad</key>", NewLaunchImagesString.ToString());

            byte[] RawInfoPList = Encoding.UTF8.GetBytes(OutString);
            File.WriteAllBytes(TargetPListFilename, RawInfoPList);

            Program.Log("Updating .plist: {0} --> {1}", SourcePListFilename, TargetPListFilename);

            // look for an entitlements file (optional)
            string SourceEntitlements = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".entitlements");

            // set where to make the entitlements file (
            string TargetEntitlements = Path.Combine(Config.PCXcodeStagingDir, Program.GameName + ".entitlements");

            if (File.Exists(SourceEntitlements))
            {
                FileOperations.CopyRequiredFile(SourceEntitlements, TargetEntitlements);
            }
            else
            {
                // we need to have something so Xcode will compile, so we just set the get-task-allow, since we know the value,
                // which is based on distribution or not (true means debuggable)
                File.WriteAllText(TargetEntitlements, string.Format("<plist><dict><key>get-task-allow</key><{0}/></dict></plist>",
                                                                    Config.bForDistribution ? "false" : "true"));
            }

            // Copy the mobile provision file over
            string CFBundleIdentifier = null;

            Info.GetString("CFBundleIdentifier", out CFBundleIdentifier);
            bool   bNameMatch;
            string ProvisionWithPrefix = MobileProvision.FindCompatibleProvision(CFBundleIdentifier, out bNameMatch);

            if (!File.Exists(ProvisionWithPrefix))
            {
                ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".mobileprovision");
                if (!File.Exists(ProvisionWithPrefix))
                {
                    ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory + "/NotForLicensees/", Program.GameName + ".mobileprovision");
                    if (!File.Exists(ProvisionWithPrefix))
                    {
                        ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory, "UE4Game.mobileprovision");
                        if (!File.Exists(ProvisionWithPrefix))
                        {
                            ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory + "/NotForLicensees/", "UE4Game.mobileprovision");
                        }
                    }
                }
            }
            string FinalMobileProvisionFilename = Path.Combine(Config.PCXcodeStagingDir, MacMobileProvisionFilename);

            FileOperations.CopyRequiredFile(ProvisionWithPrefix, FinalMobileProvisionFilename);

            // make sure this .mobileprovision file is newer than any other .mobileprovision file on the Mac (this file gets multiple games named the same file,
            // so the time stamp checking can fail when moving between games, a la the buildmachines!)
            File.SetLastWriteTime(FinalMobileProvisionFilename, DateTime.UtcNow);
            string ProjectFile = Config.RootRelativePath + @"Engine\Intermediate\ProjectFiles\UE4.xcodeproj\project.pbxproj";

            if (Program.GameName != "UE4Game")
            {
                ProjectFile = Path.GetDirectoryName(Config.IntermediateDirectory) + @"\ProjectFiles\" + Program.GameName + @".xcodeproj\project.pbxproj";
            }
            FileOperations.CopyRequiredFile(ProjectFile, Path.Combine(Config.PCXcodeStagingDir, @"project.pbxproj.datecheck"));

            // copy the signing certificate over
            // export the signing certificate to a file
            MobileProvision Provision   = MobileProvisionParser.ParseFile(ProvisionWithPrefix);
            var             Certificate = CodeSignatureBuilder.FindCertificate(Provision);

            byte[] Data = Certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs12, "A");
            File.WriteAllBytes(Path.Combine(Config.PCXcodeStagingDir, MacSigningIdentityFilename), Data);
            Config.CodeSigningIdentity  = Certificate.FriendlyName; // since the pipeline will use a temporary keychain that will contain only this certificate, this should be the only identity that will work
            CurrentBaseXCodeCommandLine = GetBaseXcodeCommandline();

            // get the UUID
            string AllText = File.ReadAllText(FinalMobileProvisionFilename);
            string UUID    = "";
            int    idx     = AllText.IndexOf("<key>UUID</key>");

            if (idx > 0)
            {
                idx = AllText.IndexOf("<string>", idx);
                if (idx > 0)
                {
                    idx += "<string>".Length;
                    UUID = AllText.Substring(idx, AllText.IndexOf("</string>", idx) - idx);
                }
            }
            CurrentBaseXCodeCommandLine += String.Format(" PROVISIONING_PROFILE=" + UUID);

            // needs Mac line endings so it can be executed
            string SrcPath  = @"..\..\..\Build\" + Config.OSString + @"\XcodeSupportFiles\prepackage.sh";
            string DestPath = Path.Combine(Config.PCXcodeStagingDir, @"prepackage.sh");

            Program.Log(" ... '" + SrcPath + "' -> '" + DestPath + "'");
            string SHContents = File.ReadAllText(SrcPath);

            SHContents = SHContents.Replace("\r\n", "\n");
            File.WriteAllText(DestPath, SHContents);

            CookTime.CopySignedFiles();
        }
        /// <summary>
        /// Copy the files always needed (even in a stub IPA)
        /// </summary>
        static public void CopyFilesNeededForMakeApp()
        {
            // Copy Info.plist over (modifiying it as needed)
            string SourcePListFilename = Utilities.GetPrecompileSourcePListFilename();

            Utilities.PListHelper Info = Utilities.PListHelper.CreateFromFile(SourcePListFilename);

            // Edit the plist
            CookTime.UpdateVersion(Info);

            // Write out the <GameName>-Info.plist file to the xcode staging directory
            string TargetPListFilename = Path.Combine(Config.PCXcodeStagingDir, Program.GameName + "-Info.plist");

            Directory.CreateDirectory(Path.GetDirectoryName(TargetPListFilename));
            string OutString = Info.SaveToString();

            OutString = OutString.Replace("${EXECUTABLE_NAME}", Program.GameName);
            OutString = OutString.Replace("${BUNDLE_IDENTIFIER}", Program.GameName.Replace("_", ""));

            // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist
            // eventually we want to generate this based on what the user has set in the project settings
            string[] IPhoneConfigs =
            {
                "Default-IPhone6",               "Landscape", "{375, 667}",
                "Default-IPhone6",               "Portrait",  "{375, 667}",
                "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}",
                "Default-IPhone6Plus-Portrait",  "Portrait",  "{414, 736}",
                "Default",                       "Landscape", "{320, 480}",
                "Default",                       "Portrait",  "{320, 480}",
                "Default-568h",                  "Landscape", "{320, 568}",
                "Default-568h",                  "Portrait",  "{320, 568}",
            };

            StringBuilder NewLaunchImagesString = new StringBuilder("<key>UILaunchImages~iphone</key>\n\t\t<array>\n");

            for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3)
            {
                NewLaunchImagesString.Append("\t\t\t<dict>\n");
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageMinimumOSVersion</key>\n");
                NewLaunchImagesString.Append("\t\t\t\t<string>8.0</string>\n");
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageName</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 0]);
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageOrientation</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 1]);
                NewLaunchImagesString.Append("\t\t\t\t<key>UILaunchImageSize</key>\n");
                NewLaunchImagesString.AppendFormat("\t\t\t\t<string>{0}</string>\n", IPhoneConfigs[ConfigIndex + 2]);
                NewLaunchImagesString.Append("\t\t\t</dict>\n");
            }

            // close it out
            NewLaunchImagesString.Append("\t\t\t</array>\n\t\t<key>UILaunchImages~ipad</key>");
            OutString = OutString.Replace("<key>UILaunchImages~ipad</key>", NewLaunchImagesString.ToString());

            byte[] RawInfoPList = Encoding.UTF8.GetBytes(OutString);
            File.WriteAllBytes(TargetPListFilename, RawInfoPList);

            Program.Log("Updating .plist: {0} --> {1}", SourcePListFilename, TargetPListFilename);

            // look for an entitlements file (optional)
            string SourceEntitlements = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".entitlements");

            // set where to make the entitlements file (
            string TargetEntitlements = Path.Combine(Config.PCXcodeStagingDir, Program.GameName + ".entitlements");

            if (File.Exists(SourceEntitlements))
            {
                FileOperations.CopyRequiredFile(SourceEntitlements, TargetEntitlements);
            }
            else
            {
                // we need to have something so Xcode will compile, so we just set the get-task-allow, since we know the value,
                // which is based on distribution or not (true means debuggable)
                File.WriteAllText(TargetEntitlements, string.Format("<plist><dict><key>get-task-allow</key><{0}/></dict></plist>",
                                                                    Config.bForDistribution ? "false" : "true"));
            }


            // Copy the no sign resource rules file over
            if (!Config.bForDistribution)
            {
                FileOperations.CopyRequiredFile(@"..\..\..\Build\IOS\XcodeSupportFiles\CustomResourceRules.plist", Path.Combine(Config.PCStagingRootDir, "CustomResourceRules.plist"));
            }

            // Copy the mobile provision file over
            string ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory, Program.GameName + ".mobileprovision");

            if (!File.Exists(ProvisionWithPrefix))
            {
                ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.BuildDirectory + "/NotForLicensees/", Program.GameName + ".mobileprovision");
                if (!File.Exists(ProvisionWithPrefix))
                {
                    ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory, "UE4Game.mobileprovision");
                    if (!File.Exists(ProvisionWithPrefix))
                    {
                        ProvisionWithPrefix = FileOperations.FindPrefixedFile(Config.EngineBuildDirectory + "/NotForLicensees/", "UE4Game.mobileprovision");
                    }
                }
            }
            string FinalMobileProvisionFilename = Path.Combine(Config.PCXcodeStagingDir, MacMobileProvisionFilename);

            FileOperations.CopyRequiredFile(ProvisionWithPrefix, FinalMobileProvisionFilename);
            // make sure this .mobileprovision file is newer than any other .mobileprovision file on the Mac (this file gets multiple games named the same file,
            // so the time stamp checking can fail when moving between games, a la the buildmachines!)
            File.SetLastWriteTime(FinalMobileProvisionFilename, DateTime.UtcNow);

            FileOperations.CopyRequiredFile(Config.RootRelativePath + @"Engine\Intermediate\IOS\UE4.xcodeproj\project.pbxproj", Path.Combine(Config.PCXcodeStagingDir, @"project.pbxproj.datecheck"));

            // needs Mac line endings so it can be executed
            string SrcPath  = @"..\..\..\Build\IOS\XcodeSupportFiles\prepackage.sh";
            string DestPath = Path.Combine(Config.PCXcodeStagingDir, @"prepackage.sh");

            Program.Log(" ... '" + SrcPath + "' -> '" + DestPath + "'");
            string SHContents = File.ReadAllText(SrcPath);

            SHContents = SHContents.Replace("\r\n", "\n");
            File.WriteAllText(DestPath, SHContents);

            CookTime.CopySignedFiles();
        }