Bazel 教程:构建 iOS 应用

本教程介绍如何使用 Bazel 构建简单的 iOS 应用。

学习内容

在本教程中,您将学习如何:

  • 安装 Bazel 和 Xcode,并下载示例项目,以设置环境
  • 设置一个包含应用源代码的 Bazel 工作区,以及一个用于标识工作区目录顶层的 WORKSPACE 文件
  • 更新 WORKSPACE 文件以包含对所需外部依赖项的引用
  • 创建 BUILD 文件
  • 运行 Bazel 为模拟器和 iOS 设备构建应用
  • 在模拟器中和 iOS 设备上运行应用

设置您的环境

首先,请安装 Bazel 和 Xcode,并获取示例项目。

安装 Bazel

按照安装说明安装 Bazel 及其依赖项。

安装 Xcode

下载并安装 Xcode。 Xcode 包含 Bazel 构建 Apple 应用所需的编译器、SDK 和其他工具。

获取示例项目

您还需要从 GitHub 获取本教程的示例项目。GitHub 代码库有两个分支:source-onlymainsource-only 分支仅包含项目的源文件。在本教程中,您将使用此分支中的文件。main 分支包含源文件以及完成后的 Bazel WORKSPACEBUILD 文件。完成教程步骤后,您可以使用此分支中的文件来检查工作。

在命令行中输入以下命令,以获取 source-only 分支中的文件:

cd $HOME
git clone -b source-only https://github.com/bazelbuild/examples

git clone 命令会创建一个名为 $HOME/examples/ 的目录。此目录中包含 Bazel 的几个示例项目。本教程的项目文件位于 $HOME/examples/tutorial/ios-app

设置工作区

工作区是一个目录,其中包含一个或多个软件项目的源文件,以及 WORKSPACE 文件和 BUILD 文件(后者包含 Bazel 用于构建软件的说明)。工作区还可能包含指向输出目录的符号链接。

工作区目录可以位于文件系统中的任何位置,并由其根目录下存在 WORKSPACE 文件来表示。在本教程中,您的工作区目录为 $HOME/examples/tutorial/,其中包含您在上一步中从 GitHub 代码库克隆的示例项目文件。

为方便起见,请立即设置 $WORKSPACE 环境变量以引用您的工作区目录。在命令行中,输入:

export WORKSPACE=$HOME/examples/tutorial

创建 WORKSPACE 文件

每个工作区的顶层工作区目录中都必须有一个名为 WORKSPACE 的文本文件。此文件可能为空,也可能包含对构建软件所需的外部依赖项的引用。

现在,您将创建一个空的 WORKSPACE 文件,该文件仅用于识别工作区目录。在后续步骤中,您将更新该文件以添加外部依赖项信息。

在命令行中输入以下内容:

touch $WORKSPACE/WORKSPACE
open -a Xcode $WORKSPACE/WORKSPACE

这将创建并打开空的 WORKSPACE 文件。

更新 WORKSPACE 文件

如需为 Apple 设备构建应用,Bazel 需要从其 GitHub 代码库中拉取最新的 Apple 构建规则。如需启用此功能,请将以下 git_repository 规则添加到 WORKSPACE 文件中:

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

git_repository(
    name = "build_bazel_rules_apple",
    remote = "https://github.com/bazelbuild/rules_apple.git",
    tag = "0.19.0",
)

git_repository(
    name = "build_bazel_rules_swift",
    remote = "https://github.com/bazelbuild/rules_swift.git",
    tag = "0.13.0",
)

git_repository(
    name = "build_bazel_apple_support",
    remote = "https://github.com/bazelbuild/apple_support.git",
    tag = "0.7.2",
)

git_repository(
    name = "bazel_skylib",
    remote = "https://github.com/bazelbuild/bazel-skylib.git",
    tag = "0.9.0",
)

查看源文件

查看应用的源文件(位于 $WORKSPACE/ios-app/UrlGet)。同样,您现在只是查看这些文件,熟悉应用的结构。您无需修改任何源文件即可完成本教程。

创建 BUILD 文件

在命令行提示符处,打开一个新的 BUILD 文件进行修改:

touch $WORKSPACE/ios-app/BUILD
open -a Xcode $WORKSPACE/ios-app/BUILD

添加规则 load 语句

为了构建 iOS 目标,每当构建运行时,Bazel 都需要从其 GitHub 代码库加载构建规则。如需将这些规则用于您的项目,请将以下 load 语句添加到 BUILD 文件的开头:

load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application")

您只需加载 ios_application 规则,因为 objc_library 规则内置于 Bazel 软件包中。

添加 objc_library 规则

