In my project I have an aggregate target that runs a script that generates a "web bundle" in a folder build/
with all the html/css/resources needed for the website. These resources are generated via a script. I use these resources in multiple targets so I have created an aggregate target to make this simple.
However, I have not found this simple. If I have the aggregate target output to $(DERIVED_FILE_DIR)/
then it outputs to a path that looks like this
DerivedData/BrowserApp-bla/Build/Intermediates.noindex/BrowserApp.build/Debug-iphonesimulator/WebBundle.build/DerivedSources/build/index.html
If I then drag that folder into Xcode and create a folder that references it. Then take that reference and make it relative to build products I get this
A9DE6A502E41E397005EF4E0 /* build */ = {
isa = PBXFileSystemSynchronizedRootGroup;
name = build;
path = "../../Intermediates.noindex/BrowserApp.build/Debug-iphonesimulator/WebBundle.build/DerivedSources/build";
sourceTree = BUILT_PRODUCTS_DIR;
};
This is because to the main BrowserApp target the BUILT_PRODUCTS_DIR
is DerivedData/BrowserApp-bla/Build/Products/Debug-iphonesimulator
.
You can see that the reference essentially has to maneuver out of the built products folder for the main BrowserApp target and into the built products directory for WebBundle.
This is ok for a debug build I suppose you can imagine that this is going to break down the moment you have a release build.
Now if we ignore that problem then comes the problem of getting it in Copy Bundle Resources. Xcode 16s PBXFileSystemSynchronizedRootGroup
is a great improvement but does not help here. The only way I have found to get the folder copied is to hop into an earlier Xcode or make the following modifications.
Change the PBXFileSystemSynchronizedRootGroup into a PBXBuildFile
(In PBXFileReference section)
A9DE6A502E41E397005EF4E0 /* ../../Intermediates.noindex/client.build/Debug/WebBundle.build/DerivedSources/build */ = {isa = PBXFileReference; lastKnownFileType = text; path = ../../Intermediates.noindex/BrowserApp.build/Debug-iphonesimulator/WebBundle.build/DerivedSources/build; sourceTree = BUILT_PRODUCTS_DIR; };
(In the mainGroup PBXGroupSection)
A9DE6A502E41E397005EF4E0 /* ../../Intermediates.noindex/client.build/Debug/WebBundle.build/DerivedSources/build */,
Then remove any references for A9DE6A502E41E397005EF4E0 as a synchronized group
Create a PBXBuildFile using the previous PBXBuildFile as its fileRef then add it to the copy resources stage
(In PBXBuildFile section)
96516AC32BF928DD00576562 /* ../../Intermediates.noindex/BrowserApp.build/Debug-iphonesimulator/WebBundle.build/DerivedSources/build in Resources */ = {isa = PBXBuildFile; fileRef = A9DE6A502E41E397005EF4E0 /* ../../Intermediates.noindex/BrowserApp.build/Debug-iphonesimulator/WebBundle.build/DerivedSources/build */; };
(In the PBXBuildResources phase for the resources section of the main target)
96516AC32BF928DD00576562 /* ../../Intermediates.noindex/BrowserApp.build/Debug-iphonesimulator/WebBundle.build/
I do not know of a way to do this with a PBXFileSystemSynchronizedRootGroup so these manual changes seem necessary. After these changes I have the following:
And you can confirm the entire folder is accessible to the app. However if you try to build for release/Archive you get
lstat(/Users/calebkierum/Library/Developer/Xcode/DerivedData/BrowserApp-bla/Build/Intermediates.noindex/ArchiveIntermediates/BrowserApp/Intermediates.noindex/BrowserApp.build/Debug-iphonesimulator/WebBundle.build/DerivedSources/build): No such file or directory (2)
Which makes sense. The file reference has a relative path that explicitly mentions "debug" however because this path is based on an aggregate target I am not sure how you really update this reference for release.
Also @DTS Engineer a bit of an AHA moment. And thank you that was a great idea haha.
Using BUILT_PRODUCTS_DIR a
s the output destination for the script rather than DERIVED_FILE_DIR
is the solution to this problem.
The core issue of this is how to link the folder that is output from the aggregate build target. This is difficult because:
- Since Xcode 16 Xcode wants to work with PBXFileSystemSynchronizedRootGroup's not folders. This makes it (I think) impossible through the UI to link the folder that is output. I had to manually modify my project file.
- If you use DERIVED_FILE_DIR it makes a separate directory for each target. Making it difficult for your folder reference to stay the same between debug and release builds.
Anywho that solves this portion of the problem.
Other little bit. Xcode complained about multiple things writing to the same location with $(BUILT_PRODUCTS_DIR)/
in the output file list (that works just fine for DERIVED_FILE_DIR
so I can only assume the entire BUILT_PRODUCTS_DIR
is reserved. I just had to change it to $(BUILT_PRODUCTS_DIR)/build/