阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

构建 iOS 持续集成平台(一)——自动化构建和依赖管理

  • 2013-09-10
  • 本文字数:4291 字

    阅读完需:约 14 分钟

2000 年 Matin Fowler 发表文章 Continuous Integration【1】;2007 年,Paul Duvall, Steve Matyas 和 Andrew Glover 合著的《Continuous Integration:Improving Software Quality and Reducing Risk》 【2】出版发行,该书获得了 2008 年的图灵大奖。持续集成理念经过 10 多年的发展,已经成为了业界的标准。在 Java, Ruby 的世界已经诞生了非常成熟的持续集成工具和实践,而对于 iOS 领域来说,因为技术本身相对比较年轻和苹果与生俱来的封闭思想,在持续集成方面的发展相对滞后一些,但是,随着越来越多的 iOS 开发者的涌入,以及各个互联网巨头加大对 iOS 开发的投入,诞生了一大批非常好用的持续集成工具和服务,本文的目的就是介绍一下如何有效的利用这些类库,服务快速构建一个 iOS 开发环境下的持续集成平台。

自动化构建

在 MartinFowler 的文章 [1] 中关于自动化的构建定义如下:

复制代码
Anyone should be able to bring in a virgin machine, check the sources
out of the repository, issue a single command, and have a running
system on their machine.

因此,自动化构建的的首要前提是有一个支持自动化构建的命令行工具,可以让开发人员可以通过一个简单的命令运行当前项目。

命令行工具

自动化构建的命令行工具比持续集成的概念要诞生得早很多,几十年前,Unix 世界就已经有了 Make,而 Java 世界有 Ant,Maven,以及当前最流行的 Gradle,.Net 世界则有 Nant 和 MSBuild。作为以 GUI 和命令行操作结合的完美性著称的苹果公司来说,当然也不会忘记为自己的封闭的 iOS 系统提供开发环境下命令行编译工具:xcodebuild【3】

xcodebuild

在介绍 xcodebuild 之前,需要先弄清楚一些在 XCode 环境下的一些概念【4】:

  • Workspace:简单来说,Workspace 就是一个容器,在该容器中可以存放多个你创建的 Xcode Project, 以及其他的项目中需要使用到的文件。使用 Workspace 的好处有,1), 扩展项目的可视域,即可以在多个项目之间跳转,重构,一个项目可以使用另一个项目的输出。Workspace 会负责各个 Project 之间提供各种相互依赖的关系 ;2), 多个项目之间共享 Build 目录。
  • Project:指一个项目,该项目会负责管理生成一个或者多个软件产品的全部文件和配置,一个 Project 可以包含多个 Target。
  • Target:一个 Target 是指在一个 Project 中构建的一个产品,它包含了构建该产品的所有文件,以及如何构建该产品的配置。
  • Scheme:一个定义好构建过程的 Target 成为一个 Scheme。可在 Scheme 中定义的 Target 的构建过程有:Build/Run/Test/Profile/Analyze/Archive
  • BuildSetting:配置产品的 Build 设置,比方说,使用哪个 Architectures?使用哪个版本的 SDK?。在 Xcode Project 中,有 Project 级别的 Build Setting,也有 Target 级别的 Build Setting。Build 一个产品时一定是针对某个 Target 的,因此,XCode 中总是优先选择 Target 的 Build Setting,如果 Target 没有配置,则会使用 Project 的 Build Setting。

弄清楚上面的这些概念之后,xcodebuild 就很好理解了,官网上对其作用的描述如下:

复制代码
xcodebuild builds one or more targets contained in an Xcode
project, or builds a scheme contained in an Xcode workspace or
Xcode project.

xcodebuild 就是用了构建产品的命令行工具,其用法可以归结为 3 个部分:

  • 可构建的对象
  • 构建行为
  • 一些其他的辅助命令

可以构建的对象有,默认情况下会运行 project 下的第一个 target:

  • workspace:必须和“-scheme”一起使用,构建该 workspace 下的一个 scheme。
  • project:当根目录下有多个 Project 的时候,必须使用“-project”指定 project,然后会运行
  • target:构建某个 Target
  • scheme:和“-workspace”一起使用,指定构建的 scheme。
  • ……

构建行为包括:

  • clean: 清除 build 目录下的
  • build: 构建
  • test: 测试某个 scheme,必须和"-scheme"一起使用
  • archive: 打包,必须和“-scheme”一起使用
  • ……

辅助命令包括:

  • -sdk:指定构建使用的 SDK
  • -list:列出当前项目下所有的 Target 和 scheme。
  • -version:版本信息
  • ……

关于 xcodebuild 更多详细的命令行请参见: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html

下图是使用 XcodeBuild 运行一个 scheme 的 build 的结果:

了解了 xcodebuild 的用法之后,接下来分析一下 xcodebuild 的主要缺陷:

  • 从上图直接可以得到的感觉,其脚本输出的可读性极差,
  • 只能要么完整的运行一个 target 或者 scheme,要么全部不运行。不能指定运行 Target 中特定的测试。
  • 最令人发指的是,XCode 4 中的 xcodebuild 居然不支持 iOSUnitTest 的 Target【5】,当我尝试运行一个 iOS App 的测试 target 时,得到如下的错误:

