From caeecf4b267605bc370efc64cfad26325ce049c2 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Thu, 8 Oct 2026 05:06:52 +0700 Subject: [PATCH] M14: Windows 7 build: patch windows-link for that build only, manual CI - Drop the workspace [patch.crates-io] and restore windows-link's crates.io source and checksum in Cargo.lock, so every normal build keeps the checksum-verified crate. windows7.ps1 now applies vendor/windows-link with --config, checks that only windows-link's lock entry moved, builds and tests with --locked, checks the patched crate is the one in use, and restores Cargo.lock afterwards. - windows7.yml runs on demand and weekly instead of on every PR, pins every action by commit SHA, and leaves the dependency check and host tests to the script (-Test) so the Cargo arguments live in one place. - ROADMAP, README, NOTICE and docs: experimental, unsupported, not verified by maintainers. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/windows7.yml | 51 ++++++++++-------------- Cargo.lock | 2 + Cargo.toml | 5 --- NOTICE | 9 +++-- README.md | 2 +- ROADMAP.md | 4 +- docs/windows7.md | 21 +++++++--- packaging/windows/windows7.ps1 | 42 +++++++++++++++---- vendor/windows-link/VECTORCRAFT-PATCH.md | 5 +++ 9 files changed, 86 insertions(+), 55 deletions(-) diff --git a/.github/workflows/windows7.yml b/.github/workflows/windows7.yml index 6e549eab..aeaa756c 100644 --- a/.github/workflows/windows7.yml +++ b/.github/workflows/windows7.yml @@ -1,52 +1,43 @@ +# Experimental, unsupported Windows 7 SP1 x64 portable build (docs/windows7.md). It runs by hand and +# weekly, so ordinary PRs never wait on it, and the weekly run shows when a dependency update starts +# importing a post-Windows-7 API. packaging/windows/windows7.ps1 does the work: it is the only build +# that uses the patched vendor/windows-link. A modern Windows runner proves compilation and host +# smoke tests only: run the checklist in docs/windows7.md on actual Windows 7 before claiming support. name: Windows 7 x64 compatibility + on: + schedule: + - cron: "23 5 * * 1" # weekly workflow_dispatch: - pull_request: - paths: - - '**/*.rs' - - '**/Cargo.toml' - - Cargo.lock - - vendor/windows-link/** - - packaging/windows/windows7.ps1 - - .github/workflows/windows7.yml + permissions: contents: read + +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: 0 + jobs: build: runs-on: windows-2022 timeout-minutes: 90 steps: - - uses: actions/checkout@v4 - - uses: ilammy/msvc-dev-cmd@v1 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + - uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 with: arch: x64 - - uses: dtolnay/rust-toolchain@master + - uses: dtolnay/rust-toolchain@7e38f4b43b4db5c8dd498af069a4f6196df1d067 # master with: toolchain: nightly-2026-10-01 components: rust-src - - uses: Swatinem/rust-cache@v2 + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: key: windows7-x64 - - name: Check that modern Windows backends are excluded + - name: Build, check and test the portable package shell: pwsh - run: | - $tree = cargo +nightly-2026-10-01 tree --locked -p vectorcraft --target x86_64-win7-windows-msvc --no-default-features --features windows7 -e normal --prefix none - if ($LASTEXITCODE -ne 0) { throw 'dependency inspection failed' } - if ($tree -match '^(wgpu|wgpu-core|wgpu-hal|accesskit_windows) v') { throw 'unsupported Windows backend in compatibility build' } - - name: Build portable package - shell: pwsh - run: ./packaging/windows/windows7.ps1 - - name: Test Windows code paths on the build host - shell: pwsh - env: - CARGO_TARGET_X86_64_WIN7_WINDOWS_MSVC_RUSTFLAGS: '-C target-feature=+crt-static' - run: | - cargo +nightly-2026-10-01 test -Z build-std=std,panic_unwind,test --locked --target x86_64-win7-windows-msvc --no-default-features --features vectorcraft/windows7 -p vectorcraft -p vectorcraft-cli - if ($LASTEXITCODE -ne 0) { throw 'tests failed' } - - uses: actions/upload-artifact@v4 + run: ./packaging/windows/windows7.ps1 -Test + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: vectorcraft-windows7-x64-portable path: dist/release/vectorcraft-windows7-x64-portable.zip if-no-files-found: error -# A modern Windows runner proves compilation and host smoke tests only. -# Run the checklist in docs/windows7.md on actual Windows 7 before claiming support. diff --git a/Cargo.lock b/Cargo.lock index 3fb612e9..99bacbca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5355,6 +5355,8 @@ dependencies = [ [[package]] name = "windows-link" version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-numerics" diff --git a/Cargo.toml b/Cargo.toml index 42583c70..4785613d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,8 +96,3 @@ opt-level = 1 [profile.release] lto = "thin" codegen-units = 1 - -# windows-sys 0.61.2 imports CoTaskMemFree from a Windows 8+ DLL. This tiny -# binding patch uses its documented Ole32 export only on the win7 target. -[patch.crates-io] -windows-link = { path = "vendor/windows-link" } diff --git a/NOTICE b/NOTICE index 4f4d576b..73e64928 100644 --- a/NOTICE +++ b/NOTICE @@ -30,6 +30,11 @@ based in part on the work of the Independent JPEG Group. WebAssembly plug-ins run in the wasmi interpreter (MIT OR Apache-2.0); its wasmparser dependency is under the Apache License 2.0 with the LLVM exception. +The experimental Windows 7 build (packaging/windows/windows7.ps1) compiles a modified copy of the +windows-link crate 0.2.1 (vendor/windows-link; Microsoft, MIT OR Apache-2.0) that binds CoTaskMemFree +through ole32.dll. Its license texts are in vendor/windows-link and ship in that build's ZIP; every +other build uses the unmodified crate from crates.io. + Builds made with craft-fonts (the CRAFT_FONTS_DIR build option; all official releases) embed the fonts listed in https://github.com/storytold/craft-fonts/blob/main/ATTRIBUTION.md (BIZ UDPGothic, Shippori Mincho, BIZ UDMincho, Noto Sans CJK SC and Noto Sans Arabic in the current manifest; @@ -67,7 +72,3 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -- windows-link 0.2.1 (vendor/windows-link), Microsoft — MIT OR Apache-2.0. - Modified to bind CoTaskMemFree through Ole32 on the Windows 7 x64 target. - License texts: vendor/windows-link/license-mit and license-apache-2.0. diff --git a/README.md b/README.md index 333897ef..e9f52f61 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ claude mcp add vectorcraft -- /path/to/vectorcraft-cli mcp The details are in [`docs/mcp.md`](docs/mcp.md) and [`docs/control-protocol.md`](docs/control-protocol.md). -For the experimental 64-bit Windows 7 build, see [Windows 7 instructions](docs/windows7.md). +For the experimental, unsupported 64-bit Windows 7 build, see [Windows 7 instructions](docs/windows7.md). ## Status diff --git a/ROADMAP.md b/ROADMAP.md index 725db6b8..ea1f6122 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -42,7 +42,7 @@ since 2026-10-01. | **Bundled content:** brush, symbol, style and swatch libraries | ~30% | Ours are original and generated in code, and far fewer than Illustrator ships; brush and symbol libraries are still missing | | **Performance** | unverified | Multithreaded, off-thread rendering and caches are in place. The last budget run (2026-10-01, loaded machine) measured 290 ms for a 50k-path fit against a 16 ms budget. Re-run `vectorcraft-cli perf` on an idle machine | | **Robustness** | good, new | ~2,840 tests, property tests, no panics in shipped code (lints, the `guard` safety net, import fuzzing), Data Recovery. Missing: a corpus of real-world files, Windows/Linux/browser QA | -| **Platforms and 1.0 polish** | ~60% | The macOS app and the web build work, and Finder opens every readable format with the macOS app (#295, #354); hybrid-graphics laptops render on the power-saving GPU by default (#306); web drops land in the document they were dropped on (#359); Windows/Linux packaging and accessibility are pending; an experimental Windows 7 x64 OpenGL build runs on a user-tested SP1/NVIDIA system, with broader runtime QA still required | +| **Platforms and 1.0 polish** | ~60% | The macOS app and the web build work, and Finder opens every readable format with the macOS app (#295, #354); hybrid-graphics laptops render on the power-saving GPU by default (#306); web drops land in the document they were dropped on (#359); Windows/Linux packaging and accessibility are pending; an experimental, unsupported Windows 7 x64 OpenGL build exists (community-contributed, not verified by maintainers) | | **Agent automation** | beyond Illustrator | Every command, gesture and dialog is drivable over MCP, the CLI and the control channel | ### Where we're lacking (in priority order) @@ -169,7 +169,7 @@ grade by behaviour against `plan/illustrator/`, not by whether a menu item exist | M11 | Artboards & views (artboard panel/tool, Trim View, middle-button pan, print tiling and the status bar's artboard navigator done; multiple windows, presentation polish) | 🟡 | 15–25 | | M12 | Advanced color & art (CMYK/ICC, separations, Gradient Mesh, Live Paint, Image Trace, Graphs) | 🟡 Gradient Mesh, Live Paint, Image Trace (12 presets, 18 ms/1k² image), Recolor Artwork, colour management (ICC, soft proofing, separations preview), Graphs (all 9 tools, Graph Data/Type, regenerate in place) done; graph Design/Column/Marker designs pending | 6–10 | | M13 | Automation (Actions ✅ record/playback, persisted; variables, scripting, batch) | 🟡 | 18–27 | -| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) | 🟡 Preferences, shortcut editor (chords with Shift and a punctuation key fire as typed), workspaces, a custom title bar on Windows/Linux with a Home button, content-sized dialogs and menus that scroll when longer than the window done; experimental Windows 7 x64 portable OpenGL build with a user-confirmed SP1/NVIDIA launch; accessibility and broader Windows/Linux packaging/QA pending | 18–28 | +| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) | 🟡 Preferences, shortcut editor (chords with Shift and a punctuation key fire as typed), workspaces, a custom title bar on Windows/Linux with a Home button, content-sized dialogs and menus that scroll when longer than the window done; an experimental, unsupported Windows 7 x64 portable OpenGL build (not verified by maintainers); accessibility and broader Windows/Linux packaging/QA pending | 18–28 | | — | Interaction fidelity pass (every tool's modifiers, Properties panel per context, isolation, nuance) | ⬜ | 60–90 | | — | Hardening at scale (big-file corpus, fuzzing, cross-platform + browser QA) | 🟡 | 50–80 | | | **Total to full parity** (one agent; re-derived from the [Parity estimate](#parity-estimate) table) | | **~320–500** | diff --git a/docs/windows7.md b/docs/windows7.md index 9df79867..52fa0ece 100644 --- a/docs/windows7.md +++ b/docs/windows7.md @@ -1,4 +1,7 @@ -# Windows 7 x64 compatibility build (experimental) +# Windows 7 x64 compatibility build (experimental, unsupported) + +Windows 7 is not a supported platform. This build is experimental and community-maintained, +and the VectorCraft maintainers have not verified it on Windows 7. This separate build targets **64-bit Windows 7 SP1**. It uses OpenGL instead of wgpu, and omits the native AccessKit accessibility adapter. Printer discovery supports the @@ -9,7 +12,8 @@ in Preferences and `WGPU_POWER_PREF` do not control this OpenGL build. ## Build or download -In your GitHub fork, open **Actions → Windows 7 x64 compatibility → Run workflow**. +In your GitHub fork, open **Actions → Windows 7 x64 compatibility → Run workflow** (it +also runs weekly, never on pull requests). When it succeeds, download the `vectorcraft-windows7-x64-portable` artifact, extract the contained portable ZIP, then run `vectorcraft.exe` on Windows 7. The CLI is included. No MSI is provided: the existing installer remains for modern Windows. @@ -23,6 +27,8 @@ Prompt for VS 2022**, change to your clone's repository root (the directory cont powershell -ExecutionPolicy Bypass -File packaging/windows/windows7.ps1 ``` +Add `-Test` to also run the app and CLI tests on the build computer. + Output: `dist/release/vectorcraft-windows7-x64-portable.zip`. The script installs the pinned nightly compiler and `rust-src`, rebuilds the standard library for `x86_64-win7-windows-msvc`, and links the C runtime statically. It never installs Rust on @@ -42,16 +48,21 @@ regression check, not an exhaustive audit of every Windows API. The small vendored `windows-link` patch routes `CoTaskMemFree` to its documented `ole32.dll` export on the Windows 7 target; the newer binding otherwise imports -`combase.dll`, which is absent on Windows 7. Other targets keep upstream behavior. +`combase.dll`, which is absent on Windows 7. Only this script uses it: it passes +`--config "patch.crates-io.windows-link.path='vendor/windows-link'"` to Cargo, so every other +build, including the normal Windows one, keeps the checksum-verified crates.io crate. Cargo +records the patch in `Cargo.lock`, so the script resolves once, fails if anything other than +windows-link's source changed, builds with `--locked`, and then restores `Cargo.lock`. ## Runtime validation -A user confirmed that the portable x64 compatibility build runs on Windows 7 SP1 +The contributor reports that a user ran the portable x64 compatibility build on Windows 7 SP1 with an NVIDIA graphics card. Their original build failed at startup with `GetSystemTimePreciseAsFileTime` missing from `kernel32.dll`; the compatibility build resolved that failure. The tested build was based on upstream commit `1f7873273b67007b0aefc63313e0d34a39f45453`. The exact GPU/driver version and completion -of every checklist item below were not recorded, so support remains experimental. +of every checklist item below were not recorded, and the maintainers have not reproduced it, +so the build remains experimental and unsupported. ## Runtime acceptance checklist diff --git a/packaging/windows/windows7.ps1 b/packaging/windows/windows7.ps1 index 3b9596e1..cab9db70 100644 --- a/packaging/windows/windows7.ps1 +++ b/packaging/windows/windows7.ps1 @@ -1,8 +1,10 @@ -<# Build on Windows 10/11 with the VS 2022 x64 C++ tools and Windows SDK. - From the repository root: powershell -File packaging/windows/windows7.ps1 +<# Experimental, unsupported Windows 7 SP1 x64 build (docs/windows7.md). + Build on Windows 10/11 with the VS 2022 x64 C++ tools and Windows SDK. + From the repository root: powershell -File packaging/windows/windows7.ps1 [-Test] The resulting portable ZIP targets Windows 7 SP1 x64 with an OpenGL 3.3 driver. - The compiler runs on the build host, not on Windows 7. #> -param([string] $Toolchain = 'nightly-2026-10-01') + The compiler runs on the build host, not on Windows 7. -Test also runs the app and CLI tests + on the build host. #> +param([string] $Toolchain = 'nightly-2026-10-01', [switch] $Test) $ErrorActionPreference = 'Stop' $Root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path $Target = 'x86_64-win7-windows-msvc' @@ -10,19 +12,38 @@ function Invoke-Checked([scriptblock] $Command) { & $Command if ($LASTEXITCODE -ne 0) { throw "Command failed with exit code $LASTEXITCODE" } } +# Cargo.lock without windows-link's registry source and checksum lines (and with LF line endings), +# so the lock files with and without the patch below compare equal. +function Get-LockWithoutWindowsLinkSource([string] $Text) { + ($Text -replace "`r`n", "`n") -replace '(?m)^(name = "windows-link"\nversion = "[^"]*"\n)source = "[^"]*"\nchecksum = "[^"]*"\n', '$1' +} Push-Location $Root $FlagName = 'CARGO_TARGET_X86_64_WIN7_WINDOWS_MSVC_RUSTFLAGS' $OldFlags = [Environment]::GetEnvironmentVariable($FlagName) $OldWinres = $env:VECTORCRAFT_REQUIRE_WINRES +$Lock = Join-Path $Root 'Cargo.lock' +$LockBytes = [IO.File]::ReadAllBytes($Lock) try { Invoke-Checked { rustup toolchain install $Toolchain --profile minimal --component rust-src } + # windows-sys imports CoTaskMemFree from combase.dll, which Windows 7 lacks. Only this build uses + # the patched copy in vendor/windows-link (see its VECTORCRAFT-PATCH.md); every other build keeps + # the crates.io crate. Cargo records the patch in Cargo.lock, so resolve once, check that nothing + # but windows-link's source moved, then build --locked. The finally block restores Cargo.lock. + $Patch = @('--config', "patch.crates-io.windows-link.path='vendor/windows-link'") + Invoke-Checked { cargo "+$Toolchain" metadata --format-version 1 @Patch | Out-Null } + $Before = Get-LockWithoutWindowsLinkSource ([Text.Encoding]::UTF8.GetString($LockBytes)) + $After = Get-LockWithoutWindowsLinkSource ([IO.File]::ReadAllText($Lock)) + if ($Before -cne $After) { throw 'Cargo.lock is out of date: applying the windows-link patch changed other entries' } + $CargoArgs = @('--locked') + $Patch + @('--target', $Target, '--no-default-features', '--features', 'vectorcraft/windows7') + $Tree = cargo "+$Toolchain" tree @CargoArgs -p vectorcraft -e normal --prefix none + if ($LASTEXITCODE -ne 0) { throw 'dependency inspection failed' } + if ($Tree -match '^(wgpu|wgpu-core|wgpu-hal|accesskit_windows) v') { throw 'unsupported Windows backend in compatibility build' } + if (-not ($Tree -match '^windows-link v[^ ]+ \(.*vendor[\\/]windows-link\)')) { throw 'the patched windows-link is not in use' } # The ordinary pc-windows-msvc standard library requires Windows 10. Rebuild std for win7. [Environment]::SetEnvironmentVariable($FlagName, '-C target-feature=+crt-static') $env:VECTORCRAFT_REQUIRE_WINRES = '1' - $BuildArgs = @('-Z', 'build-std=std,panic_unwind', '--locked', - '--target', $Target, '--no-default-features', '--features', 'vectorcraft/windows7', - '-p', 'vectorcraft', '-p', 'vectorcraft-cli') - Invoke-Checked { cargo "+$Toolchain" build @BuildArgs --release } + $CargoArgs += @('-p', 'vectorcraft', '-p', 'vectorcraft-cli') + Invoke-Checked { cargo "+$Toolchain" build -Z build-std=std,panic_unwind @CargoArgs --release } $TargetDir = if ($env:CARGO_TARGET_DIR) { $env:CARGO_TARGET_DIR } else { 'target' } $Bin = Join-Path $TargetDir "$Target\release" foreach ($Name in 'vectorcraft.exe', 'vectorcraft-cli.exe') { @@ -58,7 +79,12 @@ try { Compress-Archive -Path (Join-Path $Stage '*') -DestinationPath $Zip -Force Remove-Item -Recurse -Force $Stage Get-Item $Zip + if ($Test) { + # Exercises the Windows code paths on the build host only; it doesn't prove Windows 7 runtime support. + Invoke-Checked { cargo "+$Toolchain" test -Z build-std=std,panic_unwind,test @CargoArgs } + } } finally { + [IO.File]::WriteAllBytes($Lock, $LockBytes) [Environment]::SetEnvironmentVariable($FlagName, $OldFlags) $env:VECTORCRAFT_REQUIRE_WINRES = $OldWinres Pop-Location diff --git a/vendor/windows-link/VECTORCRAFT-PATCH.md b/vendor/windows-link/VECTORCRAFT-PATCH.md index 71b54f09..e6fcaece 100644 --- a/vendor/windows-link/VECTORCRAFT-PATCH.md +++ b/vendor/windows-link/VECTORCRAFT-PATCH.md @@ -12,5 +12,10 @@ upstream behavior. This is a binding correction, not a replacement allocator. Microsoft documents Ole32.dll and Windows 2000 as the API's minimum: https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cotaskmemfree +Only the experimental Windows 7 build uses this copy: packaging/windows/windows7.ps1 +passes `--config "patch.crates-io.windows-link.path='vendor/windows-link'"`. The +workspace has no [patch], so every other build uses the crates.io crate, verified +by the checksum in Cargo.lock. + The Windows 7 packaging check rejects combase.dll to guard this fix. Remove this patch when upstream bindings provide the same compatibility and recheck imports.