从终端定义 Xcode PhoneGap 项目中的方案。

7
我正在编写一个脚本,用于归档 phonegap 项目中的 iOS 部分。该脚本会清除包含该项目的目录,并使用源代码库中的最新代码重新填充它。然后我使用$ phonegap local build ios来构建该项目。但是为了归档该项目,我需要定义其 scheme。我尝试从命令行构建该项目,但是我得到了消息 ** BUILD FAILED **。截至目前为止,我让代码打开 Xcode 项目(这是我找到的唯一定义 scheme 的方法),然后等待 30 秒,等待 Xcode 完成其工作。我的问题是:如何模拟打开 Xcode 或以其他方式从命令行定义 scheme?感谢您提前的任何帮助。
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
13

考虑到 Xcode 方案文档不够详细,而且方案有种神秘的感觉,直到你看到它们如何连接整个构建过程,这是一个完全公正的问题。

基于你正在寻找的解决方法,听起来你需要将方案提升为“共享”状态,以便自动化工具(或其他开发人员)无需先打开您的项目并等待Xcode自动生成默认方案。 这是从试图使其与持续集成系统或针对Xcode 4或Xcode 5项目操作的其他命令行工具一起使用的开发人员的完全正常的要求。 好消息是,有一些Xcode本地的方式可以配置您的项目,而无需诉诸混乱或容易出错的解决方法。

简短版本:

Xcode 默认行为是将方案视为特定于开发人员的设置,而不与其他开发人员或工具共享。 我们需要将项目的方案提升为“共享”并将这些更改提交到您的版本控制系统:

  1. 从您的项目中进行干净的检出。
  2. 导航到 Xcode 菜单:Product > Scheme > Manage Schemes...
  3. 在方案表单的左上角取消勾选“自动创建方案”
  4. 在应该提供给所有开发人员用户和构建系统使用的方案旁边勾选“共享”复选框
  5. 最后将所有项目更改提交回您的版本控制系统。

这将使单个方案在所有使用此项目的开发人员之间共享,而不管他们的 OS X 用户名如何,并使它成为通过xcodebuild或首选构建工具进行未监视的构建的可用方案。

...现在,让我们看一下详细的答案:

在深入研究您直接的问题之前,先了解一些背景信息:

目标: 应用程序、静态库、捆绑包或更一般地说是从源代码、资产、plists、构建设置和其他文件中构建的“产品”。当调用构建操作时,无论是通过Xcode的“运行”按钮还是通过命令行工具xcodebuild,都会生成这个“产品”。

构建配置: 一个由人类可读标签识别的构建设置的命名集合。默认情况下,所有Xcode项目都从“调试”配置开始,该配置生成具有最大透明度的构建目标,帮助开发人员调试应用程序,以及“发布”配置,该配置去除了结果构建的诊断信息并对构建进行了优化,以减小其大小。一些开发人员选择根据团队的需要创建其他配置:“Ad-Hoc”可能会被创建,这样可以更改签名证书和预配文件设置,以便使用 Ad-Hoc 预配文件安装应用程序。"AppStore" 或 "Distribution"是其他常见的自定义构建配置。

Action: 一组相关活动,支持产品开发、诊断和测试的不同阶段。截至撰写本文时,共有六个操作:“构建”、“运行”、“测试”、“分析”、“剖析”和“归档”。作为开发人员,你最常使用的是“构建”和“运行”。 Build Scheme: Xcode 4中管理项目构建目标依赖项和构建并行化选项的发明。每个Scheme允许开发人员为项目生命周期中的每个操作(如“构建”、“运行”等)选择一个构建配置(例如“Debug”或“Release”),以及定义与该特定操作相关的其他行为或选项。例如,Scheme中的“Profile”操作允许开发人员在Instruments.app中剖析代码时选择默认加载哪个诊断工具。 有了这些定义,让我们回到你的问题: 我该如何模拟打开Xcode,或者以其他方式定义Scheme呢? 非常简单:你不需要做任何事情,Xcode有一种原生机制可以使方案可用,我们只需要对方案进行一些微小的重新配置,即可让你开始运行并提交这些更改到版本控制系统中(我将在本答案的其余部分中将其称为“SCM”)。 你面临的问题是Xcode的默认项目行为,当涉及到持久化项目设置时。默认情况下,许多设置都被视为特定于开发人员的设置,并驻留在一组文件中,这些文件映射到打开Xcode项目本身的帐户的特定用户名(稍后会详细说明)。管理这些设置的策略可以概括为“ Xcode设置被认为是‘开发人员专用的,直到明确提升为共享的’”。虽然这在Xcode 4之前的版本中就已存在,但直到Scheme成为调用构建的主要工具,这种方法才会导致开发团队及其持续集成系统出现问题。 随着Scheme的出现,许多早期版本的Xcode中的设置屏幕被整合到一个单独的编辑器窗口中,开发人员可以查看应用程序每个不同操作阶段的最高级别设置:
  • 运行“构建”操作时,可以定义需要构建哪些目标,或者是否应该尝试自动识别构建依赖关系。
  • 对于“运行”操作,选择应使用哪个构建配置以及使用哪个调试器。
  • 对于“测试”操作,选择应使用哪个构建配置以及应使用哪些测试类和测试数据包来测试应用程序行为。
  • ......等等......还有许多其他高级设置,但我会将探索它们留作读者的练习,或者作为提出另一个SO问题的机会!
