Skip to main content
BuckSample demonstrates how to use CocoaPods dependencies in a Buck-based project by converting pod installations into Buck targets.

Overview

The project uses CocoaPods to download dependencies but doesn’t generate Xcode projects. Instead, pod sources are wrapped in Buck targets defined in Pods/BUCK.

Podfile Configuration

The Podfile specifies dependencies but disables Xcode integration:
Podfile
# Set the platform globally
platform :ios, '12.0'

# Only download the files, don't create Xcode projects
install! 'cocoapods', integrate_targets: false

target 'BuckSample' do
  pod 'Braintree', '4.28.0'
  pod 'Braintree/DataCollector', '4.28.0'
  pod 'Braintree/Apple-Pay', '4.28.0'
  pod 'Braintree/PaymentFlow', '4.28.0'
  pod 'Bugsnag', '5.17.3'
  pod 'CryptoSwift'
  pod 'Nimble', '8.0.2'
  pod 'PromiseKit/CoreLocation', '6.1.1'
  pod 'PromiseKit/CorePromise', '6.1.1'
  pod 'Quick', '2.1.0'
end
The key setting is integrate_targets: false, which tells CocoaPods to only download pod sources without modifying Xcode projects.

Converting Pods to Buck Targets

After running pod install, the downloaded sources in Pods/ are converted to Buck targets in Pods/BUCK.

Swift Pod Example

Pure Swift pods use apple_third_party_lib:
Pods/BUCK
load("//Config:buck_rule_macros.bzl", "apple_third_party_lib")

apple_third_party_lib(
    name = "CryptoSwift",
    srcs = glob([
        "CryptoSwift/**/*.swift",
    ]),
)

Mixed Swift/Objective-C Pod

Pods with both Swift and Objective-C require exported headers:
Pods/BUCK
apple_third_party_lib(
    name = "PromiseKit",
    visibility = ["PUBLIC"],
    exported_headers = glob([
        "PromiseKit/**/*.h",
    ], exclude = [
        "PromiseKit/AnyPromise+Private.h",
    ]),
    srcs = glob([
        "PromiseKit/**/*.m",
        "PromiseKit/**/*.swift",
    ], exclude = [
        "PromiseKit/Sources/PMKCallVariadicBlock.m",
        "PromiseKit/Sources/NSMethodSignatureForBlock.m",
    ]),
)
Some files are excluded because they’re not considered sources in the pod’s podspec. This ensures Buck builds the pod the same way CocoaPods would.

C++ Pod (Bugsnag)

Pods with C/C++ code use apple_cxx_third_party_library:
Pods/BUCK
load("//Config:buck_rule_macros.bzl", "apple_cxx_third_party_library")

apple_cxx_third_party_library(
    name = "Bugsnag",
    exported_headers = glob([
        "Bugsnag/**/BSG_KSCrashReportWriter.h",
        "Bugsnag/**/Bugsnag.h",
        "Bugsnag/**/BugsnagBreadcrumb.h",
        "Bugsnag/**/BugsnagConfiguration.h",
        "Bugsnag/**/BugsnagCrashReport.h",
        "Bugsnag/**/BugsnagMetaData.h",
    ]),
    headers = glob([
        "Bugsnag/**/*.h",
    ]),
    srcs = glob([
        "Bugsnag/**/*.c",
        "Bugsnag/**/*.m",
        "Bugsnag/**/*.mm",
    ]),
)

Complex Pod with Resources

The Braintree pod demonstrates handling prebuilt frameworks, static libraries, and resource bundles:
apple_third_party_lib(
    name = "Braintree",
    visibility = ["PUBLIC"],
    exported_headers = glob([
        "Braintree/**/Public/**/*.h",
        "Braintree/BraintreePayPal/PayPalDataCollector/Risk/PPRMOCMagnesResult.h",
    ]),
    headers = glob([
        "Braintree/**/*.h",
    ]),
    srcs = glob([
        "Braintree/**/*.m",
    ]),
    deps = [
        ":BTDeviceCollectorLibrary",
        ":BTPPRiskComponent",
        ":Braintree-Drop-In-Localization-Resource",
        ":Braintree-UI-Localization-Resource",
        ":CardinalMobile",
    ],
)

Resource Bundles

Pods with localization resources need to be wrapped in apple_bundle:
apple_resource(
    name = "Braintree-Drop-In-Localization",
    visibility = ["PUBLIC"],
    dirs = [
        "Braintree/BraintreeUI/Drop-In/Localization/da.lproj",
        "Braintree/BraintreeUI/Drop-In/Localization/de.lproj",
        "Braintree/BraintreeUI/Drop-In/Localization/en.lproj",
        # ... more localizations
    ],
)

Using Pods in Your Code

Reference pod targets like any other dependency:
apple_library(
    name = "ExampleAppLibrary",
    deps = [
        "//Pods:CryptoSwift",
        "//Pods:PromiseKit",
        # other deps
    ],
)

Testing Pods

Test framework pods like Quick and Nimble require special compiler flags:
Pods/BUCK
apple_third_party_lib(
    name = "Quick",
    swift_version = "5",
    visibility = ["PUBLIC"],
    compiler_flags = ["-fapplication-extension"],
    swift_compiler_flags = ["-application-extension"],
    exported_headers = glob([
        "Quick/**/*.h",
    ]),
    srcs = glob([
        "Quick/**/*.m",
        "Quick/**/*.swift",
    ]),
    frameworks = [
        "$PLATFORM_DIR/Developer/Library/Frameworks/XCTest.framework",
    ]
)

Workflow Summary

  1. Add pod to Podfile: Specify dependencies normally
  2. Run pod install: Downloads pod sources to Pods/ directory
  3. Create Buck targets: Convert pod structure to Buck targets in Pods/BUCK
  4. Reference in deps: Use //Pods:PodName in your BUCK files
  5. Import in code: Use regular Swift/Objective-C imports
This approach gives you the dependency management of CocoaPods with the build performance and flexibility of Buck.

Build docs developers (and LLMs) love