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

Android Builds at Speed and Scale

Android Builds at Speed and Scale

How do Android engineers at Facebook "move fast on stable infrastructure"? How do we make local builds stupendously fast? How do ensure that there are no regressions in functionality? As our codebase grows, how do we make sharing code easy and lightweight? Answers to all these questions can be found within….

Simon Stewart

April 27, 2015
Tweet

More Decks by Simon Stewart

Other Decks in Programming

Transcript

  1. Large Repos Are Slow ▪Lots of commits a day Pulls

    are slow Checkouts are slow ▪Years of history Clones are slow Requires lots of disk space
  2. Shallow Checkouts Clone just the latest version Work locally without

    complete history Need more history? Download on demand HEAD HEAD-1 HEAD-2 HEAD-3
  3. Sparse Checkouts Work on just the files you need Build

    system integrations knows how to check out more ~/fbsource ios/... common/... ~/fbsource/.hg
  4. Watchman OS independent filesystem change notification Integrates with mercurial File

    checking operations scale linearly with number of files changed
  5. Large Repos Are Fast 50 times faster than git 2000

    hg improvements Up to More than
  6. Buck ▪Next generation build system ▪Designed for modern hardware ▪SSD

    ▪Plentiful RAM ▪Many cores ▪Automatically parallelizes builds ▪And it's Open Source
  7. Build Files java_binary( name = 'example-binary', deps = [ ':example',

    ], ) java_library( name = 'example', srcs = glob(['*.java']), deps = [ '//third-party/guava:guava', ], visibility = [ '//javatests/...', ], ) Build file. Typically named BUCK
  8. Build Files java_binary( name = 'example-binary', deps = [ ':example',

    ], ) java_library( name = 'example', srcs = glob(['*.java']), deps = [ '//third-party/guava:guava', ], visibility = [ '//javatests/...', ], ) Build file. Typically named BUCK A build rule of type "java_binary"
  9. Build Files java_binary( name = 'example-binary', deps = [ ':example',

    ], ) java_library( name = 'example', srcs = glob(['*.java']), deps = [ '//third-party/guava:guava', ], visibility = [ '//javatests/...', ], ) Build file. Typically named BUCK A build rule of type "java_binary" A target defined in the same build file
  10. Build Files java_binary( name = 'example-binary', deps = [ ':example',

    ], ) java_library( name = 'example', srcs = glob(['*.java']), deps = [ '//third-party/guava:guava', ], visibility = [ '//javatests/...', ], ) Build file. Typically named BUCK A build rule of type "java_binary" A target defined in the same build file Build rule of type "java_library"
  11. Build Files java_binary( name = 'example-binary', deps = [ ':example',

    ], ) java_library( name = 'example', srcs = glob(['*.java']), deps = [ '//third-party/guava:guava', ], visibility = [ '//javatests/...', ], ) Build file. Typically named BUCK A build rule of type "java_binary" A target defined in the same build file A target defined in another build file Build rule of type "java_library"
  12. Build Files java_binary( name = 'example-binary', deps = [ ':example',

    ], ) java_library( name = 'example', srcs = glob(['*.java']), deps = [ '//third-party/guava:guava', ], visibility = [ '//javatests/...', ], ) Build file. Typically named BUCK A build rule of type "java_binary" A target defined in the same build file A target defined in another build file Build rule of type "java_library" All targets have visibility
  13. Target and Action Graph Target Graph: a naive representation of

    targets defined in build files. Action Graph: an optimized graph of actions to perform as the build
  14. Language-Aware Smarts public class Foo { private String someField; public

    void doSomething(int times) { System.out.println("Wow! " + times); } } Buck calculates the ABI, and keys rebuilds of dependencies off that Packaging rules that depend on this will always be re-run.
  15. Language-Aware Smarts public class Foo { private boolean theCakeIsALie =

    true; public void doSomething(int times) { System.out.println("Wow! " + times); } } Private field changed: ABI remains the same as before
  16. Language-Aware Smarts public class Foo { private boolean theCakeIsALie =

    true; public void doSomething(int num) { System.out.println("Wow! " + num); } } Parameter name changed: ABI remains the same as before.
  17. Language-Aware Smarts public class Foo { private boolean theCakeIsALie =

    true; public void doSomething(String num) { System.out.println("Wow! " + num); } } Parameter type changed: ABI changes too!
  18. Language-Aware Smarts public class Foo { private boolean theCakeIsALie =

    true; public void doSomething(String num) { System.err.println("Wow! " + num); } } Body of method changed: ABI remains the same.
  19. Pervasive Caching • Only 3% of each build is unique.

    • Local and distributed caches slash build times.
  20. Buck Smarts Build rule knows all of the inputs that

    can affect its output Changes to dx and proguard for faster compilation Java ABI smarts Android resource smarts Daemon to watch file changes
  21. Sandcastle Design Single Master Distributed Queue Master Worker Worker Worker

    Worker Worker Worker Worker Worker Worker Worker Distributed Queue
  22. Summary Tool OSS? Link! Buck Yes https://facebook.github.io/buck/ Mercurial Yes http://mercurial.selenic.com/

    Watchman Yes https://facebook.github.io/watchman/ hgwatchman Yes https://bitbucket.org/facebook/hgwatchman remote filelog Yes https://bitbucket.org/facebook/remotefilelog Sandcastle No