解决 command codesign failed with a nonzero exit code:一步步教学 – wiki基地


解决 command codesign failed with a nonzero exit code:一步步详细教学

在 iOS 或 macOS 开发中,command codesign failed with a nonzero exit code 是一个开发者经常会遇到的令人沮丧的错误。它通常出现在尝试构建或归档(Archive)你的应用程序时。这个错误信息本身非常通用,仅仅表示 Xcode 在尝试对你的应用程序进行代码签名时,底层的 codesign 命令行工具执行失败,并返回了一个非零的退出状态码,这表明操作未能成功完成。

代码签名是 Apple 平台应用程序安全和信任机制的核心部分。它验证了应用的来源,并确保应用在发布或安装后没有被篡改。成功的代码签名依赖于一系列正确的配置:有效的开发者证书、正确的私钥、匹配的应用程序 ID (App ID) 以及有效的 provisioning profile(配置文件)。command codesign failed 错误几乎总是与这些组件中的一个或多个配置问题有关。

由于这个错误信息过于笼统,解决它通常需要进行一系列系统的排查。本文将提供一个详细、一步步的教学流程,帮助你诊断并解决这个问题。我们将从最常见的原因开始,逐步深入到更复杂的情况。

理解代码签名及其组件

在开始排查之前,先理解一下代码签名的核心要素是很有帮助的:

  1. 开发者证书 (Developer Certificate): 这是一个由 Apple 颁发的数字身份证明,用于验证你作为开发者。它存储在你的 Mac 上的“钥匙串访问” (Keychain Access) 应用中。常见的有 “Apple Development”(开发证书)和 “Apple Distribution”(发布证书)。
  2. 私钥 (Private Key): 与你的开发者证书配对生成。私钥是保密的,它允许你使用对应的证书进行签名。私钥必须存在于你的 Mac 上的钥匙串中,并且与用于签名的证书关联。
  3. App ID (Application Identifier): 这是一个唯一标识你的应用程序的字符串(通常是 Bundle ID 的逆序域名格式,如 com.yourcompany.yourapp)。在 Apple Developer Portal 中创建,并与你的应用程序项目设置相匹配。
  4. Provisioning Profile (配置文件): 这是一个文件,将你的开发者证书、App ID 以及(对于开发和 Ad Hoc 分发)允许运行应用测试的设备列表关联起来。它授权你的应用在特定设备上运行或通过特定方式(如 App Store)分发。Provisioning Profile 也包含应用的授权信息(Entitlements),比如是否允许使用 Push Notifications、App Groups 等。

codesign 工具的工作就是验证和应用这些元素到你的应用二进制文件上。任何一个环节出现问题——证书过期、私钥丢失、App ID 不匹配、配置文件无效或缺少、甚至钥匙串权限问题——都可能导致签名失败。

排查步骤:从简单到复杂

以下是解决 command codesign failed 错误的详细步骤。请按照顺序尝试,每一步之后都尝试重新构建项目,看看问题是否解决。

步骤 1:执行一次彻底的清理和重新构建 (Clean Build Folder & Build)

这是解决 Xcode 中各种奇怪构建错误的“万能”第一步。它可以清除旧的构建产物和中间文件,这些文件有时可能损坏或包含过时的签名信息。

  • 操作:
    1. 在 Xcode 菜单栏,选择 Product -> Clean Build Folder
    2. 等待清理完成。
    3. 再次选择 Product -> Build

如果问题依然存在,继续下一步。

2. 验证证书和 Provisioning Profile 的有效性和匹配性 (Verify Certificates and Provisioning Profiles)

这是导致 codesign failed 错误最常见的原因。需要检查以下几个方面:

2.1 检查 Xcode 项目设置中的签名配置

