# syntax=docker/dockerfile:1.6 # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 ARG OSXCROSS_IMAGE=crazymax/osxcross:latest ARG PYTHON_VERSION=3.12 FROM ${OSXCROSS_IMAGE} AS osxcross FROM python:${PYTHON_VERSION}-slim AS builder ARG TARGETARCH ARG NEMOCLAW_CARGO_VERSION ARG CARGO_TARGET_CACHE_SCOPE=default ENV PATH="/root/.cargo/bin:/usr/local/bin:/osxcross/bin:${PATH}" ENV LD_LIBRARY_PATH="/osxcross/lib" COPY --from=osxcross /osxcross /osxcross RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ ca-certificates \ clang \ curl \ libssl-dev \ pkg-config \ && rm -rf /var/lib/apt/lists/* # aws-lc-sys probes with --target=arm64-apple-macosx and clang then looks for # arm64-apple-macosx-ld. Provide a linker alias to osxcross ld64. RUN ln -sf /osxcross/bin/arm64-apple-darwin25.1-ld /usr/local/bin/arm64-apple-macosx-ld RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y RUN rustup target add aarch64-apple-darwin RUN pip install --no-cache-dir maturin WORKDIR /build ENV CC_aarch64_apple_darwin=oa64-clang ENV CXX_aarch64_apple_darwin=oa64-clang++ ENV AR_aarch64_apple_darwin=aarch64-apple-darwin25.1-ar ENV CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER=oa64-clang ENV CARGO_TARGET_AARCH64_APPLE_DARWIN_AR=aarch64-apple-darwin25.1-ar # Copy dependency manifests first for better caching. COPY Cargo.toml Cargo.lock ./ COPY crates/navigator-cli/Cargo.toml crates/navigator-cli/Cargo.toml COPY crates/navigator-core/Cargo.toml crates/navigator-core/Cargo.toml COPY crates/navigator-providers/Cargo.toml crates/navigator-providers/Cargo.toml COPY crates/navigator-router/Cargo.toml crates/navigator-router/Cargo.toml COPY crates/navigator-sandbox/Cargo.toml crates/navigator-sandbox/Cargo.toml COPY crates/navigator-server/Cargo.toml crates/navigator-server/Cargo.toml COPY crates/navigator-bootstrap/Cargo.toml crates/navigator-bootstrap/Cargo.toml COPY crates/navigator-core/build.rs crates/navigator-core/build.rs COPY proto/ proto/ # Create dummy source files to build dependencies. RUN mkdir -p crates/navigator-cli/src crates/navigator-core/src crates/navigator-providers/src crates/navigator-router/src crates/navigator-sandbox/src crates/navigator-server/src crates/navigator-bootstrap/src && \ echo "fn main() {}" > crates/navigator-cli/src/main.rs && \ echo "fn main() {}" > crates/navigator-sandbox/src/main.rs && \ echo "fn main() {}" > crates/navigator-server/src/main.rs && \ touch crates/navigator-core/src/lib.rs && \ touch crates/navigator-providers/src/lib.rs && \ touch crates/navigator-router/src/lib.rs && \ touch crates/navigator-bootstrap/src/lib.rs # Build dependencies only (cached unless Cargo.toml/lock changes). RUN --mount=type=cache,id=cargo-registry-python-wheels-macos-${TARGETARCH},sharing=locked,target=/root/.cargo/registry \ --mount=type=cache,id=cargo-git-python-wheels-macos-${TARGETARCH},sharing=locked,target=/root/.cargo/git \ --mount=type=cache,id=cargo-target-python-wheels-macos-${TARGETARCH}-${CARGO_TARGET_CACHE_SCOPE},sharing=locked,target=/build/target \ cargo build --release --target aarch64-apple-darwin -p navigator-cli 2>/dev/null || true # Copy actual source code and Python packaging files. COPY crates/ crates/ COPY pyproject.toml README.md ./ COPY dev-sandbox-policy.yaml ./ COPY python/ python/ # Touch source files to ensure they're rebuilt (not the cached dummy). # Touch build.rs and proto files to force proto code regeneration when the # cargo target cache mount retains stale OUT_DIR artifacts from prior builds. RUN touch crates/navigator-cli/src/main.rs \ crates/navigator-cli/src/lib.rs \ crates/navigator-bootstrap/src/lib.rs \ crates/navigator-core/src/lib.rs \ crates/navigator-providers/src/lib.rs \ crates/navigator-router/src/lib.rs \ crates/navigator-sandbox/src/main.rs \ crates/navigator-server/src/main.rs \ crates/navigator-core/build.rs \ proto/*.proto RUN --mount=type=cache,id=cargo-registry-python-wheels-macos-${TARGETARCH},sharing=locked,target=/root/.cargo/registry \ --mount=type=cache,id=cargo-git-python-wheels-macos-${TARGETARCH},sharing=locked,target=/root/.cargo/git \ --mount=type=cache,id=cargo-target-python-wheels-macos-${TARGETARCH}-${CARGO_TARGET_CACHE_SCOPE},sharing=locked,target=/build/target \ if [ -n "${NEMOCLAW_CARGO_VERSION:-}" ]; then \ sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${NEMOCLAW_CARGO_VERSION}"'"/}' Cargo.toml; \ fi && \ maturin build --release --target aarch64-apple-darwin --out /wheels FROM scratch AS wheels COPY --from=builder /wheels/*.whl /