Section 6/131 menit

6. Bazel — Konfigurasi dan Penggunaan

6. Bazel — Konfigurasi dan Penggunaan

Instalasi

swift
# Install via Bazelisk (wrapper yang otomatis pilih versi Bazel)
brew install bazelisk

# Bazelisk membaca .bazelversion di root project
echo "7.4.1" > .bazelversion

Struktur Project Bazel untuk iOS

swift
MyApp/
├── WORKSPACE           ← root, mendefinisikan external dependencies
├── BUILD               ← build rules untuk root
├── .bazelversion       ← versi Bazel yang digunakan
├── .bazelrc            ← konfigurasi Bazel default
├── Modules/
│   ├── NetworkKit/
│   │   ├── BUILD       ← build rules untuk module ini
│   │   └── Sources/
│   └── FeatureHome/
│       ├── BUILD
│       └── Sources/
└── App/
    ├── BUILD
    └── Sources/

WORKSPACE — External Dependencies

swift
# WORKSPACE

workspace(name = "MyApp")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# rules_apple — rules untuk build iOS/macOS apps
http_archive(
    name = "build_bazel_rules_apple",
    sha256 = "...",
    url = "https://github.com/bazelbuild/rules_apple/releases/download/3.10.0/rules_apple.3.10.0.tar.gz",
)

# rules_swift — rules untuk kompilasi Swift
http_archive(
    name = "build_bazel_rules_swift",
    sha256 = "...",
    url = "https://github.com/bazelbuild/rules_swift/releases/download/2.2.0/rules_swift.2.2.0.tar.gz",
)

load(
    "@build_bazel_rules_apple//apple:repositories.bzl",
    "apple_rules_dependencies",
)
apple_rules_dependencies()

load(
    "@build_bazel_rules_swift//swift:repositories.bzl",
    "swift_rules_dependencies",
)
swift_rules_dependencies()

# Swift Package Manager dependencies via swift_package_manager rules
load("@rules_swift_package_manager//:deps.bzl", "swift_package_manager_dependencies")
swift_package_manager_dependencies()

BUILD File untuk Swift Module

swift
# Modules/NetworkKit/BUILD

load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")

swift_library(
    name = "NetworkKit",
    srcs = glob(["Sources/**/*.swift"]),
    module_name = "NetworkKit",
    deps = [
        "//Modules/SharedModels:SharedModels",
        "@Alamofire//:Alamofire",
    ],
    visibility = ["//visibility:public"],
    copts = [
        "-strict-concurrency=complete",
        "-swift-version",
        "6",
    ],
)

swift_library(
    name = "NetworkKitTests",
    srcs = glob(["Tests/**/*.swift"]),
    module_name = "NetworkKitTests",
    deps = [
        ":NetworkKit",
    ],
    testonly = True,
)

BUILD File untuk iOS App

swift
# App/BUILD

load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application")
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")

swift_library(
    name = "AppLib",
    srcs = glob(["Sources/**/*.swift"]),
    deps = [
        "//Modules/NetworkKit:NetworkKit",
        "//Modules/FeatureHome:FeatureHome",
        "//Modules/FeatureProfile:FeatureProfile",
    ],
)

ios_application(
    name = "MyApp",
    bundle_id = "com.company.myapp",
    families = ["iphone"],
    infoplists = ["Sources/Info.plist"],
    minimum_os_version = "17.0",
    provisioning_profile = "//Profiles:development.mobileprovision",
    deps = [":AppLib"],
)

.bazelrc — Konfigurasi Default

swift
# .bazelrc

# Common build flags
build --features=swift.use_global_module_cache
build --features=swift.enable_batch_mode
build --swiftcopt=-strict-concurrency=complete

# Cache settings
build --disk_cache=~/.bazel-cache

# Remote cache (opsional — untuk CI sharing)
# build:remote --remote_cache=grpcs://buildbuddy.io
# build:remote --remote_header=x-buildbuddy-api-key=YOUR_KEY

# Test settings
test --test_output=errors
test --features=swift.coverage

# Xcode integration
build --apple_platform_type=ios
build --xcode_version_config=//:host_xcodes

Penggunaan Sehari-hari

swift
# Build app
bazel build //App:MyApp

# Build semua targets
bazel build //...

# Run tests
bazel test //Modules/NetworkKit:NetworkKitTests

# Run semua tests
bazel test //...

# Build dengan remote cache
bazel build //... --config=remote

# Explain kenapa target di-rebuild (audit cache misses)
bazel build //App:MyApp --explain=/tmp/explain.txt

# Query dependency graph
bazel query "deps(//App:MyApp)" --output graph | dot -Tpng > graph.png

# Cquery untuk analisis conditional dependencies
bazel cquery "deps(//App:MyApp)" --output label_kind

Xcode Integration dengan Tulsi atau rules_xcodeproj

swift
# BUILD — generate Xcode project dari Bazel (opsional, untuk developer UX)

load("@rules_xcodeproj//xcodeproj:defs.bzl", "xcodeproj")

xcodeproj(
    name = "MyApp_xcodeproj",
    project_name = "MyApp",
    tags = ["manual"],
    top_level_targets = [
        "//App:MyApp",
        "//Modules/...",
    ],
)
swift
# Generate Xcode project dari Bazel definitions
bazel run //:MyApp_xcodeproj