确保你的项目、Target 以及任何 Pods 项目或第三方依赖的签名设置是正确的。

  • 操作:
    1. 选择你的项目文件(Project Navigator 顶部)。
    2. 选择你的 Target(通常与应用同名)。
    3. 导航到 Signing & Capabilities 选项卡。
    4. 检查 Team 是否选择了正确的 Apple Developer Team。
    5. 检查 Signing 部分:
      • 如果使用 Automatically manage signing(自动管理签名),确保 Team 选择正确,并且 Xcode 没有报告任何错误(例如 “Provisioning profile doesn’t include signing certificate” 或 “No profiles for ‘com.yourcompany.yourapp’ were found”)。如果 Xcode 报告错误,点击 Enable Automatic 或按照提示修复。
      • 如果手动管理签名(Manual Signing),确保 Signing CertificateProvisioning Profile 选择了正确且有效的项。Provisioning Profile 下拉菜单应该显示可用的配置文件,并且与你选择的 Signing CertificateBundle Identifier 匹配。
    6. 对于 Release 或 Archive 配置,通常需要选择 Distribution 证书和相应的 Provisioning Profile(如 App Store, Ad Hoc, Enterprise)。确保你在 Build Settings -> Signing 下检查了所有配置(Debug, Release, Any iOS SDK 等)。展开 Code Signing IdentityProvisioning Profile 部分,确保每个需要的配置都指向正确的证书类型和配置文件。
2.2 检查 Apple Developer Portal 中的证书和 Profile

确保你在 Apple Developer 账户中有有效且正确的证书和 Provisioning Profile。

  • 操作:
    1. 登录 Apple Developer Portal
    2. 导航到 Certificates, Identifiers & Profiles
    3. 检查 Certificates:
      • Certificates 部分,确认你需要使用的开发(Development)或发布(Distribution)证书存在且状态是 Active,没有过期。
      • 如果你需要发布应用(Archive),确保你有 Apple Distribution 或相应的 Enterprise Distribution 证书。
      • 注意证书的类型(iOS Distribution, Apple Distribution, iOS Development, Apple Development 等)。
    4. 检查 Identifiers:
      • Identifiers 部分,确认你的 App ID (Bundle ID) 存在,并且与你的 Xcode 项目中的 Bundle Identifier 精确匹配(包括大小写)。
      • 检查 App ID 下配置的 Capabilities(App Services),确保它们与你的项目中的 Signing & Capabilities 选项卡下启用的功能一致。
    5. 检查 Profiles:
      • Profiles 部分,确认你需要使用的 Provisioning Profile 存在且状态是 Active,没有过期或显示 Invalid
      • 确认 Profile 的类型(iOS App Development, App Store, Ad Hoc, In House 等)与你的构建目的相符。
      • 点击进入 Profile 详情,确认它包含了正确的 App ID、正确的证书以及(如果需要)正确的测试设备列表。
      • 如果 Profile 显示 Invalid 或过期,或者不包含正确的证书/App ID/设备,你需要编辑或重新生成并下载它。
      • 如果怀疑 Profile 有问题,即使它显示为 Active,也尝试重新生成并下载它。 下载后,双击 .mobileprovision 文件,它会被自动添加到 Xcode 中。
2.3 检查你的 Mac 上的钥匙串访问 (Keychain Access)

确保签名所需的证书和私钥存在于你的 Mac 的钥匙串中,并且被系统信任。

  • 操作:
    1. 打开 应用程序 -> 实用工具 -> 钥匙串访问 (Keychain Access)。
    2. 在左侧导航栏,选择 登录 (login) 钥匙串(这是最常见存放开发者身份的地方)。
    3. 在底部左侧选择 证书 (Certificates)。
    4. 在右侧列表中搜索你的证书名称(例如 “Apple Development: Your Name (Team ID)” 或 “Apple Distribution: Your Name (Team ID)”)。
    5. 检查证书状态:
      • 确保证书存在,并且旁边有一个小的蓝色加号图标 (+) 在一个圆圈里。这表示证书被系统信任。如果没有蓝色加号,右键点击证书,选择 显示简介 (Get Info),展开 信任 (Trust) 部分,将 使用此证书时 (When using this certificate) 设置为 始终信任 (Always Trust)。
      • 确保证书没有显示为过期或吊销。
    6. 检查私钥:
      • 展开你的证书旁边的箭头。你应该能看到一个与之关联的私钥。私钥的图标是一个带有黑色钥匙的方形。
      • 重要: 签名需要同时有证书和与之配对的私钥。如果只有证书而没有私钥,或者私钥图标显示为灰色或有其他异常,你将无法进行签名。这通常发生在你在另一台 Mac 上生成了证书并导出了 .cer 文件,但在当前 Mac 上导入 .cer 文件时没有同时导入私钥(需要导出为 .p12 文件才能包含私钥)。
      • 如果私钥丢失: 你可能需要回到 Apple Developer Portal 吊销 (Revoke) 该证书(如果它是个人证书)并重新生成一个新的证书(这将同时生成新的私钥)。如果是团队共享的证书,需要找到拥有原始私钥的团队成员,让他们导出 .p12 文件并分享给你。
    7. 在左侧导航栏,选择 登录 (login) 钥匙串,然后在底部左侧选择 我的证书 (My Certificates)。这里只列出同时拥有证书和私钥的项。确保你需要用于签名的证书和私钥对在这里出现。
