在您的 iOS 项目中使用 Bazel
在开发产品时,有时你需要更聪明地工作,而不是更努力地工作。当你的应用变得庞大而复杂时,尤其如此。正如 Facebook 在其帖子(2017) 中所分享的那样,找到更好的方法来管理应用的构建是明智之举。
这就是 Bazel 的作用所在。
Bazel 是 Google 推出的一款免费工具,可帮助您构建应用。它不仅适合构建大型复杂应用,也适用于小型应用。本文将介绍如何使用 Bazel 更快速、更轻松地构建 iOS 应用。
我们将从基础开始:如何设置 Bazel 并首次使用它。读完本文后,您将能够很好地理解如何使用 Bazel,以及它为何能让您的应用构建过程更加流畅。
动机
看看这些使用 Bazel 构建应用程序的重要公司,在某些情况下,也使用 Bazel 构建后端代码:https://bazel.build/community/users
这些公司大多拥有专门的基础设施团队来负责构建工具。幸运的是,这些团队也为 Bazel 的开源代码做出了贡献,让我们能够充分利用这些专业人士的集体专业知识。
安装 Bazel
首先,请访问https://github.com/bazelbuild/bazel/releases并选择您想要使用的版本。如果您是 Bazel 新手,建议您选择未标记为“预发布”的最新版本。
下载适用于你平台的文件。如果你使用的是基于 Apple Silicon 的电脑,文件名将以 结尾-darwin-arm64
。
接下来,将下载的文件移动到您的 中的某个位置$PATH
,并检查以确认其可运行:
$ bazel --version
bazel *.*.*
对于其他安装方法(包括使用 Homebrew),请访问https://bazel.build/install/os-x
项目设置
现在,我们已准备好创建第一个基于 Bazel 的 iOS 应用。虽然稍后我们会使用 Xcode,但由于我们选择了另一种构建系统,因此需要先手动设置一些基本结构。
为了简化流程,我准备了一个模板:https://github.com/petertechstories/ios-bazel-template
这是项目文件夹的结构:
BUILD
Info.plist
[MyModule]
[Resources]
[Sources]
WORKSPACE
让我们来探究一下这里发生的事情。
让我们分析一下每个文件和文件夹的作用。
WORKSPACE
是我们项目的起点。它列出了构建应用所需的所有工具。该文件的内容乍一看可能很复杂,但在大多数情况下,它是适用于 Apple 平台的标准设置。一个典型示例可以在https://github.com/bazelbuild/rules_apple/releases找到。
BUILD
提供项目的详细描述。可以将其视为一个.xcodeproj
文件,但语法更简单,更易于阅读。对于我们的模板项目来说,它非常简单:
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application")
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
load(
"@rules_xcodeproj//xcodeproj:defs.bzl",
"top_level_targets",
"xcodeproj",
"xcode_provisioning_profile",
)
load("@build_bazel_rules_apple//apple:apple.bzl", "local_provisioning_profile")
swift_library(
name = "Sources",
srcs = [
"Sources/AppDelegate.swift",
],
data = [
"//Resources:Main.storyboard",
],
deps = [
"//MyModule"
]
)
local_provisioning_profile(
name = "xcode_managed_profile",
profile_name = "iOS Team Provisioning Profile: com.test.BazelApp",
tags = ["manual"],
)
ios_application(
name = "App",
app_icons = ["//Resources:PhoneAppIcon.xcassets"],
bundle_id = "com.test.BazelApp",
families = [
"iphone",
"ipad",
],
provisioning_profile = ":xcode_managed_profile",
infoplists = [":Info.plist"],
launch_storyboard = "//Resources:Launch.storyboard",
minimum_os_version = "13.0",
deps = [":Sources"],
visibility = ["//visibility:public"],
)
xcodeproj(
name = "xcodeproj",
project_name = "App",
tags = ["manual"],
top_level_targets = top_level_targets(
labels = [
":App",
],
target_environments = ["device", "simulator"],
),
)
看起来我们像是在查看一系列 Python 函数调用,某种程度上来说也确实如此。Bazel 使用图灵完备的语言来理解项目描述。然而,需要注意的是,即使可以理解,也不建议在此空间执行大量计算。
首先,我们load
从工具集中获取一些定义。在 Bazel 语言中,我们导入并用于定义项目不同部分的组件被称为“规则”。这些load
语句只能引用WORKSPACE
文件中已定义的规则。
接下来,我们定义一个 Swift 模块来保存应用的代码。这可以通过swift_library函数来实现。如果你熟悉 SwiftPM 的语法,你会发现它和 SwiftPM 非常相似,只是它的表达风格更接近 Python。
之后,我们调用ios_application函数来概述我们的应用程序。大多数参数应该很容易理解。这个visibility
参数在大型项目中(分为多个模块)很方便。但对于像我们这样的简单项目,将其公开也是完全没问题的。
该文件的剩余部分BUILD
负责为我们的项目添加 Xcode 支持,因此我们不必在记事本中编写代码。
该MyModule
目录包含模块的定义。将项目划分为独立的功能单元始终是一个明智之举。
最后,Info.plist
其Resources
功能与在 Xcode 中一样。
使用 Xcode
现在项目已经设置好了,我们就可以开始工作了。通常情况下,我们只需双击.xcodeproj
文件即可,但现在没有可用的文件。与许多其他第三方构建系统一样,Bazel.xcodeproj
内部不依赖于文件。但是,它可以生成一个临时项目文件供我们使用。要创建临时项目文件,请运行以下命令:
$ bazel run :xcodeproj
几秒钟后,App.xcodeproj
项目目录中会出现一个文件。双击它即可打开 Xcode。
这让我们回到了熟悉的模式。在 Xcode 中使用基于 Bazel 的项目应该感觉很熟悉。需要记住的关键是,当您想要更改项目结构(例如添加文件或模块)时,需要BUILD
先在文件中进行这些更改,然后重新生成项目。
分发准备
假设我们准备好将应用提交测试或提交到 App Store。如何获取应用存档?通常,我们会使用 Xcode 中的 Archive 操作。有了 Bazel,我们甚至不需要 Xcode 来实现这一点。只需打开终端,运行以下命令:
$ bazel build -c opt :App
在这里,我们指示 Bazel在其 Release 配置(其中代表“优化”)中构建目标:App
,即我们的应用程序(如中所示)。BUILD
opt
构建完成后,您应该看到以下几行:
Target //:App up-to-date:
bazel-bin/App.ipa
这表示构建成功,您可以在 找到 .ipa 文件bazel-bin/App.ipa
。您可以使用应用程序加载器将此文件提交到 App Store,或与朋友或同事共享以进行 AdHoc 安装。
结论
Bazel 是一款功能强大的构建系统,能够显著简化 iOS 应用的构建和分发流程,尤其是在应用日益复杂的情况下。通过将 Bazel 与 Xcode 等常用工具集成,您可以充分利用 Bazel 的灵活性和强大功能,以及 Xcode 的便捷性和熟悉性。虽然可能需要一些时间来适应,但其在效率和可扩展性方面的提升绝对值得您付出努力。
编码愉快!
鏂囩珷鏉ユ簮锛�https://dev.to/petertech/using-bazel-with-your-ios-projects-g7e