To continue the previous part of this series, this part I’ll talk about how to config a sample iOS project using Bazel.
To install Bazel on macOS, too simple. You can go to this link
To simplest, I will use brew to install bazel.
brew install bazel
After install success, you can verify by running the below command
2. Build config structure
Bazel will use BUILD files to config build for the module in your project. Besides, bazel also use
.bazel file to config the project.
2.1 WORKSPACE file
WORKSPACE is a configuration file used to pull build rules dependencies. It is placed at the root directory.
This is an example of the WORKSPACE file.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "build_bazel_rules_apple", sha256 = "c84962b64d9ae4472adfb01ec2cf1aa73cb2ee8308242add55fa7cc38602d882", url = "https://github.com/bazelbuild/rules_apple/releases/download/0.31.2/rules_apple.0.31.2.tar.gz", ) load( "@build_bazel_rules_apple//apple:repositories.bzl", "apple_rules_dependencies", ) apple_rules_dependencies() load( "@build_bazel_rules_swift//swift:repositories.bzl", "swift_rules_dependencies", ) swift_rules_dependencies() load( "@build_bazel_rules_swift//swift:extras.bzl", "swift_rules_extra_dependencies", ) swift_rules_extra_dependencies() load( "@build_bazel_apple_support//lib:repositories.bzl", "apple_support_dependencies", ) apple_support_dependencies()
The WORKSPACE will perform actions follow below steps:
- Use load function to get
http_archivefunction from Bazel build-in rules.
http_archivefunction to pull
- Use load to get
rules_applethat we did get from the previous step.
apple_rules_dependenciesto pull others dependencies of
rules_swiftis an example in list dependency of
- Continue use load and call other functions to pull dependencies of other tools like
.bazelrc is configuration file placed in root directory like WORKSPACE file. It is used to configure parameters that will be passed to bazel when the Bazel command is called.
Here is an example configuration file to config gell DSYM for debugging purposes and specific version and type of simulator device.
build --apple_platform_type=ios build --apple_generate_dsym build --ios_simulator_device="iPhone 12" build --ios_simulator_version=14.5
Continue WORKSPACE and .bazelrc, we need the file name is BUILD at the root of modules that we need to build. It will create a package at the place of the BUILD file.
These BUILD files will contain
load and call rules build-in
rules_swift to config build target. Build target in BUILD file can depend on other build targets in other files by config
For demo purposes, I will use a project placed at start folder: https://github.com/vikage/DemoProjectBazel
First, I will write
.bazelrc first with contents is same as the above example.
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") load("@rules_cc//cc:defs.bzl", "objc_library") swift_library( name = "TLLogging", module_name = "TLLogging", srcs = glob([ "*.swift", ]), deps = [ ":TLLoggingHelper", ], visibility = ["//visibility:public"], ) objc_library( name = "TLLoggingHelper", module_name = "TLLoggingHelper", srcs = glob([ "*.m", ]), hdrs = glob([ "*.h", ]), )
visibility is a field that shows the visible state of that build target. It will allow other build targets in other packages can see that build target or not. In the above config, I use public means all packages can see that build target.
deps is a field that defines dependencies of the current build target.
To learn more about other fields, please find out in the docs of
rules_apple or Bazel website.
BUILD for Assets
To build for xcassets, we will use rule named
filegroup. This is the build-in rule, so we don’t need to load this rule.
filegroup( name = "Assets", srcs = glob(["Assets.xcassets/**"]), visibility = ["//visibility:public"], )
BUILD for App_Classes and ios_app
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application") load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") swift_library( name = "App_Classes", srcs = glob([ "*.swift" ]), data = [ "//Assets:Assets", "Base.lproj/Main.storyboard", "Base.lproj/LaunchScreen.storyboard", ], deps = [ "//Lib/Logging:TLLogging" ] ) ios_application( name = "ios_app", bundle_id = "com.thanhvu.test", infoplists = ["Info.plist"], families = ["iphone"], minimum_os_version = "12.0", deps = [ ":App_Classes", ] )
Look at the
App_Classes target, Assets are embedded over the data field.
3. Build project by command line
To build the project by command line. first, we need to change the directory to the project in the command line window. And call blow command.
bazel build //App:ios_app
To run in the simulator, you can run the below command.
bazel run //App:ios_app
So we have completed a demo iOS app that uses Bazel as a build system. Next, I will talk about the challenges that I face off when migrating my project to Bazel.
Demo project: https://github.com/vikage/DemoProjectBazel