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 <noreply@anthropic.com>
This commit is contained in:
bflatasticandClaude Opus 5.5 committed 2026-10-08 05:37:06 +07:00
1 parent 58e3916e03
commit caeecf4b26
9 files changed
+86 -55

No files matched your search

+21 -30
View File
@@ -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.
Generated
+2
View File
@@ -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"
-5
View File
@@ -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" }
+5 -4
View File
@@ -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.
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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** |
+16 -5
View File
@@ -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
+34 -8
View File
@@ -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
+5
View File
@@ -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.