对于上面提到的缺陷,Facebook 给出了他们的解决方案:xctool【6】

xctool

xctool 在 其主页直接表明了其目的:

<i>xctool is a replacement for Apple's xcodebuild that makes it easier to build and<br></br> test iOS and Mac products. It's especially helpful for continuous integration.</i>其作用是替代 xcodebuild,目的是让构建和测试更加容易,更好的支持持续集成。从个人感受来看,它的确成功取代了 xcodebuild。但是 xctool 说到底只是对 xcodebuild 的一个封装,只是提供了更加丰富的 build 指令,因此,使用 xctool 的前提是 xcodebuild 已经存在,且能正常工作。

安装

xctool 的安装非常简单,只需要 clone xctool 的 repository 到项目根目录就可以使用, 如果你的机器上安装有 Homebrew,可以通过“brew install xctool”命令直接安装。(注意:使用 xctool 前一定要首先确认 xcodebuild 已安装且能正确工作)。

用法

关于 xctool 的用法就更加人性化了,几乎可以重用所有的 xcodebuild 的指令,配置。只需要注意一下几点:

  • xctool 不支持 target 构建,只能使用 scheme 构建。
  • 支持“-only”指令运行指定的测试。
  • 支持多种格式的 build 报告。

例子:

复制代码
path/to/xctool.sh
-workspaceYourWorkspace.xcworkspace
-schemeYourScheme
test -only SomeTestTarget:SomeTestClass/testSomeMethod

下图是我使用 xctool 运行 test 的效果:

常见问题:

No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=armv7 armv7s).

解决方法:到 Project Setting 中,把"Build Active Architecture Only"设置为 NO

Code Sign error: A valid provisioning profile matching the application’s Identifier ‘dk.muncken.MyApp’ could not be found

解决方法:通过“-sdkiphonesimulator”指定 SDK,从而能够使用符合 iOS 约定的 application Identifier。

依赖管理

选定了命令行工具之后, 接下来可以考虑下依赖管理的问题了。我到现在还记得几年前,刚从 Ant 转到使用 Maven 的那种爽快的感觉。后来,进入 Ruby 的世界,其与生俱来的 Gem 管理系统,也让其依赖管理变得极其简单。 对于 iOS 平台来说,在做项目时,经常需要使用到各种各样的第三方 Framework,这同样需要一个爽快的依赖管理系统,不然的话,各位可以想象一下重复的下载 Framework 文件,拖入各个 Target 的 Build Phase 的 Link Binary With Libraries 中的场景。这种重复的劳动对于“懒惰”的程序员来说,是很难接受的,于是,活跃的社区开发者们提供了这样的一个工具:Cocoapods【7】

Cocoapods 开始于 2011 年 8 月 12 日,经过 2 年多的发展,现在已经超过 2500 次提交,并且持续保持活跃更新,目前已成为 iOS 领域最流行的第三方依赖管理工具。从技术层面来说,其是一个 Ruby Gem,从功能层面来说,其是一个 iOS 平台下的依赖管理工具,为 iOS 项目开发提供了类似于在 Ruby 世界使用 Gem 的依赖管理体验。

安装

前面提到 cocoapods 本质上是一个 Ruby Gem,因此,其使用前提首先是 Ruby 开发环境。庆幸的是,Mac 下都自带 Ruby。这样,只需要简单的 2 条命令,就可以把 cocoapods 安装好:

复制代码
$ [sudo] gem install cocoapods
$ pod setup

用法

cocoapods 的使用方式和使用 Ruby Gem 非常相似,首先需要在项目根目录下创建文件 Podfile, 在 Podfile 中,开发人员只需要按照规则配置好如下内容就好:

  • 项目支持的平台,版本(iOS/OSX)
  • 每个 target 的第三方依赖

例子:

复制代码
platform :ios, '6.0'
inhibit_all_warnings!
xcodeproj `MyProject`
pod 'ObjectiveSugar', '~> 0.5'
target :test do
pod 'OCMock', '~> 2.0.1'
end
post_install do |installer|
installer.project.targets.each do |target|
puts "#{target.name}"
end
end

修改好配置文件之后,只需要简单的使用“pod install”即可安装好所有的依赖,执行该命令之后,在项目跟目录下会出现“.xcworkspace”和“Pods”两个目录:

接下来,开发者需要使用 xcworkspace 打开项目而不是使用 xcodeproject,打开项目之后,在项目目录下除了自己的 project 以外,还可以看到一个叫做 Pods 的项目,该项目会为每一个依赖创建一个 target:

在 Podfile 中,还可以指定依赖专属于某个 Target,

复制代码
target :CocoaPodsTest do
pod 'OCMock', '~> 2.0.1'
pod 'OCHamcrest'
end

