I was looking to exclude non-chunk-0 pak/.utoc/.ucas files from the IPA generated by an iOS build for my project. I initially found this tutorial page https://dev.epicgames.com/community/learning/tutorials/vwx7/unreal-engine-excluding-chunks-from-ios-builds mentioning that for iOS you needed to add the following parameters to the build command
-chunkinstalldirectory="/Users/Shared/Projects/ChunkTest/CDNChunks" -chunkinstallversion=1.0
But the page also mentioned: “Unfortunately, this does not seem to be aware of the IO Store system that generates a corresponding utoc and ucas file for each pak file, and does not exclude those files from the pak. It does work correctly if you disable the IO Store under Project Settings -> Packaging.”
I then found this old EpicProSupport post [Content removed] which seems to have been the inspiration for the Tutorial page, and in it Jack Porter mentioned: “I am working on a fix to copy and exclude the utoc and ucas files but until it’s available I suggest you try without IOStore enabled.” He also entered ticket UE-172550 to fix the IOStore issue. I went and checked the ticket https://issues.unrealengine.com/issue/UE-172550 and the associated fix commit in UE 5.3 and saw that the fix copied the .utoc/.ucas files to the chunk output directory but did nothing to exclude them from the final build.
I am therefore proposing the following change to the Engine\Source\Programs\AutomationTool\Scripts\CopyBuildToStagingDirectory.Automation.cs script to actually exclude the non-chunk-0 .utoc/.ucas files from the packaged build when running -createchunkinstall with IOStore enabled:
//copy the pak chunk to the raw data folder
InternalUtils.SafeDeleteFile(RawDataPakPath, true);
InternalUtils.SafeDeleteFile(Path.ChangeExtension(RawDataPakPath, ".sig"), true);
// BEGIN CHANGE
// Delete the .utoc and .ucas files from the chunkinstalldirectory in case they are still around from a prior run
InternalUtils.SafeDeleteFile(Path.ChangeExtension(RawDataPakPath, ".utoc"), true);
InternalUtils.SafeDeleteFile(Path.ChangeExtension(RawDataPakPath, ".ucas"), true);
// END CHANGE
InternalUtils.SafeCreateDirectory(RawDataPath, true);
InternalUtils.SafeCopyFile(OutputLocation.FullName, RawDataPakPath);
if (bPakFilesAreSigned)
{
InternalUtils.SafeCopyFile(Path.ChangeExtension(OutputLocation.FullName, ".sig"), Path.ChangeExtension(RawDataPakPath, ".sig"), true);
}
if (bShouldCreateIoStoreContainerFiles)
{
InternalUtils.SafeCopyFile(Path.ChangeExtension(OutputLocation.FullName, ".utoc"), Path.ChangeExtension(RawDataPakPath, ".utoc"), true);
InternalUtils.SafeCopyFile(Path.ChangeExtension(OutputLocation.FullName, ".ucas"), Path.ChangeExtension(RawDataPakPath, ".ucas"), true);
// BEGIN CHANGE
// Delete the .utoc and .ucas files from the output directory after having copied them to the chunkinstalldirectory in the
// context of a createchunkinstall build so they don't end up in the Catalyst\Content\Paks\ directory of the final build.
InternalUtils.SafeDeleteFile(Path.ChangeExtension(OutputLocation.FullName, ".utoc"), true);
InternalUtils.SafeDeleteFile(Path.ChangeExtension(OutputLocation.FullName, ".ucas"), true);
// END CHANGE
// Check if the optional .uondemandtoc file exists before trying to copy it
string OnDemandTocSrcPath = Path.ChangeExtension(OutputLocation.FullName, ".uondemandtoc");
if (File.Exists(OnDemandTocSrcPath))
{
InternalUtils.SafeCopyFile(OnDemandTocSrcPath, Path.ChangeExtension(RawDataPakPath, ".uondemandtoc"), true);
}
}
InternalUtils.SafeDeleteFile(OutputLocation.FullName, true);
It might be worth considering making the same change for the .uondemandtoc file as well while you are at it (I did not include that fix in my snippet).