diff --git a/.github/workflows/build_ffmpeg.yaml b/.github/workflows/build_ffmpeg.yaml index 032687ab7..c4e11f4a2 100644 --- a/.github/workflows/build_ffmpeg.yaml +++ b/.github/workflows/build_ffmpeg.yaml @@ -14,6 +14,8 @@ on: pull_request: paths: - packaging/build_ffmpeg.sh + - packaging/build_ffmpeg_arm64.bat + - packaging/build_ffmpeg.bat - .github/workflows/build_ffmpeg.yaml # self reference schedule: - cron: '0 0 * * 0' # on sunday @@ -119,3 +121,41 @@ jobs: artifact_dir="${RUNNER_ARTIFACT_DIR}/$(date +%Y-%m-%d)/windows_$(uname -m)" mkdir -p "${artifact_dir}" mv ffmpeg.tar.gz "${artifact_dir}/${FFMPEG_VERSION}.tar.gz" + + # Native Windows ARM64 counterpart of LGPL-Windows. Runs on GitHub's + # standard `windows-11-arm` hosted runner (GA for public repos since + # 2025-08-07) instead of pytorch/test-infra's windows_job.yml wrapper, + # since that reusable workflow targets test-infra's own x86_64 runner + # fleet. This job only produces a build artifact; per this workflow's + # header comment, uploading it to the S3 bucket consumed by + # BUILD_AGAINST_ALL_FFMPEG_FROM_S3 is a separate, manual, maintainer-only + # step that must be done once to unblock windows_wheel.yaml's arm64 build. + LGPL-Windows-arm64: + strategy: + fail-fast: false + matrix: + ffmpeg-version: ["4.4.4", "5.1.4", "6.1.1", "7.0.1", "8.0", "9.0"] + runs-on: windows-11-arm + defaults: + run: + shell: bash -l -eo pipefail {0} + steps: + - name: Check out repo + uses: actions/checkout@v6 + + - name: Build FFmpeg (LGPL, decode/encode symbols only) and package artifact + run: | + export FFMPEG_VERSION="${{ matrix.ffmpeg-version }}" + export FFMPEG_ROOT="${PWD}/ffmpeg" + + packaging/build_ffmpeg_arm64.bat + + tar -cf ffmpeg.tar.gz ffmpeg/include ffmpeg/bin + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ffmpeg-lgpl-windows_arm64-${{ matrix.ffmpeg-version }} + path: ffmpeg.tar.gz + if-no-files-found: error + retention-days: 14 diff --git a/.github/workflows/build_libavif.yaml b/.github/workflows/build_libavif.yaml index c72fc7152..71aeb3ae3 100644 --- a/.github/workflows/build_libavif.yaml +++ b/.github/workflows/build_libavif.yaml @@ -14,6 +14,7 @@ on: paths: - packaging/build_libavif.sh - packaging/build_libavif.bat + - packaging/build_libavif_arm64.bat - .github/workflows/build_libavif.yaml schedule: - cron: '0 0 * * 0' # on sunday @@ -121,3 +122,39 @@ jobs: artifact_dir="${RUNNER_ARTIFACT_DIR}/$(date +%Y-%m-%d)/windows_$(uname -m)" mkdir -p "${artifact_dir}" mv libavif.tar.gz "${artifact_dir}/${LIBAVIF_VERSION}.tar.gz" + + # Native Windows ARM64 counterpart of libavif-Windows. See the equivalent + # LGPL-Windows-arm64 job in build_ffmpeg.yaml for why this uses GitHub's + # standard `windows-11-arm` hosted runner directly instead of + # pytorch/test-infra's windows_job.yml. Same manual-S3-upload caveat + # applies here too. + libavif-Windows-arm64: + strategy: + fail-fast: false + matrix: + libavif-version: ["1.4.2"] + runs-on: windows-11-arm + defaults: + run: + shell: bash -l -eo pipefail {0} + steps: + - name: Check out repo + uses: actions/checkout@v6 + + - name: Build libavif (decode-only) and package artifact + run: | + export LIBAVIF_VERSION="${{ matrix.libavif-version }}" + export LIBAVIF_ROOT="${PWD}/libavif" + + packaging/build_libavif_arm64.bat + + # Include lib (import lib) and bin (DLL) so the consumer has both. + tar -cf libavif.tar.gz libavif/include libavif/lib libavif/bin libavif/licenses + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: libavif-windows_arm64-${{ matrix.libavif-version }} + path: libavif.tar.gz + if-no-files-found: error + retention-days: 14 diff --git a/.github/workflows/windows_arm64_wheel.yaml b/.github/workflows/windows_arm64_wheel.yaml new file mode 100644 index 000000000..a080ba19e --- /dev/null +++ b/.github/workflows/windows_arm64_wheel.yaml @@ -0,0 +1,136 @@ +name: Windows ARM64 Wheel + +on: + workflow_dispatch: + pull_request: + paths: + - .github/workflows/windows_arm64_wheel.yaml + - packaging/build_ffmpeg.sh + - packaging/build_ffmpeg_arm64.bat + - packaging/build_libavif.sh + - packaging/build_libavif_arm64.bat + - packaging/vc_env_helper_arm64.bat + - packaging/install_build_dependencies.sh + - packaging/pre_build_script.sh + - packaging/post_build_script.sh + - packaging/install_pytorch.sh + - packaging/install_torchcodec_wheel.sh + - packaging/install_test_dependencies.sh + - packaging/remove_src.sh + - packaging/assert_ffmpeg_version.py + - test/smoke_test.py + - pyproject.toml + - CMakeLists.txt + - src/torchcodec/_core/** + push: + branches: + - winarm64-hackathon + paths: + - .github/workflows/windows_arm64_wheel.yaml + - packaging/build_ffmpeg.sh + - packaging/build_ffmpeg_arm64.bat + - packaging/build_libavif.sh + - packaging/build_libavif_arm64.bat + - packaging/vc_env_helper_arm64.bat + - packaging/install_build_dependencies.sh + - packaging/pre_build_script.sh + - packaging/post_build_script.sh + - packaging/install_pytorch.sh + - packaging/install_torchcodec_wheel.sh + - packaging/install_test_dependencies.sh + - packaging/remove_src.sh + - packaging/assert_ffmpeg_version.py + - test/smoke_test.py + - pyproject.toml + - CMakeLists.txt + - src/torchcodec/_core/** + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref_name }}-${{ github.ref_type == 'branch' && github.sha }}-${{ github.event_name == 'workflow_dispatch' }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + build-and-test: + runs-on: windows-11-arm + defaults: + run: + shell: bash -l -eo pipefail {0} + env: + FFMPEG_VERSION: "9.0" + LIBAVIF_VERSION: "1.4.2" + TORCHCODEC_BUILD_HEIC: "0" + FAIL_WITHOUT_IMAGE_CODECS: "1" + FAIL_WITHOUT_HEIC: "0" + steps: + - name: Check out repo + uses: actions/checkout@v6 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Update pip + run: python -m pip install --upgrade pip + + - name: Install PyTorch + run: bash packaging/install_pytorch.sh cpu "torch torchvision" + + - name: Install build dependencies + run: | + python -m pip install pybind11 "scikit-build-core>=0.10" ninja + + - name: Build FFmpeg + run: | + export FFMPEG_ROOT="${PWD}/ffmpeg" + packaging/build_ffmpeg_arm64.bat + + - name: Build libavif + run: | + export LIBAVIF_ROOT="${PWD}/libavif" + packaging/build_libavif_arm64.bat + + - name: Build wheel + shell: cmd + run: | + call packaging\vc_env_helper_arm64.bat ^ + set BUILD_AGAINST_ALL_FFMPEG_FROM_S3= ^&^& ^ + set BUILD_AGAINST_ALL_FFMPEG_FROM_LOCAL=1 ^&^& ^ + set FFMPEG_ROOT=%CD%\ffmpeg ^&^& ^ + set LIBAVIF_ROOT=%CD%\libavif ^&^& ^ + set TORCHCODEC_BUILD_HEIC=0 ^&^& ^ + python -m build --wheel -vvv --no-isolation + + - name: Repair and inspect wheel + run: | + bash packaging/post_build_script.sh + ls -R + ls -R dist || true + ls -R wheelhouse || true + + - name: Upload wheel artifact + uses: actions/upload-artifact@v4 + with: + name: torchcodec-windows-arm64-py311 + path: | + dist/*.whl + wheelhouse/*.whl + if-no-files-found: error + retention-days: 14 + + - name: Remove src/ folder + run: bash packaging/remove_src.sh + + - name: Install torchcodec from the wheel + run: bash packaging/install_torchcodec_wheel.sh + + - name: Install test dependencies + run: bash packaging/install_test_dependencies.sh false + + - name: Run ARM64 smoke test + run: | + python packaging/assert_ffmpeg_version.py 9 + FAIL_WITHOUT_IMAGE_CODECS=1 FAIL_WITHOUT_HEIC=0 pytest --override-ini="addopts=-v" test/smoke_test.py --tb=short diff --git a/ARM64-DEMO-RUNBOOK.md b/ARM64-DEMO-RUNBOOK.md new file mode 100644 index 000000000..5f99ea5ad --- /dev/null +++ b/ARM64-DEMO-RUNBOOK.md @@ -0,0 +1,213 @@ +# ARM64 Machine Runbook — Sync, Test, and Record the Demo Video + +This is the **checked-in prompt/guide** for the next step: running this +submission's real hardware validation *locally* on a physical Windows-on-Arm +machine (Copilot+ PC, Surface Pro X, etc.) and turning it into a recorded +demo video. Everything referenced here already exists in this repo (`Generated +Files/demo/*`) or on the live fork +(`https://github.com/yeelam-gordon/torchcodec`, branch `winarm64-hackathon`). + +This does not replace the real hardware CI evidence already obtained on +GitHub's hosted `windows-11-arm` runners (see +`Generated Files/hackathon-fleet/agents/agent6/output/arm-readiness.r1.md`) +— it *adds* a second, independent, local proof point plus the recorded +artifact needed for a demo video. + +## 0. What you need + +- A physical Windows-on-Arm (aarch64) machine — Copilot+ PC, Surface Pro X/11, + Dev Kit 2023, etc. — with admin rights. +- [GitHub Copilot CLI](https://docs.github.com/copilot/how-tos/set-up/install-copilot-cli) + installed and authenticated (`copilot` on `PATH`, `gh auth login` done as + your own GitHub account — no special repo permission needed, this is all + read/fork-owned). +- `git`, `gh` CLI on `PATH`. +- (For the slidecast render step, run on this **or any** machine — it does + not need to be ARM64): `pip install -r scripts/requirements.txt` inside + the `slidecast` skill folder (edge-tts), `npm install` there too + (Playwright+Chromium), and `ffmpeg`/`ffprobe` on `PATH`. + +## 1. Sync the forked repo + +```powershell +git clone https://github.com/yeelam-gordon/torchcodec.git +cd torchcodec +git checkout winarm64-hackathon +git log --oneline -5 +# expect HEAD = 541f218 "Fix FFmpeg arm64 build: don't run under vcvarsall ..." +``` + +This branch already contains the working Arm64 CI fixes (`711ff55`, +`22993a4`, `541f218`) proven green on GitHub-hosted `windows-11-arm` runners. +Running the same builder scripts **locally on real Arm64 hardware** is the +natural next validation step — same code path, different (physical) machine. + +## 2. Run the Copilot CLI prompt on the ARM64 machine + +On the Arm64 machine, in the cloned `torchcodec` directory, run: + +```powershell +copilot +``` + +Then paste this prompt (also usable non-interactively via +`copilot -p ""` — check `copilot --help` for the current flag on +your installed version): + +> You are on a real Windows-on-Arm (aarch64) machine, in a clone of +> `yeelam-gordon/torchcodec` on branch `winarm64-hackathon`. This repo adds +> native Arm64 CI builder scripts for FFmpeg and libavif +> (`packaging/build_ffmpeg_arm64.bat`, `packaging/build_libavif_arm64.bat`), +> already verified green on GitHub's hosted `windows-11-arm` runners (see +> `packaging/build_ffmpeg.sh` and `packaging/build_libavif.sh` for the +> shared, architecture-aware build logic; MSYS2's CLANGARM64 subsystem +> supplies the native aarch64 clang toolchain). +> +> Your task: +> 1. Confirm this machine is genuinely ARM64: run +> `(Get-CimInstance Win32_Processor).Architecture` (expect `12`, ARM64) +> and/or `$env:PROCESSOR_ARCHITECTURE` (expect `ARM64`). Record the exact +> output. +> 2. Install MSYS2 if not already present (`choco install -y msys2 --package-parameters "/NoUpdate"`, +> or use an existing install). +> 3. Run `packaging/build_libavif_arm64.bat` from a `cmd.exe` or PowerShell +> shell in the repo root. Capture full console output to a log file +> (e.g. `Tee-Object -FilePath libavif-local-run.log`). +> 4. Run `packaging/build_ffmpeg_arm64.bat` the same way, logging to +> `ffmpeg-local-run.log`. +> 5. Report pass/fail for each, with the log tail (last ~30 lines) as +> evidence, and confirm the expected output artifacts exist +> (`libavif.tar.gz`, `ffmpeg.tar.gz`, or whatever the scripts produce +> under their working directories — check the script source if unsure). +> 6. Do not modify any files unless a genuine local-only environment issue +> (e.g. a missing MSYS2 package) requires it — if so, explain exactly +> what and why before changing anything, and keep the change minimal. +> 7. Summarize: architecture confirmed, both builds pass/fail, artifact +> paths, and total wall-clock time for each build (useful for the demo +> narration's "how long does a native Arm64 build take" beat). + +This closes the loop: the same fixes that passed on GitHub's hosted +`windows-11-arm` fleet are now also verified on a real physical Arm64 +device you control, with a live terminal session you can record. + +## 3. Record the terminal session (for the video's "live proof" shot) + +Use your OS screen recorder (Xbox Game Bar `Win+G`, OBS, etc.) while running +step 2's Copilot CLI session, or re-run the two `.bat` scripts directly and +record that terminal window. Save the recording as +`Generated Files/demo/assets/arm64-live-run.mp4` (create the `assets/` +folder if it doesn't exist) — this is the raw clip the slidecast video will +embed. + +## 4. Render the narrated demo video with slidecast + +**UPDATE: the slidecast HTML deck, storyboard, and rendered MP4 have already +been built in this repo** — see `Generated Files/demo/deck/deck.html`, +`Generated Files/demo/deck/storyboard.json`, and the finished +`Generated Files/demo/deck/build/final.mp4` (150s, 1920x1080, H.264/AAC, +burned subtitles, 7 slides matching `narration.txt`/`shot-list.md`). This +covers everything that does **not** require the physical ARM64 machine. The +steps below remain accurate for reference/re-render, and for adding the +step-3 live-Arm64-terminal clip once it exists (currently the deck does not +yet embed that clip — see "What's left" below). + +The demo *content* (script, shot list, narration, subtitles) was already +fully authored in `Generated Files/demo/`: + +- `demo-script.md` — narration beats and section timing +- `shot-list.md` — the exact shot sequence (title → gap evidence → code + diffs → **live GitHub Actions run** → **live local Arm64 terminal** → + bug-hunt recap → closing) +- `narration.txt` — the voiceover script text +- `subtitles.srt` — pre-timed subtitle cues matching the narration +- `impact-evidence.md` — every number/claim's source, for slide content + +To turn these into an actual slidecast HTML deck + narrated MP4: + +```powershell +$slidecastRoot = "C:\Users\yeelam\OneDrive - Microsoft\Documents\.copilot\skills\slidecast" + +# 1. Scaffold a deck package next to the demo assets (one-time): +mkdir "Generated Files\demo\deck" +Copy-Item "$slidecastRoot\templates\*" "Generated Files\demo\deck" -Recurse + +# 2. Author Generated Files\demo\deck\deck.html slides from shot-list.md's +# 12 shots (title, gap-evidence, code diffs, live GH Actions run, +# live local ARM64 run, bug-hunt recap, closing) using the blocks in +# templates/partials/blocks.html. Embed the step-3 recording as a +# slide's embeddedVideo clip for the "live local Arm64 run" shot. + +# 3. Write Generated Files\demo\deck\storyboard.json from narration.txt + +# subtitles.srt timing (one storyboard step per narration.txt paragraph, +# cue.toLabel pointing at each slide's sc.cue() label). + +# 4. Build: +python "$slidecastRoot\scripts\build.py" ` + --storyboard "Generated Files\demo\deck\storyboard.json" ` + --deck "Generated Files\demo\deck\deck.html" ` + --package-root "Generated Files\demo\deck" ` + --out "Generated Files\demo\deck\build" +# -> Generated Files\demo\deck\build\final.mp4 +``` + +See the `slidecast` skill's own `SKILL.md` for the full authoring workflow +(style preset selection, `sc.*` animation helpers, storyboard schema, and +the `[[cue]]` narration-sync token) — this runbook only maps *this +project's* existing demo content onto that pipeline; it does not duplicate +slidecast's own instructions. + +## 5. What "done" looks like + +- ✅ `Generated Files/demo/deck/build/final.mp4` — **already rendered**: the + finished narrated demo video (150s, 1920x1080, burned subtitles synced to + `narration.txt`, 7 animated slides per `shot-list.md`). This part required + no ARM64 hardware and is complete. +- ⬜ `libavif-local-run.log` and `ffmpeg-local-run.log` — still needed: + showing pass on a real *local* Arm64 device (independent confirmation, + complementing the already-obtained GitHub-hosted `windows-11-arm` CI + results in `arm-readiness.r1.md`). +- ⬜ `Generated Files/demo/assets/arm64-live-run.mp4` — still needed: the raw + recorded proof from step 3, to optionally be composited as an embedded + clip into a future revision of the deck (e.g. replacing/extending slide + s5's "bug hunt" beat), re-running `build.py` after adding it to + `storyboard.json`'s `embeddedVideo` field per slide. + +## What's left (only requires the physical machine) + +Steps 1–3 (sync, run the Copilot CLI prompt, record the terminal session) +are the only remaining items — they need physical Windows-on-Arm hardware +that this authoring session does not have. Everything else (deck, storyboard, +rendered video) is done and checked into this repo. + +## 6. PR status (companion to this runbook) + +There are **two** open PRs carrying the 3 real-hardware bugfix commits: + +- **Upstream** (for eventual real merge): + https://github.com/meta-pytorch/torchcodec/pull/1673 + (from `yeelam-gordon:winarm64-hackathon` into `meta-pytorch:main`). This + account is an external contributor here with no Triage/Write permission, + so the `copilot-pr-autopilot` skill's review-request API call correctly + fails with `FORBIDDEN` — a documented, accepted limitation, not a bug. +- **Fork-local** (primary target for the automated review loop): + https://github.com/yeelam-gordon/torchcodec/pull/1 + (`main` ← `winarm64-hackathon`, entirely within the fork, where this + account has full admin/write). The autopilot's `01-request-review.ps1` + runs here without permission errors, but Copilot Code Review has not yet + started reviewing as of this writing (`LatestCopilotReview: null`, + `CopilotPending: true`) even after the mutation call succeeded — this may + require either the UI's 🔄 button next to `copilot-pull-request-reviewer` + in the Reviewers panel (the skill's own docs note the internal endpoint + behind that button is not in the public API), a `synchronize` event from + a new push, or Copilot Code Review may simply not be enabled for this + personal/fork repo — check Settings → Code & automation → Copilot on + https://github.com/yeelam-gordon/torchcodec/settings if the loop still + does not start after a fresh push. + +To retry: push a substantive commit (e.g. the local-Arm64-run log/results +from this runbook) to either PR's branch to fire a `synchronize` event, +then re-run +`copilot-pr-autopilot\scripts\02-check-review-status.ps1 -Owner yeelam-gordon -Repo torchcodec -PrNumber 1` +(use `pwsh`, not Windows PowerShell 5.1, to avoid a parser bug in that +script) to check convergence, and drive any resulting review threads +through the skill's steps 3–8 as a single iteration. diff --git a/packaging/build_ffmpeg.sh b/packaging/build_ffmpeg.sh index 7f1631c0e..9ff7fa892 100755 --- a/packaging/build_ffmpeg.sh +++ b/packaging/build_ffmpeg.sh @@ -36,7 +36,22 @@ trap 'cleanup $?' EXIT cd "${build_dir}" curl -LsS -o ffmpeg.tar.gz "${archive}" tar -xf ffmpeg.tar.gz --strip-components 1 + +# FFmpeg's configure hardcodes cc_default="gcc"/cxx_default="g++" and does +# NOT read $CC/$CXX from the environment -- only the explicit --cc=/--cxx= +# flags override it. MSYS2's CLANGARM64 subsystem (used for the native +# Windows Arm64 build) ships mingw-w64-clang-aarch64-toolchain, which +# provides clang/clang++ but no gcc/g++ at all, so configure's default gcc +# probe fails with "gcc is unable to create an executable file." Every other +# platform this script runs on (Linux, macOS, the existing Windows x86_64 +# MINGW64 job) does have a working gcc and is unaffected by this override. +extra_configure_args=() +if [[ "${MSYSTEM:-}" == "CLANGARM64" ]]; then + extra_configure_args+=(--cc=clang --cxx=clang++) +fi + ./configure \ + "${extra_configure_args[@]}" \ --prefix="${prefix}" \ --disable-all \ --disable-everything \ diff --git a/packaging/build_ffmpeg_arm64.bat b/packaging/build_ffmpeg_arm64.bat new file mode 100644 index 000000000..a89a20965 --- /dev/null +++ b/packaging/build_ffmpeg_arm64.bat @@ -0,0 +1,32 @@ +:: Copyright (c) Meta Platforms, Inc. and affiliates. +:: All rights reserved. +:: +:: This source code is licensed under the BSD-style license found in the +:: LICENSE file in the root directory of this source tree. + +:: Windows ARM64 variant of build_ffmpeg.bat. Uses MSYS2's CLANGARM64 +:: subsystem (native aarch64 clang toolchain) instead of MINGW64, since +:: mingw-w64-x86_64-toolchain only ever targets x86_64. build_ffmpeg.sh +:: detects MSYSTEM=CLANGARM64 itself and passes --cc=clang --cxx=clang++ to +:: FFmpeg's ./configure (its cc_default is a hardcoded "gcc", which +:: CLANGARM64's toolchain package does not provide, and configure does not +:: read $CC/$CXX from the environment -- only the --cc=/--cxx= flags). +:: +:: Unlike build_ffmpeg.bat (x86_64), this does NOT go through +:: vc_env_helper_arm64.bat / vcvarsall.bat first: doing so (confirmed on a +:: real windows-11-arm run) sets INCLUDE/LIB to MSVC's own UCRT headers, +:: which the CLANGARM64 clang driver picks up ahead of/alongside its own +:: mingw-w64 sysroot headers and fails to parse (e.g. +:: "ucrt\stdlib.h:1184:28: error: expected identifier or '('"). gcc-based +:: MINGW64 builds don't read %INCLUDE%, so build_ffmpeg.bat's use of +:: vcvarsall is harmless there; clang does, so it must be skipped here. This +:: matches build_libavif_arm64.bat, which never called vc_env_helper either. +@echo off + +set PROJ_FOLDER=%cd% + +choco install -y --no-progress msys2 --package-parameters "/NoUpdate" || exit /b 1 +C:\tools\msys64\usr\bin\env MSYSTEM=CLANGARM64 /bin/bash -l -c "pacman -S --noconfirm --needed base-devel mingw-w64-clang-aarch64-toolchain diffutils" || exit /b 1 +C:\tools\msys64\usr\bin\env MSYSTEM=CLANGARM64 /bin/bash -l -c "cd \"${PROJ_FOLDER}\" && packaging/build_ffmpeg.sh" || exit /b 1 + +:end diff --git a/packaging/build_libavif.sh b/packaging/build_libavif.sh index e19dfc1f2..5b6058f75 100755 --- a/packaging/build_libavif.sh +++ b/packaging/build_libavif.sh @@ -35,8 +35,28 @@ set -eux # invokes it under msys2's mingw bash -- but there pacman has already installed # the toolchain, so the block below is skipped because everything is on PATH # (Windows isn't a micromamba target here, and we don't want it to be). +# On Windows/MSYS2, `uname -m` reports the architecture of MSYS2's own POSIX +# runtime (msys-2.0.dll), which today has no native aarch64 build and so +# always reports x86_64 -- even inside the CLANGARM64 subsystem, which is +# what actually determines the *target* architecture being built for (its +# toolchain packages, e.g. mingw-w64-clang-aarch64-toolchain, cross/natively +# target aarch64). Relying on `uname -m` alone therefore wrongly concludes +# we're on x86_64 under CLANGARM64 and demands nasm, which the arm64 build +# intentionally does not install (dav1d needs nasm only for its x86 SIMD; its +# NEON kernels are plain C intrinsics, verified below). Prefer $MSYSTEM when +# set; it is unset (and uname -m is authoritative) on Linux/macOS. +target_machine() { + if [[ -n "${MSYSTEM:-}" ]]; then + case "${MSYSTEM}" in + CLANGARM64) echo "arm64" ;; + *) uname -m ;; + esac + else + uname -m + fi +} tools=(cmake ninja meson) -case "$(uname -m)" in +case "$(target_machine)" in x86_64 | amd64 | i?86) tools+=(nasm) ;; esac diff --git a/packaging/build_libavif_arm64.bat b/packaging/build_libavif_arm64.bat new file mode 100644 index 000000000..d7c86c90a --- /dev/null +++ b/packaging/build_libavif_arm64.bat @@ -0,0 +1,21 @@ +:: Copyright (c) Meta Platforms, Inc. and affiliates. +:: All rights reserved. +:: +:: This source code is licensed under the BSD-style license found in the +:: LICENSE file in the root directory of this source tree. + +:: Windows ARM64 variant of build_libavif.bat. Uses MSYS2's CLANGARM64 +:: subsystem (native aarch64 clang toolchain) instead of MINGW64. nasm is +:: intentionally NOT installed: build_libavif.sh only requires nasm on +:: x86_64/i686 (for dav1d's hand-written x86 SIMD); on aarch64 dav1d's NEON +:: kernels are plain C intrinsics compiled by the C compiler, and +:: build_libavif.sh already asserts NEON symbols are present post-build. +@echo off + +set PROJ_FOLDER=%cd% + +choco install -y --no-progress msys2 --package-parameters "/NoUpdate" || exit /b 1 +C:\tools\msys64\usr\bin\env MSYSTEM=CLANGARM64 /bin/bash -l -c "pacman -S --noconfirm --needed base-devel mingw-w64-clang-aarch64-toolchain mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-ninja mingw-w64-clang-aarch64-meson diffutils" || exit /b 1 +C:\tools\msys64\usr\bin\env MSYSTEM=CLANGARM64 /bin/bash -l -c "cd \"${PROJ_FOLDER}\" && packaging/build_libavif.sh" || exit /b 1 + +:end diff --git a/packaging/vc_env_helper_arm64.bat b/packaging/vc_env_helper_arm64.bat new file mode 100644 index 000000000..13aa42746 --- /dev/null +++ b/packaging/vc_env_helper_arm64.bat @@ -0,0 +1,55 @@ +:: Copyright (c) Meta Platforms, Inc. and affiliates. +:: All rights reserved. +:: +:: This source code is licensed under the BSD-style license found in the +:: LICENSE file in the root directory of this source tree. + +:: Same as vc_env_helper.bat, but initializes the VC toolchain for a native +:: Windows ARM64 build (`vcvarsall.bat arm64`) instead of x64. CUDA/XPU setup is +:: intentionally omitted: Windows ARM64 is CPU-only for torchcodec (no CUDA +:: toolkit ships for this target), matching the boundaries of this workstream. +:: +:: NOT currently invoked by build_ffmpeg_arm64.bat or build_libavif_arm64.bat: +:: running those under an MSVC-initialized environment leaks INCLUDE/LIB +:: (MSVC UCRT headers) into the MSYS2 CLANGARM64 clang build and breaks it +:: (confirmed on real windows-11-arm hardware). This helper is kept for the +:: future torchcodec Arm64 wheel-build job (see implementation-status.md), +:: which does need MSVC's cl.exe/link.exe on PATH to build the C++ extension +:: itself, once its S3/libheif blockers are resolved. +@echo on + +set VC_VERSION_LOWER=17 +set VC_VERSION_UPPER=18 + +for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -legacy -products * -version [%VC_VERSION_LOWER%^,%VC_VERSION_UPPER%^) -property installationPath`) do ( + if exist "%%i" if exist "%%i\VC\Auxiliary\Build\vcvarsall.bat" ( + set "VS15INSTALLDIR=%%i" + set "VS15VCVARSALL=%%i\VC\Auxiliary\Build\vcvarsall.bat" + goto vswhere + ) +) + +:vswhere +if not defined VS15VCVARSALL ( + echo ERROR: Could not locate a Visual Studio installation with vcvarsall.bat >&2 + echo Checked VS versions [%VC_VERSION_LOWER%,%VC_VERSION_UPPER%^) via vswhere.exe >&2 + exit /b 1 +) + +if "%VSDEVCMD_ARGS%" == "" ( + call "%VS15VCVARSALL%" arm64 || exit /b 1 +) else ( + call "%VS15VCVARSALL%" arm64 %VSDEVCMD_ARGS% || exit /b 1 +) + +@echo on + +set DISTUTILS_USE_SDK=1 +set BUILD_AGAINST_ALL_FFMPEG_FROM_S3=1 + +if "%*" == "" ( + echo Usage: vc_env_helper_arm64.bat [command] [args] + echo e.g. vc_env_helper_arm64.bat cl /c test.cpp +) else ( + %* || exit /b 1 +)