Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Bazel

 Bazel

Talk was presented at Droidcon NYC 2019.

Why Bazel worth taking a look at and how it can help you scale development of your Android and iOS apps while (mostly) outperforming standard tooling like Gradle and xcodebuild.

In the talk we'll discuss following major topics:

- Multi-module setup vs build system
- Why Gradle is slow and how they're fixing it
- Why Gradle is fast and how they're fixing it
- ABI vs API vs implementation
- Compile avoidance
- Remote caching
- Remote execution
- Build configuration DSL (Groovy/Kotlin vs Starlark)
- IDE support
- CI/CD support
- Testing

Artem Zinnatullin

August 27, 2019
Tweet

More Decks by Artem Zinnatullin

Other Decks in Programming

Transcript

  1. Build System Use Cases -Resolve dependencies -Build (compile, process resources,

    etc) -Run apps/tests -Integrate with IDE (modules, actions, etc)
  2. Build System Use Cases -Resolve dependencies -Build (compile, process resources,

    etc) -Run apps/tests -Integrate with IDE (modules, actions, etc) -Integrate with scripts & CI
  3. Build System Use Cases -Resolve dependencies -Build (compile, process resources,

    etc) -Run apps/tests -Integrate with IDE (modules, actions, etc) -Integrate with scripts & CI -Plugins/Extensions API
  4. Build System Use Cases -Resolve dependencies -Build (compile, process resources,

    etc) -Run apps/tests -Integrate with IDE (modules, actions, etc) -Integrate with scripts & CI -Plugins/Extensions API -etc
  5. Design of Bazel: Configuration java_library( name = "a", srcs =

    [ "A.java" ], deps = [ "//:b" ], ) java_library( name = "b", srcs = [ "B.java" ], ) Bazel BUILD file
  6. Design of Bazel: Configuration ‣Static Markdown Language -XML -JSON -YAML

    (no God please no) -TOML -etc ‣Programming Language
  7. Design of Bazel: Configuration ‣Static Markdown Language -XML -JSON -YAML

    (no God please no) -TOML -etc ‣Programming Language -Dynamically Typed -Statically Typed -etc
  8. Design of Bazel: Configuration <project xmlns="…" xmlns:xsi="…" xsi:schemaLocation="…"> <modelVersion>4.0.0</modelVersion> <groupId>com.lyft.dagger1</groupId>

    <artifactId>dagger-parent</artifactId> <packaging>pom</packaging> <version>1.3.0</version> <name>Dagger (Parent)</name> <description>A fast dependency injector for Android and Java.</description> <url>https://github.com/square/dagger</url> <modules> <module>compiler</module> <module>core</module> </modules> Maven pom.xml
  9. Design of Bazel: Configuration apply plugin: 'com.android.library' apply plugin: 'kotlin-android'

    android { defaultConfig { minSdkVersion versions.minSdk compileSdkVersion versions.compileSdk buildToolsVersion versions.buildTools } } dependencies { api project(':redom:api') api androidXLibraries.recyclerView } Gradle build.gradle
  10. Design of Bazel: Configuration java_library( name = "lib", srcs =

    glob(["src/main/java/**/*.java"]), deps = [ "//:b", ] ) java_test( name = "test", srcs = glob(["src/test/java/**/*.java"]), deps = [ ":lib", ] ) Bazel BUILD file
  11. Design of Bazel: Configuration apply plugin: 'java-library' apply plugin: 'kotlin'

    // yoooooo don't do this version = Calendar.instance.get(Calendar.DAY_OF_WEEK) == 2 ? System.currentTimeMillis() : new Random().nextInt()
  12. Design of Bazel: Configuration ‣Gradle: Groovy ‣Groovy syntax and dynamic

    type system () ‣Unlimited mutability ‣Unlimited IO
  13. Design of Bazel: Configuration ‣Gradle: Groovy ‣Groovy syntax and dynamic

    type system () ‣Unlimited mutability ‣Unlimited IO ‣Full JDK stdlib
  14. Design of Bazel: Configuration ‣Gradle: Groovy ‣Groovy syntax and dynamic

    type system () ‣Unlimited mutability ‣Unlimited IO ‣Full JDK stdlib ‣Can write Java in Groovy
  15. Design of Bazel: Configuration ‣Gradle: Kotlin ‣Kotlin syntax and static

    type system () ‣Unlimited mutability ‣Unlimited IO
  16. Design of Bazel: Configuration ‣Gradle: Kotlin ‣Kotlin syntax and static

    type system () ‣Unlimited mutability ‣Unlimited IO ‣Full JDK stdlib
  17. Design of Bazel: Configuration See “Fundamental Design Issues of Gradle

    Build System” https:!//artemzin.com/blog/fundamental-design-issues-of-gradle-build-system/ *includes proposals to solve the issues
  18. Design of Bazel: Configuration ‣Bazel Starlark Evaluation Model -Loading Phase

    -Read BUILD and .bzl files required for given build -Bazel targets are directly mapped to file paths in the project https:"//docs.bazel.build/versions/master/skylark/concepts.html#evaluation-model
  19. Design of Bazel: Configuration ‣Bazel Starlark Evaluation Model -Loading Phase

    -Read BUILD and .bzl files required for given build -Bazel targets are directly mapped to file paths in the project -Analysis Phase -Rules are executed -Rules instantiate actual Actions -Action graph is composed and validated https:"//docs.bazel.build/versions/master/skylark/concepts.html#evaluation-model
  20. Design of Bazel: Configuration ‣Bazel Starlark Evaluation Model -Loading Phase

    -Read BUILD and .bzl files required for given build -Bazel targets are directly mapped to file paths in the project -Analysis Phase -Rules are executed -Rules instantiate actual Actions -Action graph is composed and validated -Execution Phase -Action graph is executed https:"//docs.bazel.build/versions/master/skylark/concepts.html#evaluation-model
  21. Design of Bazel: Configuration ‣Starlark ‣Python 3 syntax and dynamic

    type system () https:"//docs.bazel.build/versions/master/skylark/language.html
  22. Design of Bazel: Configuration ‣Starlark ‣Python 3 syntax and dynamic

    type system () ‣Custom runtime https:"//docs.bazel.build/versions/master/skylark/language.html
  23. Design of Bazel: Configuration ‣Starlark ‣Python 3 syntax and dynamic

    type system () ‣Custom runtime ‣Custom stdlib https:"//docs.bazel.build/versions/master/skylark/language.html
  24. Design of Bazel: Configuration ‣Starlark ‣Python 3 syntax and dynamic

    type system () ‣Custom runtime ‣Custom stdlib ‣Extremely limited mutability https:"//docs.bazel.build/versions/master/skylark/language.html
  25. Design of Bazel: Configuration ‣Starlark ‣Python 3 syntax and dynamic

    type system () ‣Custom runtime ‣Custom stdlib ‣Extremely limited mutability ‣No IO https:"//docs.bazel.build/versions/master/skylark/language.html
  26. Design of Bazel: Configuration ‣Starlark ‣Python 3 syntax and dynamic

    type system () ‣Custom runtime ‣Custom stdlib ‣Extremely limited mutability ‣No IO ‣Bazel provides build & IO specific APIs https:"//docs.bazel.build/versions/master/skylark/language.html
  27. Design of Bazel: Configuration ‣Starlark ‣Python 3 syntax and dynamic

    type system () ‣Custom runtime ‣Custom stdlib ‣Extremely limited mutability ‣No IO ‣Bazel provides build & IO specific APIs ‣Can be used outside of Bazel! https:"//docs.bazel.build/versions/master/skylark/language.html
  28. Design of Bazel: Configuration java_library( name = "lib", srcs =

    glob(["src/main/java/**/*.java"]), deps = [ "//:b", ] ) java_test( name = "test", srcs = glob(["src/test/java/**/*.java"]), deps = [ ":lib", ] ) Bazel BUILD file
  29. Design of Bazel: Configuration java_library( name = "lib", srcs =

    glob(["src/main/java/**/*.java"]), deps = [ "//:b", ] ) java_test( name = "test", srcs = glob(["src/test/java/**/*.java"]), deps = [ ":lib", ] ) Bazel BUILD file Target with name “lib”
  30. Design of Bazel: Configuration ‣Starlark -Functions - Rules - Macros

    https:"//docs.bazel.build/versions/master/skylark/language.html
  31. Design of Bazel: Configuration ‣Starlark -Functions - Rules - Macros

    -Variables - Mutable within a “context” - Frozen once context has been evaluated https:"//docs.bazel.build/versions/master/skylark/language.html
  32. Design of Bazel: Configuration ‣Rule -Function that performs reproducible IO

    for given Inputs https:"//docs.bazel.build/versions/master/skylark/rules.html
  33. Design of Bazel: Configuration ‣Rule -Function that performs reproducible IO

    for given Inputs -Declares set of public and private attributes (parameters) https:"//docs.bazel.build/versions/master/skylark/rules.html
  34. Design of Bazel: Configuration ‣Rule -Function that performs reproducible IO

    for given Inputs -Declares set of public and private attributes (parameters) -Examples: kotlin_library, java_test, etc https:"//docs.bazel.build/versions/master/skylark/rules.html
  35. Design of Bazel: Configuration ‣Rule -Function that performs reproducible IO

    for given Inputs -Declares set of public and private attributes (parameters) -Examples: kotlin_library, java_test, etc -Cannot perform IO during configuration/analysis https:"//docs.bazel.build/versions/master/skylark/rules.html
  36. Design of Bazel: Configuration ‣Rule -Function that performs reproducible IO

    for given Inputs -Declares set of public and private attributes (parameters) -Examples: kotlin_library, java_test, etc -Cannot perform IO during configuration/analysis -Declares list of actions to perform IO during execution https:"//docs.bazel.build/versions/master/skylark/rules.html
  37. Design of Bazel: Configuration ‣Rule -Function that performs reproducible IO

    for given Inputs -Declares set of public and private attributes (parameters) -Examples: kotlin_library, java_test, etc -Cannot perform IO during configuration/analysis -Declares list of actions to perform IO during execution -Exposes Provider(s) — rule’s public API for other rules https:"//docs.bazel.build/versions/master/skylark/rules.html
  38. Design of Bazel: Configuration android_instrumentation_test = rule( attrs = attrs.add(

    ANDROID_INSTRUMENTATION_TEST_ATTRS, ADDON_ATTRS ), fragments = ["android"], implementation = _impl, outputs = _outputs, test = True, ) https:"//github.com/bazelbuild/rules_android
  39. Design of Bazel: Configuration https:"//github.com/bazelbuild/rules_android def _impl(ctx): # Main entry

    point into the Android test runner. test_runner = get_test_runner(ctx) ……… # TODO(str): remove after android_test migration if ctx.attr._android_test_migration: # Test APK is a predeclared output on android_test ctx.actions.run_shell( inputs = [ctx.attr.test_app[ApkInfo].signed_apk], outputs = [ctx.outputs.test_app], command = "cp %s %s" % (ctx.attr.test_app[ApkInfo].signed_apk.path, ctx.outputs.test_app.path), ) runfiles = runfiles.merge(ctx.runfiles(files = [ctx.outputs.test_app])) apks_to_install = []
  40. Design of Bazel: Configuration ‣Macro -Can instantiate rule(s) -Useful for

    code reuse, composing logic, default values https:"//docs.bazel.build/versions/master/skylark/macros.html
  41. Design of Bazel: Configuration ‣Macro -Can instantiate rule(s) -Useful for

    code reuse, composing logic, default values -Present only during Loading phase https:"//docs.bazel.build/versions/master/skylark/macros.html
  42. Design of Bazel: Configuration ‣Macro -Can instantiate rule(s) -Useful for

    code reuse, composing logic, default values -Present only during Loading phase -Examples: lyft_kotlin_library, lyft_android_binary, etc https:"//docs.bazel.build/versions/master/skylark/macros.html
  43. Design of Bazel: Configuration def lyft_android_library(**kwargs): if kwargs.get("language") == "kotlin":

    _apply_detekt(**kwargs) _apply_pmd(**kwargs) kwargs = _apply_error_prone(**kwargs)
  44. Design of Bazel: Configuration def lyft_android_library(**kwargs): if kwargs.get("language") == "kotlin":

    _apply_detekt(**kwargs) _apply_pmd(**kwargs) kwargs = _apply_error_prone(**kwargs) kwargs = _apply_java_null_pkg_info_gen( **kwargs )
  45. Design of Bazel: Configuration def lyft_android_library(**kwargs): if kwargs.get("language") == "kotlin":

    _apply_detekt(**kwargs) _apply_pmd(**kwargs) kwargs = _apply_error_prone(**kwargs) kwargs = _apply_java_nullability_pkg_info_generator(**kwargs) android_library(**kwargs)
  46. Design of Bazel: Configuration ‣Visibility -Defines what packages or targets

    are allowed to directly depend on this target https:"//docs.bazel.build/versions/master/be/common-definitions.html#common-attributes
  47. Design of Bazel: Configuration java_library( name = "a", srcs =

    [ "A.java" ], deps = [ "//:b" ], visibility = [ "//visibility:public" ] ) java_library( name = "b", srcs = [ "B.java" ], visibility = [ "//myfriendlypkg:lib" ] )
  48. Design of Bazel: Configuration ‣Maintainability ‣Buildifier — tool for formatting

    & linting BUILD and .bzl files https:"//github.com/bazelbuild/buildtools
  49. Design of Bazel: Configuration ‣Maintainability ‣Buildifier — tool for formatting

    & linting BUILD and .bzl files ‣Buildozer — tool for mass refactoring of BUILD files https:"//github.com/bazelbuild/buildtools
  50. Design of Bazel: Configuration ‣Maintainability ‣Buildifier — tool for formatting

    & linting BUILD and .bzl files ‣Buildozer — tool for mass refactoring of BUILD files ‣Both written in Go, run pretty fast https:"//github.com/bazelbuild/buildtools
  51. Design of Bazel: Configuration java_library( name = "a", srcs =

    ["A.java"], deps = ["//:b"], ) java_library( name = "a", srcs = ["A.java"], deps = ["//:b"], ) Before: After:
  52. Design of Bazel: Configuration java_library( name = "a", srcs =

    ["A.java"], deps = ["//:b"], ) https:"//github.com/bazelbuild/buildtools/blob/master/buildozer/README.md
  53. Design of Bazel: Configuration java_library( name = "a", srcs =

    ["A.java"], deps = ["//:b"], ) https:"//github.com/bazelbuild/buildtools/blob/master/buildozer/README.md
  54. Design of Bazel: Configuration java_library( name = "a", srcs =

    ["A.java"], deps = ["//:b"], ) lyft_java_library( name = "a", srcs = ["A.java"], deps = ["//:b"], ) https:"//github.com/bazelbuild/buildtools/blob/master/buildozer/README.md
  55. Design of Bazel: Execution ‣Commands Command Purpose bazel query What

    Targets are there https:"//docs.bazel.build/versions/master/command-line-reference.html
  56. Design of Bazel: Execution ‣Commands Command Purpose bazel query What

    Targets are there bazel build Build one or more Targets https:"//docs.bazel.build/versions/master/command-line-reference.html
  57. Design of Bazel: Execution ‣Commands Command Purpose bazel query What

    Targets are there bazel build Build one or more Targets bazel test Run one or more Test Targets https:"//docs.bazel.build/versions/master/command-line-reference.html
  58. Design of Bazel: Execution ‣Commands Command Purpose bazel query What

    Targets are there bazel build Build one or more Targets bazel test Run one or more Test Targets bazel run Run one or more Run Targets https:"//docs.bazel.build/versions/master/command-line-reference.html
  59. Design of Bazel: Execution ‣Incrementability ‣Bazel won’t do what has

    already been done (duh) ‣Compilation is not incremental
  60. Design of Bazel: Execution ‣Incrementability ‣Bazel won’t do what has

    already been done (duh) ‣Compilation is not incremental ‣Tests results are also cached (you can opt out)
  61. Design of Bazel: Execution public class MyClass { private String

    x; public void a() { this.x = b(); } private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  62. Design of Bazel: Execution public class MyClass { private String

    x; public void a() { this.x = b(); } private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } MyClass.java
  63. Design of Bazel: Execution public class MyClass { private String

    x; public void a() { this.x = b(); } private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } MyClass.java
  64. Design of Bazel: Execution public class MyClass { private String

    x; public void a() { this.x = b(); } private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } MyClass.java
  65. Design of Bazel: Execution public class MyClass { private String

    x; public void a() { this.x = b(); } private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } MyClass.java
  66. Design of Bazel: Execution public class MyClass { public void

    a() { this.x = b(); } private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  67. Design of Bazel: Execution public class MyClass { public void

    a() { this.x = b(); } private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } MyClass.java
  68. Design of Bazel: Execution public class MyClass { public void

    a() { this.x = b(); } private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } MyClass.java
  69. Design of Bazel: Execution public class MyClass { public void

    a(); private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  70. Design of Bazel: Execution public class MyClass { public void

    a(); private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  71. Design of Bazel: Execution public class MyClass { public void

    a(); private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  72. Design of Bazel: Execution public class MyClass { public void

    a(); private String b() { Random random = new Random(); StringBuilder str = new StringBuilder(); for (int i = 0; i < random.nextInt(1024); i++) { str.append(i); } return str.toString(); } public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  73. Design of Bazel: Execution public class MyClass { public void

    a(); public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  74. Design of Bazel: Execution public class MyClass { public void

    a(); public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  75. Design of Bazel: Execution public class MyClass { public void

    a(); public static Runnable c(String s) { return () -> { new MyClass().b(); }; } } MyClass.java
  76. Design of Bazel: Execution public class MyClass { public void

    a(); public static Runnable c(String s); }
  77. Design of Bazel: Execution public class MyClass { public void

    a(); public static Runnable c(String s); } MyClass_Header.java (actually, it’s .class right away)
  78. Design of Bazel: Execution ‣Persistent Workers ‣Simple Request/Response Protocol between

    Bazel and a Worker ‣Bazel sends requests as Protobuf messages to Worker’s stdin
  79. Design of Bazel: Execution ‣Persistent Workers ‣Simple Request/Response Protocol between

    Bazel and a Worker ‣Bazel sends requests as Protobuf messages to Worker’s stdin ‣Bazel reads responses as Protobuf messages from Worker’s stdout
  80. Design of Bazel: Execution ‣Persistent Workers ‣Simple Request/Response Protocol between

    Bazel and a Worker ‣Bazel sends requests as Protobuf messages to Worker’s stdin ‣Bazel reads responses as Protobuf messages from Worker’s stdout ‣PW is useful for JVM-based or other tools that run faster when warmed up
  81. Design of Bazel: Execution ‣Persistent Workers ‣Simple Request/Response Protocol between

    Bazel and a Worker ‣Bazel sends requests as Protobuf messages to Worker’s stdin ‣Bazel reads responses as Protobuf messages from Worker’s stdout ‣PW is useful for JVM-based or other tools that run faster when warmed up ‣Expect changes in parallelism and maybe +JSON
  82. Design of Bazel: Execution ‣Persistent Workers ‣Simple Request/Response Protocol between

    Bazel and a Worker ‣Bazel sends requests as Protobuf messages to Worker’s stdin ‣Bazel reads responses as Protobuf messages from Worker’s stdout ‣PW is useful for JVM-based or other tools that run faster when warmed up ‣Expect changes in parallelism and maybe +JSON ‣In theory, PW can be used for actual incremental compilation since it keeps state
  83. Design of Bazel: Execution ‣Sandboxing ‣Another important piece of reproducible

    builds ‣Isolates filesystem and process environment for build actions similarly to containers
  84. Design of Bazel: Execution ‣Sandboxing ‣Another important piece of reproducible

    builds ‣Isolates filesystem and process environment for build actions similarly to containers ‣Supports Linux and macOS, Windows WIP
  85. Design of Bazel: Execution ‣Sandboxing ‣Another important piece of reproducible

    builds ‣Isolates filesystem and process environment for build actions similarly to containers ‣Supports Linux and macOS, Windows WIP ‣macOS performance is not great yet (we saw 30% degradation)
  86. Design of Bazel: Execution ‣Remote Cache ‣Action Cache ‣Output Cache

    ‣Has amazing optimization “Remote Builds without the Bytes”
  87. Design of Bazel: Execution ‣Remote Bazel Execution -Acts as Remote

    Cache too -Automatic selection of execution strategy (local vs remote)
  88. Design of Bazel: Execution ‣Remote Bazel Execution -Acts as Remote

    Cache too -Automatic selection of execution strategy (local vs remote) -Remote environment for actions with Docker images
  89. Design of Bazel: Execution ‣Remote Bazel Execution -Acts as Remote

    Cache too -Automatic selection of execution strategy (local vs remote) -Remote environment for actions with Docker images -Virtually indefinitely parallelism
  90. Design of Bazel: Execution ‣Remote Bazel Execution -Acts as Remote

    Cache too -Automatic selection of execution strategy (local vs remote) -Remote environment for actions with Docker images -Virtually indefinitely parallelism -Google Cloud provides it as service yo (): RBE
  91. Design of Bazel: Execution ‣Mobile Install -Like “Apply Changes” but

    made years ago https:"//docs.bazel.build/versions/master/mobile-install.html
  92. Design of Bazel: Execution ‣Mobile Install -Like “Apply Changes” but

    made years ago -Works by installing 2 apps: • Stub app with custom application class to load code & resources from “Contents app” • "Contents app" with actual code and resources https:"//docs.bazel.build/versions/master/mobile-install.html
  93. Design of Bazel: Execution ‣Mobile Install -Like “Apply Changes” but

    made years ago -Works by installing 2 apps: • Stub app with custom application class to load code & resources from “Contents app” • "Contents app" with actual code and resources -Incrementally updates dex files and resources in “Contents app” https:"//docs.bazel.build/versions/master/mobile-install.html
  94. Design of Bazel: Execution ‣Mobile Install -Like “Apply Changes” but

    made years ago -Works by installing 2 apps: • Stub app with custom application class to load code & resources from “Contents app” • "Contents app" with actual code and resources -Incrementally updates dex files and resources in “Contents app” -Has few corner cases and limitations https:"//docs.bazel.build/versions/master/mobile-install.html
  95. Design of Bazel: IDE Integration -IDE integration uses Bazel CLI

    commands -IDE queries Bazel about the project (bazel query …)
  96. Design of Bazel: IDE Integration -IDE integration uses Bazel CLI

    commands -IDE queries Bazel about the project (bazel query …) -Supports Partial Sync for specific files, dirs
  97. Design of Bazel: IDE Integration ‣IntelliJ Family -IntelliJ -Android Studio

    -CLion https:"//docs.bazel.build/versions/master/ide.html
  98. Design of Bazel: IDE Integration ‣Xcode -Tulsi and XCHammer to

    generate Xcode project from Bazel project -Lyft is working on Focus tool to limit number of loaded modules -lyft/index-import to import swift and clang index files produced as side effect of compilation https:"//docs.bazel.build/versions/master/ide.html
  99. Design of Bazel: Integration w/ Other Tools ‣Genrule -Run arbitrary

    CLI tool, Bash, Powershell, etc -As any other rule, inputs and outputs are tracked -Sandboxing makes it easier to achieve reproducibility https:"//docs.bazel.build/versions/master/be/general.html#genrule
  100. Design of Bazel: Integration w/ Other Tools genrule( name =

    "mygenrule", cmd = "mkdir $(RULEDIR)/mydir; javac -d $(OUTS) $(SRCS)", outs = [ "mydir" ], srcs = [ "B.java" ], ) https:"//docs.bazel.build/versions/master/be/general.html#genrule
  101. Design of Bazel: Integration w/ Other Tools ‣Toolchains and Platforms

    -Bazel has notion of Target and Execution Platforms -Toolchain defines key/value pairs per Platform -Toolchain typically represents a set of Tooling for a language -Compiler -Linker -etc https:"//docs.bazel.build/versions/master/toolchains.html
  102. Design of Bazel: Integration w/ Other Tools ‣Extensions -.bzl files

    written in Starlark with macros, rules, constants -load(“#//mybazelextensions:file.bzl”, “myrule_or_macro”) -One of main Bazel 1.0 goals is to extract impls from core to external rules repos https:"//docs.bazel.build/versions/master/skylark/concepts.html
  103. Design of Bazel: Integration w/ Other Tools ‣Extensions github.com/bazelbuild/ -rules_java

    -rules_android -rules_kotlin -rules_jvm_external -rules_apple
  104. Design of Bazel: Integration w/ Other Tools ‣Extensions github.com/bazelbuild/ -rules_java

    -rules_android -rules_kotlin -rules_jvm_external -rules_apple -etc
  105. Design of Bazel: Integration w/ Other Tools ‣Extensions github.com/bazelbuild/ -rules_java

    -rules_android -rules_kotlin -rules_jvm_external -rules_apple -etc ‣github.com/you/rules_x !
  106. Artem Zinnatullin ‣ @artem_zin ‣ artemzin.com Come work with me!

    Also: Lyft Mobile Podcast tools, libraries, CI, builds @