Xcode构建阶段和环境
如何教Xcode尊重环境。
如果您曾经做过iOS开发,那么您肯定会使用Xcode Build Phases。 构建阶段可以执行的任务之一就是运行Shell脚本,这是您可能会遇到的一个特殊问题……
问题在于,在Xcode构建阶段中运行的Shell脚本无法获取用户Shell配置文件。
尝试将以下内容放入您的外壳配置文件中:
Shell配置文件中的任何消息都不会显示。
原因是从Xcode构建阶段运行的外壳是非交互式外壳。
它实际上不是错误,而是预期的行为,但这可能会使您感到困惑。
这个例子
举例来说,假设您有一个要在Xcode构建阶段中运行的Ruby脚本。
该脚本恰好使用了2.5.x Ruby语言功能,而这些功能在2.3.x中不可用。
您还使用RVM来安装和使用版本2.5.x。
现在,将ruby --version
添加到构建阶段,构建项目并检查输出。 在Mojave OS X上,输出为2.3.7
,这是系统Ruby版本。
通常在外壳程序配置文件中定义的RVM环境都没有加载到脚本中。
解决此问题的一种方法是使用登录外壳程序。
就像在构建阶段的“ Shell”参数中添加-l
一样简单,例如/bin/sh -l
。 但是,它不适用于Bourne shell(sh)。
但随后它将适用于再次使用Bourne的shell(bash),因此您可以将“ Shell”参数更改为/bin/bash -l
。
您现在将在日志中看到以下内容:
加载〜/ .bash_profile
那行得通,但并不理想。 如果团队中有很多开发人员,他们的~/.bash_profile
可能会发生各种各样的事情,而您不一定要在Xcode构建阶段中运行它们。 您只需要加载RVM环境,别无其他。
其他开发人员也可以使用zsh或其他类型的shell。
构建阶段脚本
解决此问题的另一种方法是仅在每个构建阶段脚本中提供重要的内容。
例如,要使用RVM在非交互式shell中加载Ruby版本,可以使用以下代码:
尽管此方法可能需要更多工作,但由于以下几个原因,它仍然是更好的方法:
- 您只加载运行脚本所需的内容,而不加载用户的shell配置文件中的所有内容
- 根据项目的
.ruby-version
文件选择Ruby版本,而采用登录Shell方法时,将加载为RVM全局设置的默认Ruby版本,并且您必须运行额外的代码才能切换到正确的版本
提示
有关使用Shell脚本构建阶段的一些技巧。
脚本错误
如果shell脚本返回的错误代码不是0
,例如/bin/sh -e
,则构建阶段的Add -e
标志将失败。
管理构建阶段脚本
使用以下约定来管理构建阶段脚本:
每个构建阶段必须有一个Shell脚本。
例如,将所有构建阶段脚本放在名为build-phases
的目录中,例如build-phases/codecheck.sh
, build-phases/codegen.sh
等。
现在,在Xcode构建阶段用户界面中,而不是具有内联脚本,您将具有以下功能:
您甚至可以在构建阶段脚本内移动Ruby环境加载线,以将其压缩为单一格式。
由于多种原因,这是一种更好的方法:
- 如果您修改了构建阶段脚本,则与必须将其作为
pbxproj
UTF-8 ASCII plist文件更改(包括所有换行符和其他内容)的一部分进行查看时相比,在拉取请求中将其作为.sh
文件的更改进行查看要容易得多。转义序列添加到混合中。 - 您可以在Xcode之外重用构建阶段脚本,例如,如果您尝试使用替代的构建系统(例如Buck)。