diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index d8bb28a2a..d81f5baae 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -5,4 +5,5 @@ self-hosted-runner: labels: - warp-ubuntu-latest-x64-8x - warp-windows-latest-x64-16x + - warp-windows-2025-vs2026-x64-16x - warp-macos-26-arm64-6x diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 7048d8e42..af6f79272 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -320,11 +320,7 @@ jobs: # ------------------------------------------------------------------ windows: name: Windows installer (NSIS) - runs-on: warp-windows-latest-x64-16x - - defaults: - run: - shell: msys2 {0} + runs-on: warp-windows-2025-vs2026-x64-16x steps: - name: Checkout @@ -332,49 +328,42 @@ jobs: with: submodules: true - - name: Install Rust (stable) + - name: Install Rust (stable, MSVC) uses: dtolnay/rust-toolchain@stable - - - name: Setup MSYS2 - uses: msys2/setup-msys2@v2 with: - msystem: UCRT64 - update: true - # MSYS2's own Rust targets x86_64-pc-windows-gnu by default — - # the Windows build is GNU-target (the MSVC linker rejects the - # Unix-style link args the build scripts emit). - install: >- - git - mingw-w64-ucrt-x86_64-gcc - mingw-w64-ucrt-x86_64-rust + # The Windows build is MSVC-ABI (the runner carries VS 2026): + # vcpkg's FFmpeg and the vendored OCIO build both want it. + toolchain: stable-x86_64-pc-windows-msvc - - name: Install system dependencies - run: | - bash tooling/install-deps.sh - pacman -S --needed --noconfirm \ - mingw-w64-ucrt-x86_64-cmake \ - mingw-w64-ucrt-x86_64-opencolorio \ - mingw-w64-ucrt-x86_64-librsvg \ - mingw-w64-ucrt-x86_64-ffnvcodec-headers \ - mingw-w64-ucrt-x86_64-pkgconf + # vcpkg.json at the repo root pins the dependency set (FFmpeg with + # every free codec + hwaccel, pkgconf, librsvg); the resolved tree + # lands in vcpkg_installed/ and is keyed on the manifest. The + # binary-cache archives dir makes a manifest bump rebuild cheap. + - name: Cache vcpkg artifacts + uses: actions/cache@v4 + with: + path: | + vcpkg_installed + ~/AppData/Local/vcpkg/archives + key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json') }} + save-always: true + + - name: Install dependencies (vcpkg manifest) + run: vcpkg install --triplet x64-windows - name: Configure build environment run: | - # System OCIO (MSYS2, the exact 2.5.2 the bridge targets); - # tooling/ocio-env.sh links it STATICALLY when the package ships - # libOpenColorIO.a, dynamically otherwise (the DLL bundling step - # below then still applies). - bash tooling/ocio-env.sh >> "$GITHUB_ENV" - # ocio-sys is the GIT fork (Mike-Solar/ocio-rs main, pinned in - # the root manifest): its build.rs already carries the - # fork's GNU-toolchain fix, so NO crate-unpack/glob patch step - # applies here. The old code unpacked `ocio-sys-0.2.1.crate` - # from the registry cache — impossible for a git dependency - # (no .crate archive; git sources land under - # registry/src/git/), hence the - # "ls .../ocio-sys-0.2.1/build.rs: No such file" Windows CI - # failure. - echo "OCIO_RS_NO_MSVC_INCLUDES=1" >> "$GITHUB_ENV" + $prefix = "$env:GITHUB_WORKSPACE\vcpkg_installed\x64-windows" + "FFMPEG_DIR=$prefix" >> $env:GITHUB_ENV + "PKG_CONFIG_PATH=$prefix\lib\pkgconfig" >> $env:GITHUB_ENV + "$prefix\tools\pkgconf" >> $env:GITHUB_PATH + # Bundled OCIO: ocio-sys' vendored sources build with the MSVC + # toolchain (what they need — the MSYS2 package was the + # workaround, not the preference), so no OCIO_INSTALL_DIR and + # no OCIO_RS_NO_MSVC_INCLUDES anywhere. + "OCIO_RS_ENABLE_REAL=1" >> $env:GITHUB_ENV + "OCIO_RS_LINK=static" >> $env:GITHUB_ENV + vcpkg list - name: Cache cargo artifacts uses: Swatinem/rust-cache@v2 @@ -382,42 +371,30 @@ jobs: shared-key: oak-workspace cache-on-failure: true - - name: Cache project FFmpeg - uses: actions/cache@v4 - with: - path: .cache/ffmpeg - key: ffmpeg-${{ runner.os }}-${{ hashFiles('tooling/ffmpeg/build-ffmpeg.sh') }} - - - name: Build project FFmpeg (static, GPL + free codecs + hwaccel) - run: | - bash tooling/ffmpeg/build-ffmpeg.sh - echo "FFMPEG_DIR=$(cygpath -m "$PWD/.cache/ffmpeg")" >> "$GITHUB_ENV" - - name: Install cargo-packager run: cargo install cargo-packager --locked - name: Generate app icon (PNG from Oak_Icon.svg) run: | - mkdir -p icons - rsvg-convert -w 512 -h 512 Oak_Icon.svg -o icons/icon.png + New-Item -ItemType Directory -Force icons | Out-Null + & "vcpkg_installed\x64-windows\tools\librsvg\rsvg-convert.exe" -w 512 -h 512 Oak_Icon.svg -o icons/icon.png - name: Build (release) run: | - # Clear the job-hook-injected MSVC INCLUDE/LIB before the GNU - # build (they poison the MinGW compiles with MSVC SDK headers). - unset INCLUDE LIB + # Static CRT: the installer then needs no vcruntime DLLs (the + # vcpkg DLLs below are the only runtime pieces to bundle). + $env:RUSTFLAGS = "-C target-feature=+crt-static" cargo build --release --locked - # Collect the MSYS2 runtime DLLs (libstdc++/libgcc/OpenColorIO/...) - # into target/pkg/win-dlls; the packager `resources` glob then - # installs them next to the executables. + # The vcpkg runtime DLLs (avcodec/avformat/... and the codec libs) + # ship next to the executables: copy them into target/pkg/win-dlls, + # which the packager `resources` glob installs alongside (the MSVC + # CRT itself is covered by the toolchain's static linking story; + # OCIO is bundled statically). - name: Bundle runtime DLLs run: | - unset INCLUDE LIB - pacman -S --needed --noconfirm mingw-w64-ucrt-x86_64-ntldd - tooling/package/bundle-dylibs-windows.sh target/pkg/win-dlls \ - target/release/oak-editor.exe target/release/oak-cli.exe \ - target/release/oak-worker.exe + New-Item -ItemType Directory -Force target/pkg/win-dlls | Out-Null + Copy-Item "vcpkg_installed\x64-windows\bin\*.dll" target/pkg/win-dlls/ - name: Package (NSIS) run: cargo packager --release --formats nsis diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41b3f07ae..d5e5ad548 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,6 +82,7 @@ jobs: with: path: .cache/ffmpeg key: ffmpeg-${{ runner.os }}-${{ hashFiles('tooling/ffmpeg/build-ffmpeg.sh') }} + save-always: true # ------------------------------------------------------------------ # Project FFmpeg (script + FFMPEG_DIR; see docs/build.md) @@ -199,14 +200,7 @@ jobs: windows: name: Build & test (Windows) - runs-on: warp-windows-latest-x64-16x - env: - # The build needs the UCRT64 environment (mingw-w64-ucrt-x86_64-* - # toolchain), not the base MSYS one. - MSYSTEM: UCRT64 - defaults: - run: - shell: msys2 {0} + runs-on: warp-windows-2025-vs2026-x64-16x steps: - name: Checkout uses: actions/checkout@v4 @@ -215,59 +209,51 @@ jobs: # their own repo and build as path dependencies of oakapp. submodules: true - - name: Setup MSYS2 - uses: msys2/setup-msys2@v2 + - name: Install Rust (stable, MSVC) + uses: dtolnay/rust-toolchain@stable with: - msystem: UCRT64 - update: true - # MSYS2's own Rust targets x86_64-pc-windows-gnu by default — - # the Windows build is GNU-target (the MSVC linker rejects the - # Unix-style link args the build scripts emit). - install: >- - git - mingw-w64-ucrt-x86_64-gcc - mingw-w64-ucrt-x86_64-rust + # The Windows build is MSVC-ABI (the runner carries VS 2026): + # vcpkg's FFmpeg and the vendored OCIO build both want it. + toolchain: stable-x86_64-pc-windows-msvc # ------------------------------------------------------------------ - # System dependencies + # vcpkg (manifest mode) + caches # ------------------------------------------------------------------ - - name: Install system dependencies - run: | - bash ./tooling/install-deps.sh - pacman -S --needed --noconfirm \ - mingw-w64-ucrt-x86_64-cmake \ - mingw-w64-ucrt-x86_64-opencolorio \ - mingw-w64-ucrt-x86_64-ffnvcodec-headers \ - mingw-w64-ucrt-x86_64-pkgconf \ - mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-clang-libs git + # vcpkg.json at the repo root pins the dependency set (FFmpeg with + # every free codec + hwaccel, pkgconf, librsvg); the resolved tree + # lands in vcpkg_installed/ and is keyed on the manifest. The + # binary-cache archives dir makes a manifest bump rebuild cheap. + - name: Cache vcpkg artifacts + uses: actions/cache@v4 + with: + path: | + vcpkg_installed + ~/AppData/Local/vcpkg/archives + key: vcpkg-${{ runner.os }}-${{ hashFiles('vcpkg.json') }} + save-always: true + + - name: Install dependencies (vcpkg manifest) + run: vcpkg install --triplet x64-windows # ------------------------------------------------------------------ # Build environment # ------------------------------------------------------------------ - # Windows uses the MSYS2 OpenColorIO package (the exact 2.5.2 the - # bridge targets; the vendored source needs MSVC-only constructs). - # Dynamic here — the CD packages the DLLs next to the binaries. - name: Configure build environment run: | - # System OCIO (MSYS2, the exact 2.5.2 the bridge targets); - # tooling/ocio-env.sh links it STATICALLY when the package ships - # libOpenColorIO.a, dynamically otherwise. - bash tooling/ocio-env.sh >> "$GITHUB_ENV" - echo "FFMPEG_DIR=.cache/ffmpeg" >> "$GITHUB_ENV" - # ocio-sys is the GIT fork (Mike-Solar/ocio-rs main, pinned in - # the root manifest): its build.rs already carries the - # fork's GNU-toolchain fix, so NO crate-unpack/glob patch step - # applies here. The old code unpacked `ocio-sys-0.2.1.crate` - # from the registry cache — impossible for a git dependency - # (no .crate archive; git sources land under - # registry/src/git/), hence the - # "ls .../ocio-sys-0.2.1/build.rs: No such file" Windows CI - # failure. - echo "OCIO_RS_NO_MSVC_INCLUDES=1" >> "$GITHUB_ENV" + $prefix = "$env:GITHUB_WORKSPACE\vcpkg_installed\x64-windows" + "FFMPEG_DIR=$prefix" >> $env:GITHUB_ENV + "PKG_CONFIG_PATH=$prefix\lib\pkgconfig" >> $env:GITHUB_ENV + "$prefix\tools\pkgconf" >> $env:GITHUB_PATH + # Bundled OCIO: ocio-sys' vendored sources build with the MSVC + # toolchain (what they need — the MSYS2 package was the + # workaround, not the preference), so no OCIO_INSTALL_DIR and + # no OCIO_RS_NO_MSVC_INCLUDES anywhere. + "OCIO_RS_ENABLE_REAL=1" >> $env:GITHUB_ENV + "OCIO_RS_LINK=static" >> $env:GITHUB_ENV + # Record the resolved versions in the build log: pinning them + # with builtin-baseline in vcpkg.json is a follow-up. + vcpkg list - # ------------------------------------------------------------------ - # Caches - # ------------------------------------------------------------------ # Covers the whole target/ dir plus ~/.cargo; shared across branches # of the same OS. - name: Cache cargo artifacts @@ -276,57 +262,28 @@ jobs: shared-key: oak-ci-windows cache-on-failure: true - # The project FFmpeg (release/8.0, static, all free codecs + hwaccel) - # is built by tooling/ffmpeg/build-ffmpeg.sh — 10-20 min on a cold - # cache. It does not depend on the Rust toolchain, so key it on the - # script itself and keep it out of rust-cache. - - name: Cache project FFmpeg - uses: actions/cache@v4 - with: - path: .cache/ffmpeg - key: ffmpeg-${{ runner.os }}-${{ hashFiles('tooling/ffmpeg/build-ffmpeg.sh') }} - - # ------------------------------------------------------------------ - # Project FFmpeg (script + FFMPEG_DIR; see docs/build.md) - # ------------------------------------------------------------------ - - name: Build project FFmpeg - run: | - bash tooling/ffmpeg/build-ffmpeg.sh - echo "FFMPEG_DIR=$(cygpath -m "$PWD/.cache/ffmpeg")" >> "$GITHUB_ENV" - # ------------------------------------------------------------------ # Build & test # ------------------------------------------------------------------ # `cargo check` (not build): the Test step links the test binaries # anyway, and a full build would codegen every workspace crate twice - # (once without and once with cfg(test)). cargo check performs no - # final link, so the mingw-w64 link-order workaround is only needed - # in the Test step. + # (once without and once with cfg(test)). - name: Build - run: | - cargo check --workspace --locked + run: cargo check --workspace --locked - name: Test run: | - # The GitHub image injects the MSVC INCLUDE/LIB into the - # environment; clear them in-step (they poison the MinGW - # compiles with MSVC SDK headers). - unset INCLUDE LIB - # mingw-w64 >= Nov 2025 forwards _assert to __msvcrt_assert inside - # libmingwex.a; rustc's link order puts -lmingwex last, so any - # binary that pulls _assert.o leaves _fileno/_setmode/ - # __imp___msvcrt_assert unresolved. A trailing -lmsvcrt re-scans - # the CRT import lib after libmingwex. - export RUSTFLAGS="-C link-args=-lmsvcrt" - if ! cargo test --workspace --locked; then + cargo test --workspace --locked + if ($LASTEXITCODE -ne 0) { # Retry once: a few gpui keystroke tests flake on Windows CI — # a synthetic keystroke is occasionally never delivered (the # undo/redo pair and a plain 's' toggle both failed once, # each identically to its pass state). A real regression # fails both passes. - echo "first pass failed; retrying once for gpui keystroke flakes" + Write-Host "first pass failed; retrying once for gpui keystroke flakes" cargo test --workspace --locked - fi + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + } macos: name: Build & test (macOS) diff --git a/.gitignore b/.gitignore index b3fc91dcd..002fa8173 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ CmakeSettings.json # clangd's index and likely other things that need not be in the repository .cache/ +# vcpkg manifest-mode install tree (Windows CI/CD; see vcpkg.json) +vcpkg_installed/ + # Generated packaging assets (icons/icon.png is produced from Oak_Icon.svg # by rsvg-convert in the CD workflow; see .github/workflows/cd.yml) /icons/ diff --git a/docs/build.md b/docs/build.md index 1de0cbfc3..b2c1c2f4b 100644 --- a/docs/build.md +++ b/docs/build.md @@ -86,6 +86,12 @@ cargo test --workspace # Linux: see "headless tests" below ## Windows (MSYS2 UCRT64) +> **CI/CD note**: the GitHub Windows CI/CD no longer uses this path — it +> builds MSVC-ABI on `warp-windows-2025-vs2026-x64-16x` with vcpkg +> manifest mode (`vcpkg.json` at the repo root: FFmpeg with every free +> codec + hwaccel, pkgconf, librsvg) and the vendored static OCIO. The +> MSYS2 flow below remains the documented local-build alternative. + The Windows build targets **x86_64-pc-windows-gnu** with MSYS2's own Rust; the MSVC toolchain is not supported (the build scripts emit Unix-style link args the MSVC linker rejects). diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 000000000..fa76a9435 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,35 @@ +{ + "name": "oak", + "version": "0.5.0", + "comment": "Windows dependencies (CI/CD, MSVC): the project's FFmpeg with every free codec + hwaccel (mirrors tooling/ffmpeg/build-ffmpeg.sh's configure), plus pkgconf so the -sys crates can find the .pc files. ffmpeg version pinning via builtin-baseline is a follow-up once CI reports the resolved version (see .github/workflows/ci.yml).", + "dependencies": [ + { + "name": "ffmpeg", + "features": [ + "gpl", + "version3", + "x264", + "x265", + "dav1d", + "vpx", + "openh264", + "openjpeg", + "theora", + "webp", + "mp3lame", + "opus", + "vorbis", + "speex", + "snappy", + "ass", + "freetype", + "fribidi", + "fontconfig", + "gnutls", + "ffnvcodec" + ] + }, + "pkgconf", + "librsvg" + ] +}