2.4 重新下载 Provisioning Profiles

即使在 Developer Portal 中 Profile 看起来正常,重新下载并添加到 Xcode 也常常能解决问题。

  • 操作:
    1. 登录 Apple Developer Portal,导航到 Profiles
    2. 找到相关的 Provisioning Profile,编辑它(可以不做任何修改,仅为触发更新)或直接下载它。
    3. 双击下载的 .mobileprovision 文件。它会自动导入到 Xcode 和你的 Mac 中。
    4. 或者,在 Xcode 中,进入 Xcode -> Preferences -> Accounts。选择你的 Apple ID,点击 Manage Certificates... 检查证书,点击 Download Manual Profiles 下载与你的账户相关的 Provisioning Profiles。

步骤 3:检查钥匙串访问权限和状态 (Keychain Access Permissions and Status)

有时,钥匙串本身的问题或权限设置不当会导致签名失败。

  • 操作:
    1. 打开 钥匙串访问
    2. 确保 登录 (login) 钥匙串是解锁状态。如果它是锁着的,Xcode 在尝试访问私钥时可能会失败。你可以通过右键点击 登录 钥匙串并选择 解锁钥匙串 "登录" (Unlock Keychain “login”) 来解锁。
    3. 尝试修复钥匙串:这不是 macOS 的一个直接功能,但在某些情况下,重启 Mac 可以解决临时的钥匙串问题。更高级的排查可能涉及使用 Keychain First Aid 工具(已在 macOS Sierra 10.12.1 中移除)。如果怀疑钥匙串损坏,可能需要重置钥匙串,但这会丢失所有保存的密码和证书,是非常极端的手段,通常不推荐。

步骤 4:清理 Xcode 缓存和 Derived Data (Clean Xcode Cache and Derived Data)

与清理构建文件夹类似,清除 Xcode 的缓存和派生数据可以移除可能导致问题的损坏或过时文件。

  • 操作:
    1. 关闭 Xcode。
    2. 手动删除 Derived Data 文件夹的内容。默认路径是 ~/Library/Developer/Xcode/DerivedData/。你可以在 Finder 中按下 Shift + Command + G,输入路径前往该文件夹,然后删除其中的所有内容(或只删除你当前项目对应的文件夹)。
    3. 手动删除 Xcode 的缓存文件。默认路径是 ~/Library/Caches/com.apple.dt.Xcode/。同样,前往该文件夹并删除其中的内容。
    4. 重新打开 Xcode。
    5. 再次执行 Product -> Clean Build Folder
    6. 尝试 Product -> Build

5. 验证 Bundle Identifier 和 App ID 的一致性 (Verify Bundle Identifier Consistency)

确保你的 Xcode 项目中的 Bundle Identifier 与你在 Provisioning Profile 和 Apple Developer Portal 中使用的 App ID 精确匹配。

  • 操作:
    1. 在 Xcode 中,选择你的项目文件。
    2. 选择你的 Target。
    3. 导航到 General 选项卡。
    4. Identity 部分,检查 Bundle Identifier 的值。
    5. 登录 Apple Developer Portal,检查你的 App ID 的精确字符串。
    6. 检查你的 Provisioning Profile 的详情,确认其中包含正确的 App ID。
    7. 确保这三个地方的字符串完全一致。

6. 检查 Capabilities (Entitlements) 的匹配性

如果你使用了推送通知、App Groups、Keychain Sharing 等 Capabilities,确保它们在以下三个地方都正确配置:

  • 操作:
    1. Xcode 项目中的 Signing & Capabilities 选项卡。
    2. Apple Developer Portal 中你的 App ID 的配置。
    3. 生成 Provisioning Profile 时,Profile 中包含了这些 Entitlements。