如果你记不清楚某个依赖库的名称,可以使用“pod search ”模糊搜索依赖库中的相似库, 另外,如果你想使用的库在 cocoapods 的中央库中找不到,那么,你可以考虑为开源社区做做贡献,把你觉得好用的库添加到中央库中,Cocoapods 的官网上有具体的步骤【8】

原理

CocoaPods 的原理思想基本上来自于 Jonah Williams 的博客“Using Open Source Static Libraries in Xcode 4”【9】, 当使用“pod install”安装文件时,cocoapods 做了如下这些事:

  • 创建或者更新当前的 workspace
  • 创建一个新的项目来存放静态库
  • 把静态库会编译生成的 libpods.a 文件配置到 target 的 build phase 的 link with libraries 中
  • 在依赖项目中创建 *.xcconfig 文件, 指定在编译时的一些参数和依赖
  • 添加一个新的名为“Copy Pods Resource”的 Build Phase,该 build phase 会使用"${SRCROOT}/Pods/Pods-CocoaPodsTest-resources.sh"把 Pods 下的资源文件拷贝到 app bundle 下。

注意事项

当使用 xctool 作为命令行工具构建项目时,使用 cocoapods 管理依赖时,需要做一些额外的配置:

  • 编辑 Scheme,把 pods 静态库项目作为显式的依赖添加到项目的 build 中,
  • 把 pods 依赖项目拖动到本来的项目之上,表示先编译 pods 静态库项目,再编译自己的项目。


感谢张凯峰对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2013-09-10 00:1318654

评论

发布
暂无评论
发现更多内容

App Cleaner & Uninstaller for mac v8.2.5中文激活版下载

影影绰绰一往直前

Dynamic Wallpaper for Mac v17.1中文版下载

影影绰绰一往直前

“云+冷链”新场景,华为云助力前海粤十“物畅其流”

华为云开发者联盟

后端 物联网 华为云 华为云开发者联盟

泰开集团总会计师杜艳春:浅谈设备制造企业数智化之路

用友BIP

企业数智化

“数据要素×” 行动计划要做的几件小事,可都不是小事啊!

用友BIP

数据要素

青否数字人系统源码到底怎么样?

青否数字人

数字人

解锁前端新潜能:如何使用 Rust 锈化前端工具链

京东科技开发者

拥抱梦想夏令营:2024年暑假招生计划发布,助力青少年成长

科技热闻

大模型Chatbots评估新视角:结合定性与程序方法的实践经验

Baihai IDP

程序员 AI LLM 白海科技 Chatbots

XPET宠物游戏系统开发

l8l259l3365

文件备份和同步软件推荐:Syncovery 最新激活版

胖墩儿不胖y

Mac软件 同步备份软件

AlDente Pro for Mac v1.24激活版下载

影影绰绰一往直前

Serato DJ Pro for Mac(专业DJ软件)v3.0.3中文激活版下载

影影绰绰一往直前

“青否数字人”的应用领域!

青否数字人

数字人

Illustrator 2021 for mac v25.4.1中文直装版下载

影影绰绰一往直前

IPQ6000 series IPQ6010 and IPQ6018: Explore infinite possibilities, when will your smart connection evolve?

wallysSK

文心一言 VS 讯飞星火 VS chatgpt (174)-- 算法导论13.3 3题

福大大架构师每日一题

福大大架构师每日一题

【领先实践之离散制造行业】MOM全场景,助力光伏单晶行业降本增效

用友BIP

领先实践 光伏单晶行业

AlDente Pro for Mac v1.24激活版下载

iMac小白

即将取代你的数字人到底是什么?

青否数字人

数字人

Mybatis 拦截器实现单数据源内多数据库切换 | 京东物流技术团队

京东科技开发者

8种超简单的Golang生成随机字符串方式

华为云开发者联盟

开发 华为云 Go 语言 华为云开发者联盟

打造新一代云原生"消息、事件、流"统一消息引擎的融合处理平台

洛神灬殇

RocketMQ 云原生 消息队列 2024年第五篇文章

企业数字化转型是什么?数字化转型的痛点又是什么?怎么转?从哪里转?转了有哪些好处?

天津汇柏科技有限公司

数字化转型峰会

龙蜥副理事长张东:潮蜥共引,繁荣系统软件生态 | 2023龙蜥操作系统大会

OpenAnolis小助手

操作系统 算力 系统软件 龙蜥社区 浪潮信息

XMind for mac (XMind思维导图)v24.01中文版下载

iMac小白

商业智能、数据分析和需求预测在现代零售管理中的关键运用

第七在线

Navicat Premium 15 for Mac v15.0.36中文激活版下载

iMac小白

对话式搜索:基于OpenSearch向量检索版+大模型的实践

百度开发者中心

人工智能 大模型 对话系统

DevSecOps|极狐GitLab IaC 安全扫描,保障云原生安全

极狐GitLab

应对 DevOps 中的技术债务:创新与稳定性的微妙平衡

禅道项目管理

DevOps 自动化测试 技术债务 禅道项目管理

构建iOS持续集成平台(一)——自动化构建和依赖管理_DevOps & 平台工程_刘先宁_InfoQ精选文章