76 lines
10 KiB
Markdown
76 lines
10 KiB
Markdown
# Portable Windows packaging
|
|
|
|
The standard build target is x86_64 MSVC. The optional gnullvm build uses LLVM-MinGW UCRT and currently needs `libunwind.dll` alongside both executables. Packaging is a separate operation on already-built inputs; it neither builds nor launches applications and does not confer release acceptance.
|
|
|
|
For feature checks after extracting the integrated preview, use the
|
|
[human testing checklist](preview-human-checks.md) alongside the release's exact
|
|
validation record and known limitations.
|
|
|
|
Run from a Git checkout with Windows PowerShell 5.1 or PowerShell 7 and Python 3.11+ (standard library only). Build and test first using the [README](../README.md). Select the actual output directory explicitly; a native-host Cargo build normally uses `target/release`, while an explicit `--target` uses `target/<target>/release`. `-Python <executable>` selects Python when it is not named `python` on PATH; it collects/checks the package-local documentation closure without running binaries.
|
|
|
|
Packaging also needs the build's matching `cargo` and `rustc` on the packaging process PATH, the locked dependency sources/archive cache, and installed Rust target libraries and copyright reports. The script invokes only read-only `cargo metadata --locked --offline --filter-platform <target>` and Rust version/sysroot queries. It does not download dependencies or build. These tools are packaging prerequisites; the extracted application does not require them.
|
|
|
|
```powershell
|
|
# MSVC outputs, already built with a verified runtime strategy:
|
|
./scripts/package-windows.ps1 -Target x86_64-pc-windows-msvc `
|
|
-Version 0.2.0-rc1 -BinaryDirectory ./target/release
|
|
|
|
# Optional LLVM-MinGW outputs, already built in a separate target directory:
|
|
./scripts/package-windows.ps1 -Target x86_64-pc-windows-gnullvm `
|
|
-Version 0.2.0-rc1 -BinaryDirectory ./target-gnullvm/release `
|
|
-LlvmMinGWRoot C:/Tools/llvm-mingw-20260826-ucrt-x86_64
|
|
```
|
|
|
|
The caller must supply the matching build target, version, and final binaries. PE headers establish x86_64 architecture, but do not prove a source revision or Cargo profile. `package.json` records input hashes and inspected imports; retain build/test evidence tied to those hashes separately. The version labels the package and does not change the embedded application version. Optional `-BuildEvidence <json>` requires nonempty `source_identity`, `profile`, `compiler`, exact `target`, and `binary_sha256` keyed by both executable filenames. Target and lowercase SHA256 values are checked; source/compiler/profile remain explicitly supplied assertions, never inferred from a directory name.
|
|
|
|
Ordinary dynamic-CRT MSVC output can import VC redistributables and will be refused by the strict runtime check. One candidate recipe is an explicit-target build with `CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS=-C target-feature=+crt-static`; validate its actual imports and runtime on the intended platform before packaging. This guide does not assert that such a build has been performed. The existing GNU/LLVM recipe has its own exact libunwind staging below. Do not silence an unknown import or copy arbitrary DLLs to make packaging pass.
|
|
|
|
The script creates a fresh `dist/ArcadiaStudio-<version>-<target>/`, matching ZIP, and ZIP `.sha256` file. `-OutputRoot` selects another location. Existing output names are refused; no directories are deleted or overwritten. A `.packaging.lock` claim and partial outputs remain after failure for inspection; retry under a fresh version/output location. ZIP file order and timestamps are fixed so unchanged inputs can be compared across runs; this is not a reproducible compiler-build guarantee.
|
|
|
|
Each package includes both executables, a package-specific README, MIT license, built-in Help, language/API specifications and OpenAPI, server/platform guides and their reachable documentation closure, all tracked examples and deployment references, START-HERE, provenance, and SHA256 inventory. Relative Markdown/reST/HTML file links are checked before archiving; upstream license texts retain their own source-tree links unchanged. Current working-tree contents of tracked inputs are copied, so review uncommitted documentation edits before packaging. Untracked sample/user files are excluded. Repository sources and tools are needed separately for Cargo/Docker recipes; the archive README makes this distinction explicit.
|
|
|
|
For gnullvm, the exact selected toolchain's x86_64 `libunwind.dll` and full distribution `LICENSE.TXT` are included; both are hashed. Standard MSVC packaging has no LLVM-MinGW coupling. The script reads ordinary PE imports recursively for packaged runtime DLLs, accepts a bounded list of Windows system components/API sets, and fails on unknown imports. For example, a build importing a VC redistributable DLL must have its redistribution and dependency handling resolved before packaging; it is not silently treated as part of Windows. Do not copy arbitrary DLLs from System32. Dynamically loaded graphics libraries and delay-load imports require the runtime check below.
|
|
|
|
Every staged copy is SHA-256 compared with its source; all ZIP entries are read back and SHA-256 compared with staging, and names/counts are checked. `SHA256SUMS.txt` covers every package file except itself; the separate archive hash covers the ZIP including that inventory. Integrity success establishes transport contents, not application behavior.
|
|
|
|
## Dependency and asset notices
|
|
|
|
`THIRD-PARTY-NOTICES.txt` indexes the collected texts. `dependency-notices.json` records exact package versions and license expressions, the Cargo.lock hash, registry archive checksums verified against the lock, hashes of actual local source files, resolved features, embedded font identities, and staged notice paths/hashes. The selected graph starts at `oa-desktop` and `oa-server` and follows transitive normal/build dependency edges; dev-only edges are excluded. Cargo workspace feature unification can retain a conservative superset. This inventory is tied to packaging inputs and is not proof that caller-supplied binaries were built from them. Keep matching compiler/build evidence separately.
|
|
|
|
Available LICENSE, COPYING, NOTICE, COPYRIGHT, OFL and equivalent named files are retained from each selected crate, including nested notices. Workspace crates receive this repository's license. Published crates that omit required texts need supplements in `scripts/windows-notices/manifest.json` (or `-NoticeManifest <path>`), bound to their exact version and locked registry checksum. Supplemental files must be local, stay inside that manifest's directory, and match the recorded SHA-256 and upstream HTTPS source URL. This manifest is deliberately reviewed input; the packaging script does not fetch notices or substitute a generic SPDX license text. Updates to dependencies can require new reviewed supplements.
|
|
|
|
Literal `include_bytes!` font references in production/build Rust files receive separate exact asset hash and notice mappings, conservatively including feature-gated references; dependency test/example font files are not assumed to ship. This scan is not a complete binary asset detector: generated, indirect or non-font embeds need deliberate review. Rust's installed `COPYRIGHT-library.html` and full `COPYRIGHT.html` are included, with available distribution runtime copying notices, compiler identity, and target-library hashes. LLVM-MinGW includes its distribution LICENSE plus a component notice mapping bound to the exact `libunwind.dll` hash. Missing sources, unsupported source types, missing required notices, unknown embedded font mappings, or changed supplemental hashes stop packaging before creating an output claim.
|
|
|
|
Notice collection is an auditable aid and does not constitute a universal license audit. An unresolved item requires source/provenance review; do not remove the check merely to produce a ZIP.
|
|
|
|
## Clean-environment verification
|
|
|
|
Use an ordinary Windows account with a supported graphical desktop/driver. Extract the ZIP to a fresh user-writable directory, keep the DLL beside both executables, verify hashes, and test from an unrelated working directory. Record exact binary/runtime/ZIP hashes, Windows version and graphics adapter, stdout/stderr, exit codes, and native screenshots. A second Windows machine without development tools remains the stronger portability check.
|
|
|
|
For a controlled smoke, set **only the current PowerShell process's** PATH to Windows system paths, launch hidden with absolute executable paths, then restore PATH in `finally`. This does not change machine/user environment settings. Use a fresh temporary server data directory and an unused loopback port. Example setup (replace `$bundle` with the actual extracted directory):
|
|
|
|
```powershell
|
|
$bundle = 'C:/Users/YourName/Downloads/ArcadiaStudio-0.2.0-rc1-x86_64-pc-windows-gnullvm'
|
|
$qa = Join-Path $env:TEMP ('arcadia-package-smoke-' + [guid]::NewGuid().ToString('N'))
|
|
[void][IO.Directory]::CreateDirectory($qa)
|
|
$savedPath = $env:PATH
|
|
try {
|
|
$env:PATH = "$env:SystemRoot/System32;$env:SystemRoot"
|
|
$server = Start-Process -FilePath (Join-Path $bundle 'arcadia-server.exe') `
|
|
-ArgumentList @('--bind', '127.0.0.1:18787', '--data-dir', ('"' + (Join-Path $qa 'store') + '"')) `
|
|
-WorkingDirectory $qa -WindowStyle Hidden -PassThru `
|
|
-RedirectStandardOutput (Join-Path $qa 'server.stdout.log') `
|
|
-RedirectStandardError (Join-Path $qa 'server.stderr.log')
|
|
$desktop = Start-Process -FilePath (Join-Path $bundle 'arcadia-studio.exe') `
|
|
-WorkingDirectory $qa -WindowStyle Hidden -PassThru `
|
|
-RedirectStandardOutput (Join-Path $qa 'desktop.stdout.log') `
|
|
-RedirectStandardError (Join-Path $qa 'desktop.stderr.log')
|
|
} finally {
|
|
$env:PATH = $savedPath
|
|
}
|
|
```
|
|
|
|
This snippet only starts processes; it does not verify readiness. Check the server's health route documented in [server setup](server.md), import/read/update a model, restart with the same temporary store, and verify persistence. Close only the processes started for this smoke. Exercise Home/example/open/save/reopen and Help, inspect real diagrams, and verify a graphical edit → Save as → Undo → Redo → Save → reopen against the complete intended model/source. Close normally and check stderr/exit state. A process that survives a few seconds alone is not adequate GUI evidence.
|
|
|
|
Acceptance is pending until these checks are actually performed against the packaged final binaries. Historical V2 bundles, this machine's Cargo checks, and a successful development launch with compiler PATH are separate evidence.
|