不一致的 Capabilities 会导致 codesign 在尝试写入 Entitlements 时失败。

7. 检查 Build Settings 中的 Code Signing Identity

虽然 Signing & Capabilities 选项卡是配置签名的首选地方,但 Build Settings 下的 Code Signing IdentityProvisioning Profile 设置会覆盖它(特别是在配置复杂或包含多个 Build Configurations 时)。

  • 操作:
    1. 选择你的项目或 Target。
    2. 导航到 Build Settings 选项卡。
    3. 搜索 Code Signing Identity
    4. 展开所有配置(Debug, Release, Any iOS SDK 等)。
    5. 确保每种配置都指向了正确的证书类型(例如,iOS DeveloperiOS Distribution)。通常设置为 Apple DevelopmentApple Distribution,或者使用 iOS Developer / iOS Distribution 让 Xcode 自动选择。
    6. 搜索 Provisioning Profile
    7. 展开所有配置,确保每种配置都选择了正确或合适的 Provisioning Profile。使用 Automatic 通常是一个不错的选择,如果手动管理,确保选择了正确的 Profile UUID 或名称。

8. 检查 Xcode 版本和 Command Line Tools

确保你的 Xcode 版本与项目兼容,并且安装了正确的命令行工具。

  • 操作:
    1. 检查你使用的 Xcode 版本是否是最新的,或者至少是支持你的操作系统和项目 SDK 的版本。
    2. 安装或更新命令行工具:
      • 打开 终端 (Terminal)。
      • 运行命令: xcode-select --install
      • 如果已经安装,它会提示。如果需要安装,按照提示操作。
    3. 确保 Xcode 使用了正确的命令行工具路径:
      • 在 Xcode 菜单栏,选择 Xcode -> Preferences -> Locations
      • 检查 Command Line Tools 下拉菜单是否选择了当前安装的 Xcode 版本。

9. 检查项目文件和文件权限 (Project Files and Permissions)

虽然不常见,但项目文件本身损坏或特定文件权限问题有时可能干扰构建过程,包括代码签名。

  • 操作:
    1. 检查项目文件(.xcodeproj.xcworkspace)是否存在于一个你有读写权限的目录下。
    2. 在 Finder 中,右键点击你的项目文件夹,选择 获取信息 (Get Info),检查底部的 共享与权限 (Sharing & Permissions),确保你的用户账户有读写权限。可以尝试点击齿轮图标并选择 应用到包含项... (Apply to enclosed items…)。
    3. 尝试将项目复制到另一个位置(如桌面)并从那里打开和构建。

10. 检查第三方依赖和嵌入式框架 (Third-Party Dependencies and Embedded Frameworks)

如果你的项目使用了 CocoaPods 或手动嵌入了第三方框架,这些框架自身的签名设置可能会与你的主项目发生冲突。

  • 操作:
    1. 对于 CocoaPods 项目 (.xcworkspace),进入 Pods 项目,检查每个 Library 或 Framework Target 的 Build Settings -> Code Signing IdentityProvisioning Profile。确保它们与你的主项目设置兼容,或者至少没有设置为 Manual Signing 并指向一个无效的 Profile。通常,将它们设置为 iOS Developer / iOS DistributionAutomatic 让 Xcode 统一管理是一个好方法。
    2. 对于手动嵌入的框架,确保框架本身已经被正确签名(或者你需要在构建过程中对其进行嵌入式签名)。在你的 Target 的 General -> Frameworks, Libraries, and Embedded Content 中,对于嵌入的项,Embed 选项通常应该设置为 Embed & Sign。确保你的签名配置能够覆盖并正确签发这些嵌入项。

11. 使用命令行工具进行高级调试 (Advanced Debugging with Command Line Tools)

codesign 失败的根本原因是底层的 codesign 命令行工具返回了错误。直接运行这个工具并查看其详细输出通常能提供更具体的错误信息。

  • 操作:
    1. 定位问题文件: 首先,你需要知道是哪个文件签名失败了。在 Xcode 的构建输出中,通常会有更详细的错误信息,指示是哪个二进制文件(例如 .app 包)或嵌入的文件签名失败。查找包含 codesign 命令行的那一行。
    2. 获取构建路径: 构建失败后,不要清理项目。在 Finder 中找到你的构建产物(通常在 Derived Data 文件夹里,例如 DerivedData/YourApp-abcdefg/Build/Products/Debug-iphonesimulator/YourApp.appRelease-iphoneos/YourApp.app)。右键点击 .app 文件,按住 Option 键,选择 将“YourApp.app”的路径拷贝为路径名称 (Copy “YourApp.app” as Pathname)。
    3. 运行 codesign 命令进行验证: 打开 终端。运行以下命令,将 /path/to/YourApp.app 替换为你刚才复制的路径:
      bash
      codesign --verify --verbose=4 /path/to/YourApp.app

      或者使用你的签名身份尝试签名(这更接近 Xcode 做的事情,但要小心,这可能会修改文件,最好在拷贝出来的文件上测试):
      bash
      codesign --force --timestamp --sign "Your Signing Identity Name" /path/to/YourApp.app --entitlements /path/to/YourApp.entitlements

      你需要替换 "Your Signing Identity Name" 为你在钥匙串或 Xcode build settings 中看到的完整证书名称(例如 "Apple Development: Your Name (Team ID)")。/path/to/YourApp.entitlements 是你的项目中的 Entitlements 文件路径(通常是 YourApp.entitlements)。
    4. 分析输出: codesign 命令的输出通常会更详细地说明失败的原因,例如找不到私钥、证书不受信任、Entitlements 文件问题、文件损坏等。仔细阅读这些输出,它可能会直接指出问题的根源。

12. 检查系统或软件冲突

极少数情况下,macOS 系统本身的问题、第三方安全软件、VPN 或其他系统级软件可能会干扰代码签名过程。

  • 操作:
    1. 重启 Mac。
    2. 尝试在安全模式 (Safe Mode) 下构建(这将禁用一些第三方启动项和缓存)。
    3. 暂时禁用或卸载第三方杀毒软件或防火墙,看是否解决问题(请谨慎操作并确保了解风险)。
    4. 确保没有 VPN 或网络代理配置干扰到与 Apple 服务器的通信(在下载证书、Profile 或验证状态时可能需要)。

13. 寻求帮助并提供信息

如果以上步骤都无法解决问题,你可能需要向社区或 Apple Support 寻求帮助。在提问时,提供尽可能多的背景信息至关重要:

  • 你遇到的具体错误信息(完整的 Xcode 构建输出)。
  • 你的 Xcode 版本和 macOS 版本。
  • 你尝试的构建类型(Debug, Release, Archive)。
  • 你正在使用的签名方法(Automatic 或 Manual)。
  • 你在 Apple Developer Portal、钥匙串访问和 Xcode 项目设置中看到的证书和 Provisioning Profile 状态。
  • 你已经尝试过的排查步骤。

预防未来的 codesign failed 错误

  • 使用自动管理签名 (Automatically manage signing): 对于大多数项目,让 Xcode 自动处理证书和 Provisioning Profile 是最简单且最不容易出错的方法。
  • 定期检查证书和 Profile 的有效期: 在 Apple Developer Portal 中设置提醒或定期登录检查。
  • 保持 Xcode 和 macOS 更新: 新版本通常修复了签名相关的 Bug。
  • 维护干净的钥匙串: 定期清理过期或重复的证书和私钥。
  • 理解团队签名: 如果在团队中工作,确保团队成员之间共享必要的 Distribution 证书和私钥(通常通过 .p12 文件),并确保所有人使用相同的 Provisioning Profiles。

总结

command codesign failed with a nonzero exit code 是一个信号,表明应用程序的代码签名过程未能成功完成。尽管错误信息本身不具体,但通过系统地检查证书、私钥、App ID、Provisioning Profile 以及相关的 Xcode 和系统配置,通常可以找到问题的根源。从简单的清理和重新构建开始,逐步检查签名设置、钥匙串、Developer Portal 配置,并利用命令行工具进行深入诊断,是解决这个问题的有效路径。记住,耐心和细致是解决这类配置问题的关键。希望这篇详细的指南能帮助你成功解决 codesign failed 错误,让你的应用程序顺利通过构建和签名流程!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部