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

Story of Migrating a Large iOS Codebase to Bazel

Story of Migrating a Large iOS Codebase to Bazel

LINE DevDay 2020

November 26, 2020
Tweet

More Decks by LINE DevDay 2020

Other Decks in Technology

Transcript

  1. Why Migrate to Bazel? Services growing led to project growing

    › LINE iOS has inevitable grown to a huge codebase over the years
  2. Why Migrate to Bazel? › Build times increased for all

    developers Developer productivity degraded Services growing led to project growing › LINE iOS has inevitable grown to a huge codebase over the years
  3. Why Migrate to Bazel? › Build times increased for all

    developers Developer productivity degraded Services growing led to project growing › LINE iOS has inevitable grown to a huge codebase over the years Bazel › Fast and reproducible › Advanced caching
  4. Why Migrate to Bazel? › Build times increased for all

    developers Developer productivity degraded Services growing led to project growing › LINE iOS has inevitable grown to a huge codebase over the years Bazel › Fast and reproducible › Advanced caching Growing LINE for iOS LINE DEVELOPER DAY 2019 Faster iOS Builds With Bazel LINE DEVELOPER DAY 2019
  5. 0 5 10 15 20 25 30 April 16 April

    23 May 1 May 8 May 16 May 24 June 1 June 8 June 16 Build Times https://engineering.linecorp.com/en/blog/improving-build-performance-line-ios-bazel
  6. Keep Project Structure Simple › Helps reduce complexity of synchronizing

    between Xcode and Bazel › One module per directory, named after module name, all flatten
  7. Keep Project Structure Simple › Helps reduce complexity of synchronizing

    between Xcode and Bazel › One module per directory, named after module name, all flatten › Bonus: Swift generated headers get into search paths for free
  8. Support Both Xcode or Bazel – Choose One › Helps

    measure both build systems side by side
  9. Support Both Xcode or Bazel – Choose One › Easier

    to try new Xcode features › Helps measure both build systems side by side
  10. Support Both Xcode or Bazel – Choose One › Easier

    to try new Xcode features › Xcode still provides better debugging experience › Helps measure both build systems side by side
  11. Avoid Mix and Match Mixed Objective-C and Swift modules lead

    to many problems May slow down your builds › Changes to code in a language may trigger a full rebuild of the other
  12. Avoid Mix and Match Mixed Objective-C and Swift modules lead

    to many problems › Needs a custom rule › In case you need one: https://github.com/line/rules_apple_line No official supports from Bazel May slow down your builds › Changes to code in a language may trigger a full rebuild of the other
  13. Avoid Mix and Match Mixed Objective-C and Swift modules lead

    to many problems › Needs a custom rule › In case you need one: https://github.com/line/rules_apple_line No official supports from Bazel Clang modules can’t be cached by Bazel › Module maps rely on implicit module caching that clashes with Bazel’s hermeticity model › Slow down Obj-C builds on remote execution May slow down your builds › Changes to code in a language may trigger a full rebuild of the other
  14. Provide Faster Remote Cache Provide a way to disable remote

    cache › Remote cache may be slower than building locally depending on network speed › Most developers work from home now, not everyone has a fast connection
  15. Provide Faster Remote Cache › If VPN is a bottleneck,

    provide remote cache without VPN › If you have a distributed team, distribute remote cache via CDN Provide faster remote cache Provide a way to disable remote cache › Remote cache may be slower than building locally depending on network speed › Most developers work from home now, not everyone has a fast connection
  16. Optimize for Reproducible Builds Identify cache misses # Re-run the

    builds without caching options to obtain execution logs $ bazel clean $ bazel build --disk_cache= --remote_cache= --execution_log_json_file=exec1.json //your:target $ bazel clean $ bazel build --disk_cache= --remote_cache= --execution_log_json_file=exec1.json //your:target # Compare the execution logs between two runs $ diff -u exec1.json exec2.json › More reproducible builds = Less cache misses › Re-run the builds w/o cache to identify non-reproducible actions
  17. Optimize for Reproducible Builds Reproducible object files build --swiftcopt=-Xfrontend build

    --swiftcopt=-no-clang-module-breadcrumbs › Remove Clang module breadcrumbs from debug information
  18. Optimize for Reproducible Builds Reproducible object files build --swiftcopt=-Xfrontend build

    --swiftcopt=-no-clang-module-breadcrumbs # https://github.com/bazelbuild/rules_swift/pull/456 build --features=swift.deterministic_module_breadcrumbs › Remove Clang module breadcrumbs from debug information › Make Clang module breadcrumbs deterministic
  19. Bazel’s default settings for optimized builds produce larger binary size

    compared to Xcode’s. Binary Size build:release --features=dead_strip build:release --features=swift.opt_uses_osize build:release --objc_enable_binary_stripping build:release --objccopt=-Oz
  20. Apply LTO flags to release builds Binary Size build:release --features=dead_strip

    build:release --features=swift.opt_uses_osize build:release --objc_enable_binary_stripping build:release --objccopt=-Oz build:release --objccopt=-flto build:release --linkopt=-flto
  21. Apply LTO flags to release builds only Binary Size build:release

    --features=dead_strip build:release --features=swift.opt_uses_osize build:release --objc_enable_binary_stripping build:release --objccopt=-Oz build:release --objccopt=-flto build:release --linkopt=-flto
  22. Conclusion › Simple structure › Support both › Avoid mix

    and match › Provide faster cache › Optimize for reproducible builds
  23. Conclusion › Simple structure › Support both › Avoid mix

    and match › Provide faster cache › Optimize for reproducible builds › Keep binary size manageable