Copying app extensions in a post-build phase includes the CodeSignOnCopy attribute, which creates a cycle when using the new build system. Xcode doesn't add the attribute, so it probably shouldn't be included.
Copying the app extension into the main target creates a cycle when using the new build system:
Showing Recent Messages
:-1: Cycle inside MyApp; building could produce unreliable results.
Cycle details:
→ Target 'MyApp' : CodeSign /Users/caesar/Library/Developer/Xcode/DerivedData/MyApp-akrqtdfekistduerxppbnpbmbzhr/Build/Products/Debug-iphonesimulator/MyApp.app/PlugIns/iMessageApp.appex
○ Target 'MyApp' : ValidateEmbeddedBinary /Users/caesar/Library/Developer/Xcode/DerivedData/MyApp-akrqtdfekistduerxppbnpbmbzhr/Build/Products/Debug-iphonesimulator/MyApp.app/PlugIns/iMessageApp.appex
○ Target 'MyApp' : CodeSign /Users/caesar/Library/Developer/Xcode/DerivedData/MyApp-akrqtdfekistduerxppbnpbmbzhr/Build/Products/Debug-iphonesimulator/MyApp.app/PlugIns/iMessageApp.appex
I have a sample project that illustrates this.
I'm embedding the app extension using this build phase:
postBuildScripts:
- name: Embed App Extensions
script: |
cp -r ${BUILT_PRODUCTS_DIR}/iMessage.appex ${TARGET_BUILD_DIR}/${PLUGINS_FOLDER_PATH}/iMessage.appex
Maybe I'm just doing this bit wrong, and this problem is just user error 🤷♂️
I am able to get the project to build by going into the Copy Files build phase that is created, removing the iMessage.appex from it, and then manually re-adding it to the build phase (which is what the this commit in the sample project is doing).
We use XcodeGen pretty heavily, so having to remember to manually remove/re-add the file each time isn't great.
The relevant part of the diff is basically:
- BF_887147700664 /* iMessageApp.appex in CopyFiles */ = {isa = PBXBuildFile; fileRef = FR_935153865209 /* iMessageApp.appex */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 397D8E8520C85D0E00FFACDE /* iMessageApp.appex in CopyFiles */ = {isa = PBXBuildFile; fileRef = FR_935153865209 /* iMessageApp.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
Or to zero in on it, the CodeSignOnCopy attribute isn't included when manually including the file through Xcode.
This kind of makes sense looking at the error message, then --> it looks like it's trying to codesign the same file twice, which isn't something that the new build system wants to do (?).
It's definitely possible that I'm just not using the correct settings in the project.yml to include the app extension. In which case this was a fun exploration into the project.pbxproj file 🤷♂️
@yonaskolb - FWIW, this is happening for us as well and blocks building of an app with extension. Is this an issue in xcproj or xcodegen?
For what it's worth, I also submitted a radar to either add the "Code Sign On Copy" checkbox to app extensions, or ignore the attribute when building with the new build system, since it's able to detect it and hide the checkbox for extensions.
It was marked as a duplicate of 40839160.
Thats a dupe of my radar! I'll let you know if I hear anything back
It looks like CodeSignOnCopy defaults to true for all dependencies
https://github.com/yonaskolb/XcodeGen/blob/master/Sources/ProjectSpec/Dependency.swift#L38
A workaround is to set codeSign to false for your dependency.
The default for this value should be changed based on what type of target it's referencing. Are you aware of what sort of dependencies should be code signed?
@cjwirth in addition you may not need your postbuild script if you set embed to true as well. The default for this could be changed too.
dependencies:
- target: MyExtension
codeSign: false
embed: true
Are you aware of what sort of dependencies should be code signed?
Unfortunately not. There's still 2 days of WWDC, so I guess I could stop into a lab and ask?
in addition you may not need your postbuild script if you set embed to true as well. The default for this could be changed too.
This works! I must have missed these options in the docs, thanks!
Feel free to close this issue, as it's not really an issue. Or leave it open if you think it's worth it for changing the default value of codeSign.
I'll leave it here, as those defaults should be smarter
It seems frameworks are set to be code signed by default but extensions are not.
I think XcodeGen should change the default value, based on dependency targets type.
I talked with an engineer today, and he said that since the entire bundle will be code signed at the end, it's probably not necessary to code sign files that are being copied into the bundle (and in this case causing problems). He also said that he wasn't _entirely_ sure about it, but that's what he thought.
I've opened #324 for this 👍
Most helpful comment
I talked with an engineer today, and he said that since the entire bundle will be code signed at the end, it's probably not necessary to code sign files that are being copied into the bundle (and in this case causing problems). He also said that he wasn't _entirely_ sure about it, but that's what he thought.