Bazel 提供了一些构建规则,您可以使用这些规则为 iOS 平台构建应用。在本教程中,您将首先使用 objc_library 规则告知 Bazel 如何根据应用源代码和 Xib 文件构建静态库。然后,您将使用 ios_application 规则来指示它如何构建应用二进制文件和 .ipa 软件包。

请将以下内容添加到 BUILD 文件:

objc_library(
    name = "UrlGetClasses",
    srcs = [
         "UrlGet/AppDelegate.m",
         "UrlGet/UrlGetViewController.m",
         "UrlGet/main.m",
    ],
    hdrs = glob(["UrlGet/*.h"]),
    data = ["UrlGet/UrlGetViewController.xib"],
)

记下规则的名称 UrlGetClasses

添加 ios_application 规则

ios_application 规则会构建应用二进制文件并创建 .ipa 软件包文件。

请将以下内容添加到 BUILD 文件:

ios_application(
    name = "ios-app",
    bundle_id = "Google.UrlGet",
    families = [
        "iphone",
        "ipad",
    ],
    minimum_os_version = "9.0",
    infoplists = [":UrlGet/UrlGet-Info.plist"],
    visibility = ["//visibility:public"],
    deps = [":UrlGetClasses"],
)

请注意 deps 属性如何引用您添加到上述 BUILD 文件中的 UrlGetClasses 规则的输出。

现在,保存并关闭该文件。您可以将 BUILD 文件与 GitHub 代码库 main 分支中的完整示例进行比较。

构建和部署应用

现在,您可以构建应用并将其部署到模拟器和 iOS 设备了。

构建的应用位于 $WORKSPACE/bazel-bin 目录中。

为本教程完成的 WORKSPACEBUILD 文件位于 GitHub 代码库的主分支中。您可以将工作内容与已完成的文件进行比较,以获取更多帮助或进行问题排查。

为模拟器构建应用

确保当前的工作目录位于 Bazel 工作区内:

cd $WORKSPACE

现在,输入以下命令来构建示例应用:

bazel build //ios-app:ios-app

Bazel 会启动并构建示例应用。在构建流程中,其输出将如下所示:

INFO: Found 1 target...
Target //ios-app:ios-app up-to-date:
  bazel-bin/ios-app/ios-app.ipa
INFO: Elapsed time: 0.565s, Critical Path: 0.44s

查找构建输出

.ipa 文件和其他输出位于 $WORKSPACE/bazel-bin/ios-app 目录下。

在模拟器中运行和调试应用

现在,您可以使用 iOS 模拟器从 Xcode 运行应用。首先,使用 Tulsi 生成一个 Xcode 项目

然后,在 Xcode 中打开项目,选择一个 iOS 模拟器作为运行时方案,并点击 Run

为设备构建应用

为了构建应用以便在 iOS 设备上安装和启动,Bazel 需要适用于该设备模型的预配配置文件。执行以下操作:

  1. 转到您的 Apple 开发者帐号,然后为您的设备下载相应的预配配置文件。如需了解详情,请参阅 Apple 的文档

  2. 将您的个人资料移至 $WORKSPACE

  3. (可选)将您的个人资料添加到 .gitignore 文件中。

  4. 将以下代码行添加到 BUILD 文件的 ios_application 目标中:

    provisioning_profile = "<your_profile_name>.mobileprovision",
    

现在,针对您的设备构建应用:

bazel build //ios-app:ios-app --ios_multi_cpus=armv7,arm64

这会将应用构建为胖二进制文件。如需针对特定设备架构进行构建,请在构建选项中指定相应架构。

如需针对特定 Xcode 版本进行构建,请使用 --xcode_version 选项。如需针对特定 SDK 版本进行构建,请使用 --ios_sdk_version 选项。在大多数情况下,使用 --xcode_version 选项就足够了。

如需指定所需的最低 iOS 版本,请将 minimum_os_version 参数添加到 BUILD 文件中的 ios_application 构建规则中。

您也可以使用 Tulsi 通过 GUI(而不是命令行)构建应用。

在设备上安装应用

如需在设备上安装应用,最简单的方法是启动 Xcode 并使用 Windows > Devices 命令。从左侧列表中选择插入的设备,然后点击“已安装的应用”下的添加(加号)按钮并选择您构建的 .ipa 文件,以添加应用。

如果您的应用未能在您的设备上安装,请务必在 BUILD 文件中指定正确的预配配置文件(上一部分中的第 4 步)。

如果您的应用无法启动,请确保您的设备已加入预配配置文件。Xcode 中 Devices 屏幕上的 View Device Logs 按钮可能会提供有关问题的更多信息。

深入阅读

如需了解详情,请参阅 GitHub 代码库的主分支