为什么 Xcode 复制嵌入式框架 headers 的行为因目标而异?
Why does Xcode behavior of copying embedded framework headers differ across targets?
我正在开发一个有两个构建目标的 Mac 项目。我的一位用户报告无法安装其中一个目标。
好的,让我们用RB App Checker Lite.
检查一下
有意思。这个目标缺少一些资源,我们称它为 Example 2.
为了确定,我检查了另一个目标 Example 1
,那个没有任何验证问题。
所以目标是不同的,因为它涉及复制 headers 嵌入在 HockeySDK/CrashReporter 框架中。代码签名期望这些 headers 存在,但它们不存在,并且签名验证失败。
我还检查了磁盘上的捆绑包。果然,示例 1 中有 headers 而示例 2 中没有。
我的下一个问题是,为什么构建的目标不同?为什么示例 1 包含 headers 而示例 2 不包含?我查看了目标的构建日志,果然,“复制框架”阶段有所不同。
示例 1 日志:
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
示例 2 日志:
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
果然,示例 2 builtin-copy
命令包含额外的参数 -exclude Headers -exclude PrivateHeaders
,这导致 headers 不被包含。
现在,问题是,为什么构建一个目标排除 headers 而另一个不排除?
我一遍又一遍地检查了目标的构建设置,看起来与我一样。我似乎没有办法影响 builtin-copy
的行为。但很明显,有什么在影响它。
我现在使用我不喜欢的丑陋解决方法修复了它。我真的很想了解这里发生了什么以及如何解决这个问题。
我的 Xcode 版本是 6.1.1 (6A2008a),目前可从 App Store 下载。
Xcode 非常有选择性地决定向您展示什么,因此在调查此类问题时,第一步是查看 project.pbxproj
文件 手工.
打开 Example 1.xcodeproj/project.pbxproj
并导航至复制框架的说明(我搜索 "Copy Framework Files"),您会看到如下内容:
BCAC434BC9F0E2F78087CA01 /* HockeySDK.framework in Copy Framework Files */ = {isa = PBXBuildFile; fileRef = BCAC434BC9F0E2F78087CA01 /* HockeySDK.framework */; };
Example 2.xcodeproj/project.pbxproj
中的类似物:
F19543FC17EC99FB62CA62C8 /* HockeySDK.framework in Copy Framework Files */ = {isa = PBXBuildFile; fileRef = F19543FC17EC99FB62CA62C8 /* HockeySDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
从那里,很清楚。示例 2 的复制指令后面有一些附加设置:
settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); };
因此,对于 "fix" 这个问题,您可以根据需要添加或删除 RemoveHeadersOnCopy
设置。
遗憾的是,这并未反映在 UI 中。 Xcode 的某些版本似乎只会添加它(我怀疑它与代码签名复选框有关,但我无法重现任何值得一提的内容)。
我正在开发一个有两个构建目标的 Mac 项目。我的一位用户报告无法安装其中一个目标。
好的,让我们用RB App Checker Lite.
检查一下有意思。这个目标缺少一些资源,我们称它为 Example 2.
为了确定,我检查了另一个目标 Example 1
,那个没有任何验证问题。
所以目标是不同的,因为它涉及复制 headers 嵌入在 HockeySDK/CrashReporter 框架中。代码签名期望这些 headers 存在,但它们不存在,并且签名验证失败。
我还检查了磁盘上的捆绑包。果然,示例 1 中有 headers 而示例 2 中没有。
我的下一个问题是,为什么构建的目标不同?为什么示例 1 包含 headers 而示例 2 不包含?我查看了目标的构建日志,果然,“复制框架”阶段有所不同。
示例 1 日志:
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
示例 2 日志:
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
果然,示例 2 builtin-copy
命令包含额外的参数 -exclude Headers -exclude PrivateHeaders
,这导致 headers 不被包含。
现在,问题是,为什么构建一个目标排除 headers 而另一个不排除?
我一遍又一遍地检查了目标的构建设置,看起来与我一样。我似乎没有办法影响 builtin-copy
的行为。但很明显,有什么在影响它。
我现在使用我不喜欢的丑陋解决方法修复了它。我真的很想了解这里发生了什么以及如何解决这个问题。
我的 Xcode 版本是 6.1.1 (6A2008a),目前可从 App Store 下载。
Xcode 非常有选择性地决定向您展示什么,因此在调查此类问题时,第一步是查看 project.pbxproj
文件 手工.
打开 Example 1.xcodeproj/project.pbxproj
并导航至复制框架的说明(我搜索 "Copy Framework Files"),您会看到如下内容:
BCAC434BC9F0E2F78087CA01 /* HockeySDK.framework in Copy Framework Files */ = {isa = PBXBuildFile; fileRef = BCAC434BC9F0E2F78087CA01 /* HockeySDK.framework */; };
Example 2.xcodeproj/project.pbxproj
中的类似物:
F19543FC17EC99FB62CA62C8 /* HockeySDK.framework in Copy Framework Files */ = {isa = PBXBuildFile; fileRef = F19543FC17EC99FB62CA62C8 /* HockeySDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
从那里,很清楚。示例 2 的复制指令后面有一些附加设置:
settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); };
因此,对于 "fix" 这个问题,您可以根据需要添加或删除 RemoveHeadersOnCopy
设置。
遗憾的是,这并未反映在 UI 中。 Xcode 的某些版本似乎只会添加它(我怀疑它与代码签名复选框有关,但我无法重现任何值得一提的内容)。