陈坤 - 《Buck在大规模iOS开发中的应用实践》

展开查看详情

1.《BUCK在大规模iOS开发中的应用实践》 演讲者/陈坤

2. Airbnb iOS Stats • 80 commits/day to master (PRs are squashed) • 500+ builds/week • 71 iOS contributors last month

3. Airbnb iOS Stats • Multi apps • Monorepo • 900k lines of code • 67% Swift • 25% Javascript • 8% Objective-C • 80 internal frameworks + 25 Cocoapods + 2 Carthage

4. Main Challenges • Multi-Repos • Hard to refactor • Non-atomic changes, complex versioning • Cocopods encourages multi repos.

5. Main Challenges • Xcode project management • Resolving .xcproj conflicts. • Hard to maintain dependencies. • Hard for modernization. • Hard to change build settings. • CI build/test performance

6. Airbnb change to use Monorepo • Unified versioning, one source of truth. • Atomic changes. • Flexible team boundaries and code ownership. • Large scale refactoring, codebase modernization. • Works for BUCK.

7.

8.Use Buck as the build system

9. Build Tool Landscape • Cocoapods • Carthage • BUCK • xctool • xcodebuild • Swift Package Manager • …

10. Cocoapods • Airbnb now only uses Cocoapods for 3rd party libraries. • We used it for internal UI frameworks. • Why it doesn’t work us: • Slow to resolve, complex interdependencies. • Not designed for monorepo.

11. BUCK helps • Designed for monorepo. • Easy and clean dependency management. • Encouraging modernization. • Generate project for Xcode. • More important: Faster build/test.

12. Why using BUCK • Build Time • Building with multi-threading • Cache aggressively • App Size • Merging modules into single binary • Saving spaces in keep multiple copies of same resource • Dev Efficiency • Reducing effort in maintaining Cocoapods • Creating new module easier by adding BUCK file • Running tests with one line command • Review diffs in Xcode project changes

13. BUCK File • Every framework/app has a BUCK file. • Buck tool is written in Java, but BUCK file is python script. • Define build rules and build targets. • Build targets • What and how to compile. • Specify dependencies (transitive)

14.Example of BUCK file

15.Power of python script

16. BUCK DAG • Explicit dependency, no hidden state. • Dependencies are transitive. • DAG powers the build speed and cache.

17. Faster Build • BUCK is deterministic, output only determined by declared input. • Cache • Disk cache. • Http cache. • https://github.com/uber/buck-http-cache • Parallelize build/test.

18.Buck Build Demo

19.How Buck builds iOS app

20. How apple_library works 1. Input: *.h. Output: Module.hmap. 2. Input: *.swift, Module.hmap. Output: Module.o, Module.swiftmodule, Module-Swift.h 3. Input: *.m, Module.hmap, Module-Swift.h. Output: *.o for each *.m. 4. Input: *.o, Module.o. Output: libModule.a.

21. BUCK Commands • build • buck build //ios:AirbnbPackage_Alpha • buck build AirbnbAlpha • Generate project • buck project //ios:Airbnb • Query • buck query “deps(//ios:Airbnb)”

22.Airbnb Dependency Graph TODO… Attach an image here

23.Challenges in Airbnb

24. Mix Languages 1 • Auto import objective-c to Swift • -import-underlying-module doesn’t work • Explicitly pass bridging headers.

25. Mix Languages 2 • @import doesn’t work in objective-C due to no module.modulemap. • Use #import in our own codebase. • For generated *-Swift.h, use customize script to do transform. • https://github.com/airbnb/buck/commit/93453 a5730445c0dd799872b6e8bba49233430d7

26. Mix Languages 3 • Bridging header can’t import headers under current module. • Update BUCK to include the generated header map for current library. • https://github.com/facebook/buck/ Can’t #import <Greeter/Greeter.h> in the bridging header pull/1164

27. Work with Cocopods • Still use Cocopods to install packages. • Manually create and maintain a BUCK file. • We can do better: • Hook into Podfile to generate BUCK file automatically. • But we are moving off from Cocoapods.

28.Work with Cocopods

29. Others • Support prebuilt_cxx_library in BUCK project generation • Support umbrella headers • Cocoapod generate umbrella headers named as Module- umbrella.h • Buck assuming all module header named as Module.h • swiftc compliant if a public header file is not included in module header