Example #1
0
        /**
         * Creates the application directory on the Mac
         */
        static public void CreateApplicationDirOnMac()
        {
            DateTime StartTime = DateTime.Now;

            // Cleans out the intermediate folders on both ends
            CompileTime.ExecuteRemoteCommand("DeleteIPA");
            CompileTime.ExecuteRemoteCommand("DeleteMacStagingFiles");
            Program.ExecuteCommand("Clean", null);
            //@TODO: mnoland 10/5/2010
            // Need to come up with a way to prevent this from causing an error on the remote machine
            // CompileTime.ExecuteRemoteCommand("Clean");

            // Stage files
            Program.Log("Staging files before copying to Mac ...");
            CopyFilesNeededForMakeApp();

            // Copy staged files from PC to Mac
            Program.ExecuteCommand("StageMacFiles", null);

            // Set the executable bit on the EXE
            CompileTime.ExecuteRemoteCommand("SetExec");

            // Install the provision (necessary for MakeApp to succeed)
            CompileTime.ExecuteRemoteCommand("EnsureProvisionDirExists");
            CompileTime.ExecuteRemoteCommand("InstallProvision");

            // strip the symbols if desired or required
            if (Config.bForceStripSymbols || Config.bForDistribution)
            {
                CompileTime.ExecuteRemoteCommand("Strip");
            }

            // sign the exe, etc...
            CompileTime.ExecuteRemoteCommand("PrePackage");
            if (!Config.bUseRPCUtil)
            {
                CompileTime.ExecuteRemoteCommand("DeleteKeyChain", true);
                CompileTime.ExecuteRemoteCommand("CreateKeyChain");
            }
            CompileTime.ExecuteRemoteCommand("MakeApp");
            if (!Config.bUseRPCUtil)
            {
                CompileTime.ExecuteRemoteCommand("DeleteKeyChain");
            }

            Program.Log(String.Format("Finished creating .app directory on Mac (took {0:0.00} s)",
                                      (DateTime.Now - StartTime).TotalSeconds));
        }
Example #2
0
        /**
         * Packages an IPA on the Mac
         */
        static public void PackageIPAOnMac()
        {
            // Create the .app structure on the Mac (and codesign, etc...)
            CreateApplicationDirOnMac();

            DateTime StartTime = DateTime.Now;

            // zip up
            CompileTime.ExecuteRemoteCommand("Zip");

            // fetch the IPA
            if (Config.bCreateStubSet)
            {
                Program.ExecuteCommand("GetStubIPA", null);
            }
            else
            {
                Program.ExecuteCommand("GetIPA", null);
            }

            Program.Log(String.Format("Finished packaging into IPA (took {0:0.00} s)",
                                      (DateTime.Now - StartTime).TotalSeconds));
        }
