Switch the containerization dependency from the github URL to a vendored copy (third_party/containerization, upstream commit 6b7b42ca) referenced by path, so we can carry a small local patch that upstream lacks: LinuxContainer.Configuration gains a `vmExtensions` field forwarded into VMConfiguration.extensions. Upstream already supports VMConfiguration.extensions + the VZInstanceExtension hook, but LinuxContainer — our only entry point — never forwarded them, so there was no way to attach a device (e.g. a memory balloon) to a container's VM. Tests/, docs/, examples/, images/ and the corresponding test targets are trimmed for footprint (we never build the dependency's tests). See PATCHES.md for the full diff vs. upstream and the re-vendoring procedure. Also adds the ContainerizationExtras product to NucleicCore (AddressAllocator, named in the configureVZ signature). Co-Authored-By: Claude Opus 4.8 <[email protected]>
275 lines
9.3 KiB
Makefile
275 lines
9.3 KiB
Makefile
# Copyright © 2025-2026 Apple Inc. and the Containerization project authors.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# Build configuration variables
|
|
BUILD_CONFIGURATION ?= debug
|
|
WARNINGS_AS_ERRORS ?= true
|
|
SWIFT_CONFIGURATION := $(if $(filter-out false,$(WARNINGS_AS_ERRORS)),-Xswiftc -warnings-as-errors) --disable-automatic-resolution
|
|
|
|
# Commonly used locations
|
|
UNAME_S := $(shell uname -s)
|
|
UNAME_M := $(shell uname -m)
|
|
KERNEL_ARCH := $(if $(filter $(UNAME_M),aarch64 arm64),arm64,$(UNAME_M))
|
|
# Candidate kernel filenames in bin/ (compiled vmlinuz first, kata-fetched vmlinux fallback).
|
|
ifeq ($(KERNEL_ARCH),x86_64)
|
|
KERNEL_CANDIDATES := bin/vmlinuz-x86_64 bin/vmlinux-x86_64
|
|
else
|
|
KERNEL_CANDIDATES := bin/vmlinux-$(KERNEL_ARCH)
|
|
endif
|
|
ifeq ($(UNAME_S),Darwin)
|
|
SWIFT ?= /usr/bin/swift
|
|
else
|
|
SWIFT ?= swift
|
|
endif
|
|
|
|
ROOT_DIR := $(shell git rev-parse --show-toplevel)
|
|
BUILD_BIN_DIR = $(shell $(SWIFT) build -c $(BUILD_CONFIGURATION) --show-bin-path)
|
|
COV_DATA_DIR = $(shell $(SWIFT) test --show-coverage-path | xargs dirname)
|
|
COV_REPORT_FILE = $(ROOT_DIR)/code-coverage-report
|
|
|
|
# Variables for libarchive integration
|
|
LIBARCHIVE_UPSTREAM_REPO := https://github.com/libarchive/libarchive
|
|
LIBARCHIVE_UPSTREAM_VERSION := v3.7.7
|
|
LIBARCHIVE_LOCAL_DIR := workdir/libarchive
|
|
|
|
KATA_BINARY_PACKAGE := https://github.com/kata-containers/kata-containers/releases/download/3.17.0/kata-static-3.17.0-arm64.tar.xz
|
|
|
|
SWIFT_VERSION := $(shell cat $(ROOT_DIR)/.swift-version)
|
|
SWIFT_SDK_URL := $(shell grep '^SWIFT_SDK_URL' vminitd/Makefile | head -1 | sed 's/.*:= *//')
|
|
SWIFT_SDK_CHECKSUM := $(shell grep '^SWIFT_SDK_CHECKSUM' vminitd/Makefile | head -1 | sed 's/.*:= *//')
|
|
LINUX_DEV_IMAGE := containerization-dev:$(SWIFT_VERSION)
|
|
|
|
# Run a command inside a Linux dev container.
|
|
# Requires 'container' (https://github.com/apple/container).
|
|
# Automatically builds the dev image if it doesn't exist.
|
|
define linux_run
|
|
@if ! command -v container > /dev/null 2>&1; then \
|
|
echo "Error: 'container' CLI not found. Install from https://github.com/apple/container"; \
|
|
exit 1; \
|
|
fi
|
|
@if ! container image list -q 2>/dev/null | grep -q "$(LINUX_DEV_IMAGE)"; then \
|
|
echo "Building Linux dev container image..."; \
|
|
$(MAKE) linux-image; \
|
|
fi
|
|
@container run --memory 8gb --cpus 4 -v $(ROOT_DIR):/workspace -w /workspace $(LINUX_DEV_IMAGE) \
|
|
bash -c "$(1)"
|
|
endef
|
|
|
|
include Protobuf.Makefile
|
|
.DEFAULT_GOAL := all
|
|
|
|
.PHONY: deps
|
|
deps:
|
|
ifeq ($(UNAME_S),Linux)
|
|
sudo apt-get install -y libarchive-dev libbz2-dev liblzma-dev libssl-dev
|
|
else
|
|
@echo "No additional dependencies required on $(UNAME_S)"
|
|
endif
|
|
|
|
ifeq ($(UNAME_S),Darwin)
|
|
.PHONY: linux-image
|
|
linux-image:
|
|
container build \
|
|
--progress plain \
|
|
-f images/linux-dev/Dockerfile \
|
|
--build-arg SWIFT_VERSION=$(SWIFT_VERSION) \
|
|
--build-arg SWIFT_SDK_URL=$(SWIFT_SDK_URL) \
|
|
--build-arg SWIFT_SDK_CHECKSUM=$(SWIFT_SDK_CHECKSUM) \
|
|
-t $(LINUX_DEV_IMAGE) \
|
|
.
|
|
|
|
.PHONY: linux-build
|
|
linux-build: LIBC ?= musl
|
|
linux-build:
|
|
ifeq ($(LIBC),all)
|
|
$(call linux_run,make containerization && make -C vminitd LIBC=glibc && make -C vminitd LIBC=musl)
|
|
else
|
|
$(call linux_run,make containerization && make -C vminitd LIBC=$(LIBC))
|
|
endif
|
|
|
|
.PHONY: linux-test
|
|
linux-test:
|
|
$(call linux_run,swift test $(SWIFT_CONFIGURATION))
|
|
endif
|
|
|
|
.PHONY: all
|
|
all: containerization
|
|
all: init
|
|
|
|
.PHONY: release
|
|
release: BUILD_CONFIGURATION = release
|
|
release: all
|
|
|
|
.PHONY: containerization
|
|
containerization:
|
|
@echo Building containerization binaries...
|
|
@$(SWIFT) --version
|
|
@$(SWIFT) build -c $(BUILD_CONFIGURATION) $(SWIFT_CONFIGURATION)
|
|
|
|
@echo Copying containerization binaries...
|
|
@mkdir -p bin
|
|
@install "$(BUILD_BIN_DIR)/cctl" ./bin/
|
|
ifeq ($(UNAME_S),Darwin)
|
|
@install "$(BUILD_BIN_DIR)/containerization-integration" ./bin/
|
|
|
|
@echo Signing containerization binaries...
|
|
@codesign --force --sign - --timestamp=none --entitlements=signing/vz.entitlements bin/cctl
|
|
@codesign --force --sign - --timestamp=none --entitlements=signing/vz.entitlements bin/containerization-integration
|
|
endif
|
|
|
|
.PHONY: init
|
|
init: containerization vminitd
|
|
@echo Creating init.ext4...
|
|
@rm -f bin/init.rootfs.tar.gz bin/init.block bin/initfs.ext4
|
|
@./bin/cctl rootfs create \
|
|
--vminitd vminitd/bin/vminitd \
|
|
--vmexec vminitd/bin/vmexec \
|
|
--ext4 ./bin/initfs.ext4 \
|
|
--label org.opencontainers.image.source=https://github.com/apple/containerization \
|
|
--image vminit:latest \
|
|
bin/init.rootfs.tar.gz
|
|
|
|
.PHONY: cross-prep
|
|
cross-prep:
|
|
@"$(MAKE)" -C vminitd cross-prep
|
|
|
|
.PHONY: vminitd
|
|
vminitd:
|
|
@mkdir -p ./bin
|
|
@"$(MAKE)" -C vminitd BUILD_CONFIGURATION=$(BUILD_CONFIGURATION) WARNINGS_AS_ERRORS=$(WARNINGS_AS_ERRORS)
|
|
|
|
.PHONY: update-libarchive-source
|
|
update-libarchive-source:
|
|
@echo Updating the libarchive source files...
|
|
@git clone $(LIBARCHIVE_UPSTREAM_REPO) --depth 1 --branch $(LIBARCHIVE_UPSTREAM_VERSION) "$(LIBARCHIVE_LOCAL_DIR)"
|
|
@cp "$(LIBARCHIVE_LOCAL_DIR)/libarchive/archive_entry.h" Sources/ContainerizationArchive/CArchive/include
|
|
@cp "$(LIBARCHIVE_LOCAL_DIR)/libarchive/archive.h" Sources/ContainerizationArchive/CArchive/include
|
|
@cp "$(LIBARCHIVE_LOCAL_DIR)/COPYING" Sources/ContainerizationArchive/CArchive/COPYING
|
|
@rm -rf "$(LIBARCHIVE_LOCAL_DIR)"
|
|
|
|
.PHONY: test
|
|
test:
|
|
@echo Testing all test targets...
|
|
@$(SWIFT) test --enable-code-coverage $(SWIFT_CONFIGURATION)
|
|
|
|
.PHONY: coverage
|
|
coverage: test
|
|
@echo Generating code coverage report...
|
|
@xcrun llvm-cov show --compilation-dir=`pwd` \
|
|
-instr-profile=$(COV_DATA_DIR)/default.profdata \
|
|
--ignore-filename-regex=".build/" \
|
|
--ignore-filename-regex=".pb.swift" \
|
|
--ignore-filename-regex=".proto" \
|
|
--ignore-filename-regex=".grpc.swift" \
|
|
$(BUILD_BIN_DIR)/containerizationPackageTests.xctest/Contents/MacOS/containerizationPackageTests > $(COV_REPORT_FILE)
|
|
@echo Code coverage report generated: $(COV_REPORT_FILE)
|
|
|
|
.PHONY: integration
|
|
integration:
|
|
@kernel="$$(for f in $(KERNEL_CANDIDATES); do [ -f $$f ] && echo $$f && break; done)"; \
|
|
if [ -z "$$kernel" ]; then \
|
|
echo "No kernel found. Looked for: $(KERNEL_CANDIDATES). See fetch-default-kernel target or build via kernel/Makefile."; \
|
|
exit 1; \
|
|
fi; \
|
|
echo "Running the integration tests with kernel $$kernel..."; \
|
|
./bin/containerization-integration --kernel "$$kernel"
|
|
|
|
.PHONY: fetch-default-kernel
|
|
fetch-default-kernel:
|
|
@mkdir -p .local/ bin/
|
|
ifeq (,$(wildcard .local/kata.tar.gz))
|
|
@curl -SsL -o .local/kata.tar.gz ${KATA_BINARY_PACKAGE}
|
|
endif
|
|
ifeq (,$(wildcard .local/vmlinux-$(KERNEL_ARCH)))
|
|
@tar -zxf .local/kata.tar.gz -C .local/ --strip-components=1
|
|
@cp -L .local/opt/kata/share/kata-containers/vmlinux.container .local/vmlinux-$(KERNEL_ARCH)
|
|
endif
|
|
ifeq (,$(wildcard bin/vmlinux-$(KERNEL_ARCH)))
|
|
@cp .local/vmlinux-$(KERNEL_ARCH) bin/vmlinux-$(KERNEL_ARCH)
|
|
endif
|
|
|
|
.PHONY: check
|
|
check: swift-fmt-check check-licenses
|
|
|
|
.PHONY: fmt
|
|
fmt: swift-fmt update-licenses
|
|
|
|
.PHONY: swift-fmt
|
|
SWIFT_SRC = $(shell find . -type f -name '*.swift' -not -path "*/.*" -not -path "*.pb.swift" -not -path "*.grpc.swift" -not -path "*/checkouts/*")
|
|
swift-fmt:
|
|
@echo Applying the standard code formatting...
|
|
@$(SWIFT) format --recursive --configuration .swift-format -i $(SWIFT_SRC)
|
|
|
|
swift-fmt-check:
|
|
@echo Checking code formatting compliance...
|
|
@$(SWIFT) format lint --recursive --strict --configuration .swift-format-nolint $(SWIFT_SRC)
|
|
|
|
.PHONY: update-licenses
|
|
update-licenses:
|
|
@echo Updating license headers...
|
|
@./scripts/ensure-hawkeye-exists.sh
|
|
@.local/bin/hawkeye format --fail-if-unknown --fail-if-updated false
|
|
|
|
.PHONY: check-licenses
|
|
check-licenses:
|
|
@echo Checking license headers existence in source files...
|
|
@./scripts/ensure-hawkeye-exists.sh
|
|
@.local/bin/hawkeye check --fail-if-unknown
|
|
|
|
.PHONY: pre-commit
|
|
pre-commit:
|
|
cp Scripts/pre-commit.fmt .git/hooks
|
|
touch .git/hooks/pre-commit
|
|
cat .git/hooks/pre-commit | grep -v 'hooks/pre-commit\.fmt' > /tmp/pre-commit.new || true
|
|
echo 'PRECOMMIT_NOFMT=$${PRECOMMIT_NOFMT} $$(git rev-parse --show-toplevel)/.git/hooks/pre-commit.fmt' >> /tmp/pre-commit.new
|
|
mv /tmp/pre-commit.new .git/hooks/pre-commit
|
|
chmod +x .git/hooks/pre-commit
|
|
|
|
.PHONY: serve-docs
|
|
serve-docs:
|
|
@echo 'to browse: open http://127.0.0.1:8000/containerization/documentation/'
|
|
@rm -rf _serve
|
|
@mkdir -p _serve
|
|
@cp -a _site _serve/containerization
|
|
@python3 -m http.server --bind 127.0.0.1 --directory ./_serve
|
|
|
|
.PHONY: docs
|
|
docs:
|
|
@echo Updating API documentation...
|
|
@rm -rf _site
|
|
@scripts/make-docs.sh _site containerization
|
|
|
|
.PHONY: cleancontent
|
|
cleancontent:
|
|
@echo Cleaning the content...
|
|
@rm -rf ~/Library/Application\ Support/com.apple.containerization
|
|
|
|
.PHONY: examples
|
|
examples:
|
|
@echo Building examples...
|
|
@mkdir -p bin
|
|
@"$(MAKE)" -C examples/sandboxy build BUILD_CONFIGURATION=$(BUILD_CONFIGURATION)
|
|
@install examples/sandboxy/bin/sandboxy ./bin/
|
|
@codesign --force --sign - --timestamp=none --entitlements=signing/vz.entitlements bin/sandboxy
|
|
|
|
.PHONY: clean
|
|
clean:
|
|
@echo Cleaning build files...
|
|
@rm -rf bin/
|
|
@rm -rf _site/
|
|
@rm -rf _serve/
|
|
@rm -f $(COV_REPORT_FILE)
|
|
@$(SWIFT) package clean
|
|
@"$(MAKE)" -C vminitd clean
|