在每种情况下,这些设置都会引起一系列级联效应 - 选择“调试”配置将尽可能多地保留诊断数据以帮助开发人员追踪问题的源头,这反过来会调用在构建目标中配置的“调试”特定构建设置,这些设置可能还会运行“调试”特定脚本或启用“调试”特定设置。 当然,这些选择需要存储在某个地方,以便它们可以在开发会话之间或在Xcode偶尔崩溃的情况下持久存在。 "开发人员私有直到升级"的行为称雄,这些方案设置被持久化在.xcodeproj文件本身内的“xcuserdata”文件夹中-对于作为.xcworkspace的一部分存在的项目仍然如此。 您可以在自己的项目中看到这一点。首先,确保您正在使用代码的干净版本,然后打开Xcode项目或工作区,以确保我们在遍历您的项目文件时可以看到您个人版本的默认方案: 1.从Xcode切换到Finder,然后导航到项目的检查目录。 2.右键单击您的项目的.xcodeproj文件,并选择“显示包内容”。如果使用工作区,请仍然选择包含您的项目文件而不是.xcworkspace本身的.xcodeproj 3.进入“xcuserdata”。 根据参与该项目的开发人员数量或提交该项目的具有不同用户名的多个不同计算机的数量,极有可能存在一个以上的.xcuserdatad文件夹。 1.选择与您的OS X用户名匹配的文件夹。对于我来说,我的OS X用户名是'bmusial',因此我会选择'bmusial.xcuserdatad'文件夹。 2.进入“xcschemes”文件夹。 3.观察您有两个文件: “[TARGET NAME] .xcscheme”和“xcschemenamagement.plist”,其中包含方案的顺序信息以及是否应该自动生成方案。 啊哈!方案被视为开发人员私有数据,并在项目首次启动时自动生成! 这种意识开始涉及我们需要做的核心-将此方案迁出开发人员特定的xcuserdata文件夹并迁移到所有开发人员共享的位置,禁用自动方案生成以防止其他人未来陷入陷阱,并将这些更改提交回您的SCM。切换回Xcode,让我们重新配置一些东西: 1.导航到Xcode的菜单:产品>方案>管理方案...菜单选项 2.在方案表单的左上角取消选中“自动创建方案” 3.在应向所有开发人员用户和构建系统提供的方案旁边选中“共享”复选框

切换回Finder窗口,并上升两个级别,返回到.xcodeproj文件夹的内容(其中包含“xcuserdata”文件夹)。现在可以看到一个“xcshareddata”文件夹。该文件夹包含了我们刚才分享的方案的“xcschemes”文件夹,并且我们自己的xcuserdata文件夹中的.xcscheme已经消失。我们将您的私有方案提升为共享的、公共的方案,可供所有开发人员和工具使用,即使他们从未直接启动Xcode项目也是如此。

提交我们所做的所有更改(将会有一些新的文件夹和文件!)回到您的SCM,以便下次更新源代码时每个人都能收到相同的配置更改!

下次运行phonegap时,它将按照您指示重置您的checkout,但因为您已经提交了一个方案,它将可以处理构建操作。

尝试一下并告诉我们情况如何,如果您在此过程中遇到任何后续问题或问题,请让我们知道。


惊人的答案。有没有一种方法可以不涉及将PhoneGap生成的工件提交到SCM?我们在这里试图更加精细化。 - Wyatt Barnett
这里没有任何PhoneGap特定的工件 - 这些是您和同事在本地构建,运行,调试和部署时使用的相同构建方案,确保每个贡献者都运行相同的方案配置。至于您的直接问题,不幸的是,在Xcode 5之后,不存在自动生成构建目标方案的命令行机制,因为在打开项目时在Xcode UI中处理此操作。 OPs过程是可行的,但由于需要运行Xcode索引的不确定时间而远非理想。 - Bryan Musial
2
感谢回复 - OP的情况对我们来说甚至都行不通,因为我们是通过SSH运行它,所以xcode永远不会启动。我看到未来可能会采取生成方案文件、隐藏它们并在适当的时候复制它们的方法... - Wyatt Barnett

5
你可能会发现ruby gem xcodeproj 很有用。它可以在不打开xcode的情况下创建方案。 你可以通过这里了解更多信息。 对于phonegap/cordova,请将share_schemes.rb脚本保存在cordova项目的scripts目录中。
#!/usr/bin/env ruby
# share_schemes.rb

require 'xcodeproj'
xcproj = Xcodeproj::Project.open("platforms/ios/MyProject.xcodeproj")
xcproj.recreate_user_schemes
xcproj.save
然后在您的config.xml中添加一个钩子来运行它。
<platform name="ios">
    <hook type="after_platform_add" src="scripts/share_schemes.rb" />
</platform>
现在您不需要打开Xcode进行更改,也不需要检查平台文件夹中的任何更改。每次添加iOS平台时,此脚本将创建您的方案。

在这里不需要检查平台文件夹是一个胜利。 - Simon Prickett
这很棒,但是在不向项目添加对RubyGems包管理器的依赖的情况下,在您的Cordova项目中如何使用这个gem呢?我想任何使用Cordova的人都将已经在使用npm,不会想通过添加另一个包管理器来使事情更加复杂。我想你可以将gem检入源代码控制吧? - Barjavel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,