Example #3
0
        /**
         * Using the stub IPA previously compiled on the Mac, create a new IPA with assets
         */
        static public void RepackageIPAFromStub()
        {
            if (string.IsNullOrEmpty(Config.RepackageStagingDirectory) || !Directory.Exists(Config.RepackageStagingDirectory))
            {
                Program.Error("Directory specified with -stagedir could not be found!");
                return;
            }


            DateTime             StartTime  = DateTime.Now;
            CodeSignatureBuilder CodeSigner = null;

            // Clean the staging directory
            Program.ExecuteCommand("Clean", null);

            // Create a copy of the IPA so as to not trash the original
            ZipFile Zip = SetupWorkIPA();

            if (Zip == null)
            {
                return;
            }

            string ZipWorkingDir = String.Format("Payload/{0}{1}.app/", Program.GameName, Program.Architecture);

            FileOperations.ZipFileSystem FileSystem = new FileOperations.ZipFileSystem(Zip, ZipWorkingDir);

            // Check for a staged plist that needs to be merged into the main one
            {
                // Determine if there is a staged one we should try to use instead
                string PossiblePList = Path.Combine(Config.RepackageStagingDirectory, "Info.plist");
                if (File.Exists(PossiblePList))
                {
                    if (Config.bPerformResignWhenRepackaging)
                    {
                        Program.Log("Found Info.plist ({0}) in stage, which will be merged in with stub plist contents", PossiblePList);

                        // Merge the two plists, using the staged one as the authority when they conflict
                        byte[] StagePListBytes = File.ReadAllBytes(PossiblePList);
                        string StageInfoString = Encoding.UTF8.GetString(StagePListBytes);

                        byte[] StubPListBytes          = FileSystem.ReadAllBytes("Info.plist");
                        Utilities.PListHelper StubInfo = new Utilities.PListHelper(Encoding.UTF8.GetString(StubPListBytes));

                        StubInfo.MergePlistIn(StageInfoString);

                        // Write it back to the cloned stub, where it will be used for all subsequent actions
                        byte[] MergedPListBytes = Encoding.UTF8.GetBytes(StubInfo.SaveToString());
                        FileSystem.WriteAllBytes("Info.plist", MergedPListBytes);
                    }
                    else
                    {
                        Program.Warning("Found Info.plist ({0}) in stage that will be ignored; IPP cannot combine it with the stub plist since -sign was not specified", PossiblePList);
                    }
                }
            }

            // Get the name of the executable file
            string CFBundleExecutable;

            {
                // Load the .plist from the stub
                byte[] RawInfoPList = FileSystem.ReadAllBytes("Info.plist");

                Utilities.PListHelper Info = new Utilities.PListHelper(Encoding.UTF8.GetString(RawInfoPList));

                // Get the name of the executable file
                if (!Info.GetString("CFBundleExecutable", out CFBundleExecutable))
                {
                    throw new InvalidDataException("Info.plist must contain the key CFBundleExecutable");
                }
            }

            // Tell the file system about the executable file name so that we can set correct attributes on
            // the file when zipping it up
            FileSystem.ExecutableFileName = CFBundleExecutable;

            // Prepare for signing if requested
            if (Config.bPerformResignWhenRepackaging)
            {
                // Start the resign process (load the mobileprovision and info.plist, find the cert, etc...)
                CodeSigner            = new CodeSignatureBuilder();
                CodeSigner.FileSystem = FileSystem;

                CodeSigner.PrepareForSigning();

                // Merge in any user overrides that exist
                UpdateVersion(CodeSigner.Info);
            }

            // Empty the current staging directory
            FileOperations.DeleteDirectory(new DirectoryInfo(Config.PCStagingRootDir));

            // we will zip files in the pre-staged payload dir
            string ZipSourceDir = Config.RepackageStagingDirectory;

            // Save the zip
            Program.Log("Saving IPA ...");

            FilesBeingModifiedToPrintOut.Clear();
            Zip.SaveProgress += UpdateSaveProgress;

            Zip.CompressionLevel = (Ionic.Zlib.CompressionLevel)Config.RecompressionSetting;

            // Add all of the payload files, replacing existing files in the stub IPA if necessary (should only occur for icons)
            {
                string   SourceDir    = Path.GetFullPath(ZipSourceDir);
                string[] PayloadFiles = Directory.GetFiles(SourceDir, "*.*", SearchOption.AllDirectories);
                foreach (string Filename in PayloadFiles)
                {
                    // Get the relative path to the file (this implementation only works because we know the files are all
                    // deeper than the base dir, since they were generated from a search)
                    string AbsoluteFilename = Path.GetFullPath(Filename);
                    string RelativeFilename = AbsoluteFilename.Substring(SourceDir.Length + 1).Replace('\\', '/');

                    string ZipAbsolutePath = String.Format("Payload/{0}{1}.app/{1}",
                                                           Program.GameName,
                                                           Program.Architecture,
                                                           RelativeFilename);

                    byte[] FileContents = File.ReadAllBytes(AbsoluteFilename);
                    if (FileContents.Length == 0)
                    {
                        // Zero-length files added by Ionic cause installation/upgrade to fail on device with error 0xE8000050
                        // We store a single byte in the files as a workaround for now
                        FileContents    = new byte[1];
                        FileContents[0] = 0;
                    }

                    FileSystem.WriteAllBytes(RelativeFilename, FileContents);

                    if ((FileContents.Length >= 1024 * 1024) || (Config.bVerbose))
                    {
                        FilesBeingModifiedToPrintOut.Add(ZipAbsolutePath);
                    }
                }
            }

            // Re-sign the executable if there is a signing context
            if (CodeSigner != null)
            {
                if (Config.OverrideBundleName != null)
                {
                    CodeSigner.Info.SetString("CFBundleDisplayName", Config.OverrideBundleName);
                    string CFBundleIdentifier;
                    if (CodeSigner.Info.GetString("CFBundleIdentifier", out CFBundleIdentifier))
                    {
                        CodeSigner.Info.SetString("CFBundleIdentifier", CFBundleIdentifier + "_" + Config.OverrideBundleName);
                    }
                }
                CodeSigner.PerformSigning();
            }

            // Stick in the iTunesArtwork PNG if available
            string iTunesArtworkPath = Path.Combine(Config.BuildDirectory, "iTunesArtwork");

            if (File.Exists(iTunesArtworkPath))
            {
                Zip.UpdateFile(iTunesArtworkPath, "");
            }

            // Save the Zip

            Program.Log("Compressing files into IPA (-compress={1}).{0}", Config.bVerbose ? "" : "  Only large files will be listed next, but other files are also being packaged.", Config.RecompressionSetting);
            FileSystem.Close();

            TimeSpan ZipLength = DateTime.Now - StartTime;

            FileInfo FinalZipInfo = new FileInfo(Zip.Name);


            Program.Log(String.Format("Finished repackaging into {2:0.00} MB IPA, written to '{0}' (took {1:0.00} s for all steps)",
                                      Zip.Name,
                                      ZipLength.TotalSeconds,
                                      FinalZipInfo.Length / (1024.0f * 1024.0f)));
        }