Slide 1

Slide 1 text

2019 DevDay Faster iOS Builds With Bazel > TruongThi Doan > LINE App Dev 4 Software Engineer

Slide 2

Slide 2 text

Agenda > Problems > Challenges > Room for Improvement

Slide 3

Slide 3 text

Overview LINE iOS Modules 224 Lines of Code 1.4m Source Files 8.4k

Slide 4

Slide 4 text

Problems > “Works on my machine” problems > Release builds must be full clean builds > Long build times as project grows

Slide 5

Slide 5 text

https://bazel.build Bazel Growing LINE for iOS • Thursday, 14:30 > Fast & Reproducible > Remote Caching > Extensible

Slide 6

Slide 6 text

Incremental Adoption Prebuilt Static Frameworks Ƃ load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") swift_library( name = "LineServices", srcs = glob(["*.swift"]), deps = [":Thrift"], )

Slide 7

Slide 7 text

Incremental Adoption Prebuilt Static Frameworks Ƃ load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") load("@build_bazel_rules_apple//apple:ios.bzl", "ios_static_framework") swift_library( name = "LineServices", srcs = glob(["*.swift"]), deps = [":Thrift"], ) ios_static_framework( name = "LineServicesFramework", bundle_name = "LineServices", minimum_os_version = "11.0", deps = [":LineServices"], )

Slide 8

Slide 8 text

> Swift dependencies Carthage Git Submodules > Dependencies that aren’t directly related to iOS CocoaPods > Objective-C dependencies Dependencies

Slide 9

Slide 9 text

> Pod2BUILD > Manually writing BUILD files Objective-C static frameworks Swift static frameworks > .swiftdoc & .swiftmodule weren’t bundled > Post-processing ios_static_framework() Cont’d Dependencies

Slide 10

Slide 10 text

Mixed Objective-C & Swift Frameworks

Slide 11

Slide 11 text

Mixed Targets > Generating module map from Obj-C headers Ƃ native.genrule( name = "objc_module_map", srcs = hdrs, outs = ["module.modulemap"], cmd = """ echo "module {} {{" >> $@ for src in $(SRCS); do echo " header \\"$${{src}}\\"" >> $@ done echo "}}" >> $@ """.format(module_name), )

Slide 12

Slide 12 text

Mixed Targets > Generating module map from Obj-C headers > swift_library() with all Swift source files Ƃ native.swift_library( name = "LineServices", module_name = "LineServices", srcs = native.glob(["*.swift"]), copts = [ "-import-underlying-module", "-Xfrontend", "-enable-objc-interop", "-Xcc", "-fmodule-map-file=$(execpath :module.modulemap)", ], swiftc_inputs = hdrs + ["module.modulemap"], features = ["swift.no_generated_module_map"], )

Slide 13

Slide 13 text

Mixed Targets > Generating module map from Obj-C headers > swift_library() with all Swift source files > objc_library() with all Obj-C source files Ƃ native.objc_library( name = "LineServices_umbrella", module_name = "LineServices", hdrs = hdrs, srcs = native.glob(["*.m"]), deps =[":LineServices"], )

Slide 14

Slide 14 text

Ƃ Local Development > Generating Xcode project from BUILD files with Tulsi > Breakpoints work by overriding an LLDB setting # ~/.lldbinit settings set target.source-map "./" "~/line-ios/"

Slide 15

Slide 15 text

Remote Caching > Any HTTP/1.1 backend > Google Cloud Storage > bazel-remote • github.com/buchgr/bazel-remote > Don’t use Bazel 1.1 Ƃ

Slide 16

Slide 16 text

Clean Build Times No Cache With Cache 0෼ 6෼ 12෼ 18෼ 24෼ 30෼ Bazel Xcode

Slide 17

Slide 17 text

Room for Improvement > Developer experience > Improving shared remote cache > Swift Package Manager support

Slide 18

Slide 18 text

Thank You