What is Buck Local?
Buck Local splits your build into two parts:- Buck builds dependencies: All libraries, frameworks, and resources are built with Buck and copied to Xcode’s DerivedData
- Xcode builds your code: Your active development code is built using Xcode’s native build system
Benefits
Faster Incremental Builds
Only rebuild what you’re actively editing. Dependencies are cached.
Full Xcode Integration
Native Xcode build system means full IDE support and faster indexing.
Buck-Powered Dependencies
Dependencies use Buck’s fast, correct builds with strong caching.
Seamless Development
Edit, build, debug, and test entirely within Xcode.
Quick Start
Generate a Buck Local workspace:App/ExampleAppBuckLocal-BUCK.xcworkspace and opens it in Xcode.
How It Works
Buck builds dependencies
A pre-build script runs Buck to build all dependencies:This script:
BuckLocal/buck_build_and_copy.sh:14-16
- Builds all libraries with Buck
- Copies
.afiles to DerivedData - Copies swiftmodule files for Swift dependencies
- Copies resources and asset catalogs
The first build takes longer as Buck builds all dependencies. Subsequent builds are much faster since only your code rebuilds.
Configuration
Buck Local Targets
Buck Local requires special target definitions. Regular targets are wrapped with Buck Local equivalents:Binary Wrapper
Config/buck_local.bzl:1-24
- Creates two binaries: one for normal Buck builds, one for Buck Local
native_xcode_deps: Dependencies built by Xcodebuck_local_deps: Pre-built Buck libraries
Bundle Wrapper
Config/buck_local.bzl:26-44
Workspace Configuration
Config/buck_local.bzl:46-73
The BuckLocal/BUCK File
TheBuckLocal/BUCK file is auto-generated during project generation:
BuckLocal/BUCK:1-29
BuckLocal/ruby_scripts/project_generator.rb and should not be edited manually.
Build Process
Pre-Build Phase
When you build in Xcode, a pre-build script runs first:BuckLocal/BUCK:2-5
- Reads the dependency list from
BuckLocal/lib_targets.list - Builds all libraries with Buck:
- Copies artifacts to DerivedData:
- Static libraries (
.afiles) - Swift modules (
.swiftmodule) - Resources and asset catalogs
- Static libraries (
Linking Phase
Your app binary links against the pre-built libraries:BuckLocal/BUCK:25
Post-Build Phase
A post-build script remaps debug source paths for breakpoint support:BuckLocal/BUCK:34-38
UUID.plist inside the dSYM bundle so LLDB can map breakpoints from local source paths to compiled code.
Using Buck Local
Generate the workspace
- Cleans old projects
- Generates
BuckLocal/BUCKfile - Creates the Buck Local workspace
- Opens it in Xcode
First build
In Xcode, press Cmd+B to build.The first build:
- Runs Buck to build all dependencies (slow)
- Builds your app code with Xcode (fast)
- Total time: Similar to a full Buck build
Incremental builds
Make changes to your app code and build again.Incremental builds:
- Skip Buck (dependencies unchanged)
- Only rebuild changed files with Xcode
- Total time: Much faster!
When to Use Buck Local
Best For
✅ Rapid iteration on app codeEditing ViewControllers, AppDelegate, and UI code ✅ UI/UX development
Tweaking layouts, colors, animations ✅ Debugging
Full Xcode debugger support with fast rebuilds ✅ Large dependency graphs
The more dependencies, the bigger the time savings
Not Ideal For
❌ Library developmentIf you’re changing library code frequently, dependencies rebuild often ❌ CI builds
CI should use pure Buck for consistency ❌ Clean builds
First build is no faster than standard Buck
Comparison
Buck Local vs Standard Buck Project
| Aspect | Standard Project | Buck Local |
|---|---|---|
| Build system | Buck for everything | Buck for deps, Xcode for app |
| Incremental builds | Fast | Faster |
| First build | Fast | Similar speed |
| Xcode integration | Limited | Full native |
| Build settings | Edit BUCK files | Edit BUCK files |
| Debugging | Good | Excellent |
| Indexing | Slower | Faster |
| CI/CD | Recommended | Not recommended |
Buck Local vs Pure Xcode
| Aspect | Pure Xcode | Buck Local |
|---|---|---|
| Correctness | Can be incorrect | Buck ensures correctness |
| Caching | Limited | Strong Buck caching |
| Dependencies | Manual management | Buck manages automatically |
| Incremental builds | Fast | Similarly fast |
| Build definitions | Xcode project files | BUCK files |
Project Generator
The Buck Local workspace is generated by Ruby scripts inBuckLocal/ruby_scripts/:
project_generator.rb
Main orchestration:BuckLocal/ruby_scripts/project_generator.rb:19-30
Key Steps
- Analyze dependencies: Query all transitive dependencies of the app
- Generate linker flags: Create flags for all Buck-built libraries
- Write BuckLocal/BUCK: Use ERB template to generate the file
- Generate Xcode project: Run
buck project - Update xcconfig files: Remove conflicting header search paths
- Update schemes: Disable implicit dependency building
Dependency Analysis
The generator queries Buck for all dependencies:BuckLocal/ruby_scripts/project_generator.rb:43
apple_librarytargetsprebuilt_cxx_librarytargetsapple_resourcetargetsapple_asset_catalogtargets- Exported linker flags
Debugging with Buck Local
Breakpoint Support
Buck Local includes full breakpoint support:- Debug symbols: Buck generates dSYM bundles
- Source mapping: The
remap_debug_source_path.shscript creates path mappings - LLDB integration: Xcode’s debugger works seamlessly
Setting Breakpoints
Set breakpoints normally:- Click line gutters in Xcode
- Use symbolic breakpoints
- Set exception breakpoints
Source Path Remapping
Buck builds with absolute paths, but your source is in a different location. The remap script:- Reads
BuckLocal/RemoteSourcePathList.txt - Creates mappings from Buck paths to local paths
- Writes mappings to the dSYM bundle
- LLDB uses these mappings for breakpoint resolution
Troubleshooting
Build Script Errors
Problem: “Buck build failed” during pre-build- Solution: Check Buck output for errors. Dependencies may have compilation issues:
- Solution: Regenerate the project. The
BuckLocal/BUCKfile may be stale:
Slow Builds
Problem: Every build runs Buck even when libraries didn’t change- Solution: Buck should cache unchanged targets. Check Buck cache:
- Solution: The script builds all dependencies. This is expected on first build or when libraries change.
Debugging Issues
Problem: Breakpoints don’t work in library code- Solution: Ensure the post-build script ran successfully. Check for errors in build log.
- Solution: The source path remapping may have failed. Check
BuckLocal/RemoteSourcePathList.txtexists.
Project Generation Fails
Problem: Ruby errors during generation- Solution: Install Ruby dependencies:
- Solution: Ensure
//App:workspace-buck-localtarget exists inApp/BUCK:
Testing Buck Local Scripts
The Ruby scripts have their own test suite:BuckLocal/ruby_scripts/spec/:
buck_local_spec.rb: Tests main Buck Local logicbuck_local_targets_spec.rb: Tests target parsingbuck_log_formatter_spec.rb: Tests build output formatting
Advanced Configuration
Custom Xcconfig Settings
Additional Xcode build settings can be added to generated xcconfig files. Theupdate_xcconfig_files method:
BuckLocal/ruby_scripts/project_generator.rb:79-86
Header and Swift include paths are removed because Buck handles these internally. Including them causes duplicate definitions.
Customizing the Build Script
Thebuck_build_and_copy.sh script can be customized:
BuckLocal/buck_build_and_copy.sh:5-16
Next Steps
Building the App
Learn about Buck build commands and configurations
Testing
Run unit tests and UI tests with Buck and Xcode