Reputation: 17856
I am working on a Mac project that has two build targets. One of my users reported being unable to install one of the targets.
Okay, let’s check it with RB App Checker Lite.
Interesting. There’s some resources missing from this target, let’s call it Example 2.
Just to be sure, I checked the other target, Example 1
and that one didn’t have any validation problems.
So the targets are different as it relates to copying the headers embedded in HockeySDK/CrashReporter framework. The code signature expects these headers to be there, but they’re not, and the signature validation fails.
I also checked the bundles on disk. Sure enough, the headers are there in Example 1 but not Example 2.
My next question was, why are the targets built differently? Why does Example 1 include the headers and Example 2 doesn’t? I looked into the build logs of the targets, and sure enough, there’s a difference in the “Copy frameworks” phase.
Example 1 log:
PBXCp Libraries/HockeySDK-Mac/HockeySDK.framework /Users/jaanus/Library/Developer/Xcode/DerivedData/Example-chptxdrwwlafgodccbiqclccqjkl/Build/Intermediates/ArchiveIntermediates/Example\ 1/InstallationBuildProductsLocation/Applications/Example\ 1.app/Contents/Frameworks/HockeySDK.framework
cd /Users/jaanus/dev/Example/tool
builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git\
-exclude .hg -resolve-src-symlinks /Users/jaanus/dev/Example/tool/Libraries/HockeySDK-Mac/HockeySDK.framework /Users/jaanus/Library/Developer/Xcode/DerivedData/Example-chptxdrwwlafgodccbiqclccqjkl/Build/Intermediates/ArchiveIntermediates/Example\ 1/InstallationBuildProductsLocation/Applications/Example\ 1.app/Contents/Frameworks
Example 2 log:
PBXCp Libraries/HockeySDK-Mac/HockeySDK.framework /Users/jaanus/Library/Developer/Xcode/DerivedData/Example-chptxdrwwlafgodccbiqclccqjkl/Build/Intermediates/ArchiveIntermediates/Example\ 2/InstallationBuildProductsLocation/Applications/Example\ 2.app/Contents/Frameworks/HockeySDK.framework
cd /Users/jaanus/dev/Example/tool
builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git\
-exclude .hg -exclude Headers -exclude PrivateHeaders -resolve-src-symlinks /Users/jaanus/dev/Example/tool/Libraries/HockeySDK-Mac/HockeySDK.framework /Users/jaanus/Library/Developer/Xcode/DerivedData/Example-chptxdrwwlafgodccbiqclccqjkl/Build/Intermediates/ArchiveIntermediates/Example\ 2/InstallationBuildProductsLocation/Applications/Example\ 2.app/Contents/Frameworks
Sure enough, the example 2 builtin-copy
command contains the extra arguments -exclude Headers -exclude PrivateHeaders
which are causing the headers to not be included.
Now, the question is, why does building one target exclude the headers and the other doesn’t?
I’ve reviewed the build settings of the targets over and over and the look as identical as can be to me. There doesn’t seem to be a way for me to influence the behavior of builtin-copy
. But obviously, something is influencing it.
I fixed it for now using an ugly workaround that I don’t like. I’d really like to understand what’s going on here and how to fix this.
My Xcode version is 6.1.1 (6A2008a), the one that’s currently available from App Store.
Upvotes: 4
Views: 1448
Reputation: 601
Xcode is very selective about what it decides to show you, so when it comes to investigating a problem like this the first step is to look at the project.pbxproj
file by hand.
Opening up Example 1.xcodeproj/project.pbxproj
and navigating to the instruction to copy the framework (I search for "Copy Framework Files"), you'll see something like:
BCAC434BC9F0E2F78087CA01 /* HockeySDK.framework in Copy Framework Files */ = {isa = PBXBuildFile; fileRef = BCAC434BC9F0E2F78087CA01 /* HockeySDK.framework */; };
And the analogue in Example 2.xcodeproj/project.pbxproj
:
F19543FC17EC99FB62CA62C8 /* HockeySDK.framework in Copy Framework Files */ = {isa = PBXBuildFile; fileRef = F19543FC17EC99FB62CA62C8 /* HockeySDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
From there, it's clear. Example 2's copy instruction has some additional settings after it:
settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); };
So to "fix" the problem you can just add or remove the RemoveHeadersOnCopy
setting as required.
Unfortunately, this is not reflected in the UI. It seems some versions of Xcode will just add it in (and I suspect it's related to the Code Sign checkbox, but I couldn't reproduce anything worthy of mentioning).
Upvotes: 4