Build Tools Used by the Apple Container Project: A Complete Technical Guide

The apple/container project relies on Swift 6.2, Swift Package Manager (SPM), and Make as its primary build tools, augmented by Protocol Buffers compilers (protoc), swift-format, hawkeye for license compliance, and llvm-cov for test coverage analysis.

The apple/container repository is a pure-Swift implementation of container management tooling that requires a specific, reproducible build environment. Understanding the build tools used by the apple/container project is essential for contributors compiling the CLI, running integration tests, or generating installer packages. This guide examines the complete toolchain based on the actual source files in the repository.

Core Build Stack

Swift 6.2 and Swift Package Manager

The foundation of the build system is Swift 6.2, declared at the top of Package.swift using the Swift tools version directive:

// swift-tools-version: 6.2

This declaration enforces the minimum compiler version required to parse the package manifest. Swift Package Manager (SPM) drives the entire dependency graph and compilation process. In Package.swift, the Package initializer defines all products, executable targets, and external dependencies:

let package = Package(
    name: "container",
    products: [...],
    targets: [...]
)

The SPM handles the resolution of remote Swift packages, incremental builds, and target dependency ordering automatically.

Build Orchestration with Make

While SPM manages Swift compilation, Make serves as the primary build orchestrator. The root Makefile provides a unified interface for developers, wrapping SPM invocations and coordinating auxiliary tools.

Key targets defined in Makefile include:

  • make build – invokes swift build -c debug to compile the default debug configuration
  • make release – produces a signed installer package (.pkg) after running a release build
  • make install – copies built artifacts to system directories
  • make protos – triggers Protocol Buffer generation via the included Protobuf.Makefile

The Makefile also defines .PHONY targets to ensure these commands always execute regardless of file timestamps.

Protocol Buffer Generation Pipeline

The project uses Protocol Buffers for communication between the Container Builder shim and the CLI. The Protobuf.Makefile handles the complex toolchain required for Swift code generation.

The protoc Toolchain

The build pipeline downloads protoc (version 26.1) and builds two custom plugins from the same repository:

  • protoc-gen-swift – generates Swift structs from .proto definitions
  • protoc-gen-grpc-swift-2 – generates gRPC client/server code for Swift

These plugins are defined as SPM targets in Package.swift and built before the main compilation phase.

Generating Stubs

Running make protos executes the following logic from Protobuf.Makefile:

protos: $(PROTOC) protoc-gen-swift
	@$(PROTOC) $(LOCAL_DIR)/container-builder-shim/pkg/api/Builder.proto \
		--plugin=protoc-gen-grpc-swift=$(BUILD_BIN_DIR)/protoc-gen-grpc-swift-2 \
		--plugin=protoc-gen-swift=$(BUILD_BIN_DIR)/protoc-gen-swift \
		--grpc-swift_out="Sources/ContainerBuild" \
		--swift_out="Sources/ContainerBuild"

This command clones the container-builder-shim repository at the version pinned in Package.swift and generates Swift source files under Sources/ContainerBuild.

Code Quality and Compliance Tools

The build system enforces strict code style and licensing standards through automated checks.

swift-format

swift-format handles automatic code formatting and linting. The Makefile defines the swift-fmt target:

swift-fmt:
	@$(SWIFT) format --recursive --configuration .swift-format -i $(SWIFT_SRC)

Configuration is stored in .swift-format and .swift-format-nolint files at the repository root. The make fmt target combines formatting with license updates.

Hawkeye License Verification

hawkeye ensures every source file contains a valid Apache-2.0 license header. The Makefile provides two targets:

  • make update-licenses – adds or updates license headers across the source tree
  • make check-licenses – validates headers and fails the build if any are missing

The check-licenses target invokes a helper script to ensure the tool is installed:

check-licenses:
	@./scripts/ensure-hawkeye-exists.sh
	@.local/bin/hawkeye check --fail-if-unknown

Testing and Coverage Reporting

For test execution and coverage analysis, the build tools integrate with LLVM's coverage infrastructure.

llvm-cov and llvm-profdata

The Makefile provides coverage* recipes that leverage llvm-cov and llvm-profdata to generate detailed reports. Running make coverage builds the project with instrumentation enabled, executes the test suite via swift test, and aggregates coverage data into human-readable reports.

This integration allows the CI pipeline to track code coverage metrics across unit and integration tests.

Typical Development Workflow

Working with the apple/container project follows a standardized four-step process managed entirely through Make:

  1. Initialize Protocol Buffers – Run make protos to download protoc, build the Swift plugins, and generate gRPC stubs from .proto definitions.

  2. Compile the CLI – Execute make build to invoke swift build -c debug, or use make cli to build only the container executable target:

cli:
	@$(SWIFT) build -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION) --product container
	@install "$(BUILD_BIN_DIR)/container" "bin/container"
  1. Create Release Artifacts – Run make release to produce a signed .pkg installer suitable for distribution.

  2. Validate Changes – Execute make coverage to run the full test suite with coverage instrumentation, or run make fmt to auto-format code and update license headers before submitting.

Summary

  • Swift 6.2 and SPM form the compilation core, defined in Package.swift with the // swift-tools-version: 6.2 directive.
  • Make orchestrates the entire pipeline through Makefile and Protobuf.Makefile, managing dependencies beyond Swift compilation.
  • protoc with custom Swift plugins generates gRPC code from Protocol Buffer definitions in the Container Builder shim.
  • swift-format and hawkeye enforce code style and Apache-2.0 license compliance automatically.
  • llvm-cov generates coverage reports when running make coverage.
  • All tools are invocable through standard make commands without manual setup on macOS 26+ systems with a Swift toolchain installed.

Frequently Asked Questions

What version of Swift is required to build the apple/container project?

The project requires Swift 6.2 or later, as declared by the // swift-tools-version: 6.2 directive at the top of Package.swift. This version requirement ensures compatibility with the package manifest syntax and language features used throughout the codebase.

How do I generate the Protocol Buffer Swift files?

Run make protos from the repository root. This target downloads protoc (v26.1), builds the protoc-gen-swift and protoc-gen-grpc-swift-2 plugins using SPM, and generates Swift source files under Sources/ContainerBuild from the .proto definitions in the container-builder-shim dependency.

What build command produces the release installer?

Execute make release to generate a signed .pkg installer. This target configures SPM for release mode (swift build -c release), compiles the container executable, and assembles the final macOS installer package using the build configuration defined in the root Makefile.

Can I build the project without using Make?

While possible by running swift build directly, using Make is strongly recommended. The Makefile handles prerequisite steps like protobuf generation, license verification, and proper binary installation paths that pure SPM commands do not automatically manage.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →