mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-29 12:17:14 -06:00
Merge pull request #4497 from dylanmtaylor/chore/remove-windows7
Remove the experimental Windows 7 build
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
# Experimental, unsupported Windows 7 SP1 x64 portable build (docs/windows7.md). It runs by hand and
|
||||
# weekly and for changes to the compatibility path; 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:
|
||||
pull_request:
|
||||
paths:
|
||||
- "Cargo.toml"
|
||||
- "Cargo.lock"
|
||||
- "apps/vectorcraft/Cargo.toml"
|
||||
- "apps/vectorcraft/src/printing.rs"
|
||||
- "apps/vectorcraft/src/printing/**"
|
||||
- "crates/ui-egui/src/print.rs"
|
||||
- "crates/ui-egui/src/tests/printps.rs"
|
||||
- "packaging/windows/windows7.ps1"
|
||||
- ".github/workflows/windows7.yml"
|
||||
schedule:
|
||||
- cron: "23 5 * * 1" # weekly
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
CARGO_INCREMENTAL: 0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-2022
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
|
||||
with:
|
||||
arch: x64
|
||||
- uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f # master
|
||||
with:
|
||||
toolchain: nightly-2026-10-01
|
||||
components: rust-src
|
||||
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2.9.3
|
||||
with:
|
||||
key: windows7-x64
|
||||
- name: Build, check and test the portable package
|
||||
shell: pwsh
|
||||
run: ./packaging/windows/windows7.ps1 -Test
|
||||
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
||||
with:
|
||||
name: vectorcraft-windows7-x64-portable
|
||||
path: dist/release/vectorcraft-windows7-x64-portable.zip
|
||||
if-no-files-found: error
|
||||
Generated
-1
@@ -1310,7 +1310,6 @@ dependencies = [
|
||||
"egui-wgpu",
|
||||
"egui-winit",
|
||||
"egui_glow",
|
||||
"glow",
|
||||
"glutin",
|
||||
"glutin-winit",
|
||||
"image",
|
||||
|
||||
@@ -30,11 +30,6 @@ 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;
|
||||
|
||||
@@ -227,8 +227,6 @@ claude mcp add vectorcraft -- /path/to/vectorcraft-cli mcp --automation-read-roo
|
||||
|
||||
The details are in [`docs/mcp.md`](docs/mcp.md) and [`docs/control-protocol.md`](docs/control-protocol.md).
|
||||
|
||||
For the experimental, unsupported 64-bit Windows 7 build, see [Windows 7 instructions](docs/windows7.md).
|
||||
|
||||
## Status
|
||||
|
||||
VectorCraft is under active development. [**ROADMAP.md**](ROADMAP.md) has the stage, the numbers by dimension
|
||||
|
||||
@@ -35,7 +35,6 @@ winsafe = { version = "0.0.29", default-features = false, features = ["kernel",
|
||||
# DirectWrite's system font collection and GDI's font list (the desktop app's src/system_fonts.rs,
|
||||
# shared): fonts that font services such as Adobe Fonts load in place (#579, #1258). MIT OR
|
||||
# Apache-2.0.
|
||||
[target.'cfg(all(windows, not(target_vendor = "win7")))'.dependencies]
|
||||
windows = { version = "0.62", features = ["Win32_Graphics_DirectWrite", "Win32_Graphics_Gdi"] }
|
||||
|
||||
# CoreText's font manager (the desktop app's src/mac_fonts.rs, shared): fonts that apps and font
|
||||
|
||||
@@ -46,7 +46,7 @@ mod perf;
|
||||
#[path = "../../vectorcraft/src/prefs_dir.rs"]
|
||||
mod prefs_dir;
|
||||
/// The desktop app's DirectWrite font lister, shared: exports and MCP find the same fonts.
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
#[path = "../../vectorcraft/src/system_fonts.rs"]
|
||||
mod system_fonts;
|
||||
|
||||
@@ -162,7 +162,7 @@ fn help() -> Result<(), String> {
|
||||
|
||||
fn main() -> ExitCode {
|
||||
// Before any font lookup: the fonts font services load (#579).
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
system_fonts::install();
|
||||
#[cfg(target_os = "macos")]
|
||||
mac_fonts::install();
|
||||
|
||||
@@ -13,8 +13,6 @@ workspace = true
|
||||
default = ["wgpu", "accessibility"]
|
||||
wgpu = ["eframe/wgpu", "dep:winsafe"]
|
||||
accessibility = ["eframe/accesskit"]
|
||||
# Build with --no-default-features --features windows7 and the win7 Rust target.
|
||||
windows7 = ["eframe/glow"]
|
||||
|
||||
[dependencies]
|
||||
vectorcraft-engine = { workspace = true, features = ["bundled-fonts"] }
|
||||
@@ -37,9 +35,6 @@ image = { workspace = true }
|
||||
webbrowser = { workspace = true }
|
||||
# The window's monitors, size and position (the same winit eframe runs on).
|
||||
winit = { version = "0.30", default-features = false }
|
||||
|
||||
# The win7 target retains the viewer fallback; craft-print's WinRT PDF renderer needs newer Windows.
|
||||
[target.'cfg(all(not(target_arch = "wasm32"), not(target_vendor = "win7")))'.dependencies]
|
||||
craft-print = { workspace = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
@@ -56,7 +51,6 @@ winsafe = { version = "0.0.29", default-features = false, features = ["user"], o
|
||||
# Win32_UI_WindowsAndMessaging has `MSG` and `WM_POINTERDOWN`, which src/windows_stylus.rs uses to
|
||||
# read a pen's barrel button from its pointer messages. Win32_UI_Input_Pointer has
|
||||
# `GetPointerPenInfo`, which it uses to read the pen's pressure and which end of the pen is down.
|
||||
[target.'cfg(all(windows, not(target_vendor = "win7")))'.dependencies]
|
||||
windows = { version = "0.62", features = ["Win32_Graphics_DirectWrite", "Win32_Graphics_Gdi", "Win32_UI_Input_Pointer", "Win32_UI_WindowsAndMessaging"] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
|
||||
@@ -12,12 +12,12 @@ pub(crate) fn native_input_hook(app: &VectorcraftApp) -> Option<vectorcraft_ui_e
|
||||
app.services.native_menu.is_some().then(|| std::sync::Arc::new(mac_menu::raw_input_hook) as vectorcraft_ui_egui::NativeInputHook)
|
||||
}
|
||||
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
pub(crate) fn native_input_hook(_: &VectorcraftApp) -> Option<vectorcraft_ui_egui::NativeInputHook> {
|
||||
Some(std::sync::Arc::new(windows_stylus::raw_input_hook))
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", all(windows, not(target_vendor = "win7")))))]
|
||||
#[cfg(not(any(target_os = "macos", windows)))]
|
||||
pub(crate) fn native_input_hook(_: &VectorcraftApp) -> Option<vectorcraft_ui_egui::NativeInputHook> {
|
||||
None
|
||||
}
|
||||
@@ -43,7 +43,7 @@ impl eframe::App for App {
|
||||
mac_menu::raw_input_hook(raw);
|
||||
}
|
||||
// A pen contact with the barrel button held presses the secondary button (Windows Ink).
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
windows_stylus::raw_input_hook(raw);
|
||||
file_access::unconfined(|| self.app.raw_input_hook(ctx, raw));
|
||||
}
|
||||
@@ -67,15 +67,10 @@ impl eframe::App for App {
|
||||
discard_marked_text();
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "windows7"))]
|
||||
fn on_exit(&mut self) {
|
||||
file_access::unconfined(|| save_prefs(&self.app));
|
||||
end_before_teardown(self.frames);
|
||||
}
|
||||
#[cfg(feature = "windows7")]
|
||||
fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) {
|
||||
file_access::unconfined(|| save_prefs(&self.app));
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
||||
@@ -272,7 +272,7 @@ pub(crate) fn services(parent: Parent, ui: egui::Context) -> Services {
|
||||
#[cfg(target_os = "macos")]
|
||||
stylus: mac_tablet::start(),
|
||||
// Windows reads it from the pen's pointer messages (`windows_stylus`).
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
stylus: Some(windows_stylus::start()),
|
||||
read: Some(Box::new(|p: &str| std::fs::read(p).map_err(|e| e.to_string()))),
|
||||
write: Some(Box::new(write_file)),
|
||||
|
||||
@@ -15,13 +15,6 @@
|
||||
//! keyboard isn't confined.
|
||||
#![cfg_attr(all(target_os = "windows", not(debug_assertions)), windows_subsystem = "windows")]
|
||||
|
||||
#[cfg(all(feature = "windows7", any(feature = "wgpu", feature = "accessibility")))]
|
||||
compile_error!("windows7 requires --no-default-features (wgpu and accessibility must be disabled)");
|
||||
#[cfg(all(windows, feature = "windows7", not(target_vendor = "win7")))]
|
||||
compile_error!("windows7 requires --target x86_64-win7-windows-msvc; the ordinary Windows target still imports newer APIs");
|
||||
#[cfg(all(target_vendor = "win7", not(feature = "windows7")))]
|
||||
compile_error!("the win7 target requires --no-default-features --features windows7");
|
||||
|
||||
mod automation_args;
|
||||
mod clipboard;
|
||||
#[cfg(feature = "wgpu")]
|
||||
@@ -50,7 +43,7 @@ mod open_documents;
|
||||
mod portal_save;
|
||||
mod prefs_dir;
|
||||
mod printing;
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
mod system_fonts;
|
||||
mod tablet;
|
||||
mod window;
|
||||
@@ -190,7 +183,7 @@ fn main() -> std::process::ExitCode {
|
||||
let logger = logging::install();
|
||||
vectorcraft_ui_egui::i18n::detect_system_lang_in_background();
|
||||
// Before the first font scan (the app's start): the fonts font services load (#579).
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
system_fonts::install();
|
||||
#[cfg(target_os = "macos")]
|
||||
mac_fonts::install();
|
||||
@@ -295,7 +288,7 @@ fn main() -> std::process::ExitCode {
|
||||
// With Windows Ink, winit reports a pen as a touch and drops its barrel button and which end
|
||||
// is down; the message hook notes each pointer contact and whether it starts with the barrel
|
||||
// button held, and writes the pen's end into the pen feed (`windows_stylus`).
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
let options = {
|
||||
use winit::platform::windows::EventLoopBuilderExtWindows as _;
|
||||
let mut options = options;
|
||||
@@ -436,10 +429,6 @@ fn main() -> std::process::ExitCode {
|
||||
let (loss, ctx) = (graphics_loss.clone(), cc.egui_ctx.clone());
|
||||
rs.device.set_device_lost_callback(move |reason, msg| loss.report(&ctx, format!("{reason:?}: {msg}")));
|
||||
}
|
||||
#[cfg(feature = "windows7")]
|
||||
{
|
||||
app.graphics_adapter = Some("OpenGL (Windows 7 compatibility)".into());
|
||||
}
|
||||
app.custom_titlebar = custom_titlebar;
|
||||
if let Some(port) = control_port {
|
||||
let rx = control_server::start(port, cc.egui_ctx.clone());
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
//! Desktop printer transport. VectorCraft composes every page and copy before submission;
|
||||
//! craft-print owns discovery and spooling. Windows 7 keeps its viewer-based transport because
|
||||
//! Windows.Data.Pdf is unavailable there.
|
||||
#[cfg(not(all(windows, any(feature = "windows7", target_vendor = "win7"))))]
|
||||
//! craft-print owns discovery and spooling.
|
||||
use std::process::Command;
|
||||
use vectorcraft_ui_egui::print::{PrintJob, PrintService, Printer};
|
||||
|
||||
#[cfg(all(windows, any(feature = "windows7", target_vendor = "win7")))]
|
||||
mod windows7;
|
||||
#[cfg(all(windows, any(feature = "windows7", target_vendor = "win7")))]
|
||||
use windows7 as system;
|
||||
|
||||
pub struct SystemPrint;
|
||||
impl PrintService for SystemPrint {
|
||||
fn printers(&mut self) -> Vec<Printer> {
|
||||
@@ -36,7 +29,6 @@ impl PrintService for SystemPrint {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(all(windows, any(feature = "windows7", target_vendor = "win7"))))]
|
||||
mod system {
|
||||
use super::{Command, PrintJob, Printer};
|
||||
pub fn printers() -> Vec<Printer> {
|
||||
@@ -95,7 +87,7 @@ mod system {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, windows, not(any(feature = "windows7", target_vendor = "win7"))))]
|
||||
#[cfg(all(test, windows))]
|
||||
mod tests {
|
||||
use super::system::setup_command;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
//! The legacy viewer print verb is needed on Windows 7, where Windows.Data.Pdf is absent.
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use vectorcraft_ui_egui::print::{PrintJob, Printer};
|
||||
|
||||
/// Where a job's PDF waits for the spooler: a fresh file in the temp folder. Files of jobs more
|
||||
/// than an hour old (the print verb reads them after Print returns) are removed first.
|
||||
fn job_file(pdf: &[u8]) -> Result<PathBuf, String> {
|
||||
let dir = std::env::temp_dir().join("vectorcraft-print");
|
||||
std::fs::create_dir_all(&dir).map_err(|e| format!("can't make {}: {e}", dir.display()))?;
|
||||
for e in std::fs::read_dir(&dir).into_iter().flatten().flatten() {
|
||||
let old = e.metadata().and_then(|m| m.modified()).ok().and_then(|t| t.elapsed().ok()).is_some_and(|age| age.as_secs() > 3600);
|
||||
if old {
|
||||
// Another job may still be reading it: leave it for next time.
|
||||
let _ = std::fs::remove_file(e.path());
|
||||
}
|
||||
}
|
||||
let stamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).map(|d| d.as_nanos()).unwrap_or_default();
|
||||
let path = dir.join(format!("job-{}-{stamp}.pdf", std::process::id()));
|
||||
// The viewer reads asynchronously, so this cannot use immediate drop cleanup. Never
|
||||
// truncate an existing path, and remove incomplete files or refused launches immediately.
|
||||
use std::io::Write as _;
|
||||
let mut file =
|
||||
std::fs::OpenOptions::new().write(true).create_new(true).open(&path).map_err(|e| format!("can't create {}: {e}", path.display()))?;
|
||||
if let Err(e) = file.write_all(pdf).and_then(|_| file.flush()) {
|
||||
drop(file);
|
||||
let _ = std::fs::remove_file(&path);
|
||||
return Err(format!("can't write {}: {e}", path.display()));
|
||||
}
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
/// Run `c` → its output, or its error message.
|
||||
fn output(c: &mut Command) -> Result<String, String> {
|
||||
let program = c.get_program().to_string_lossy().to_string();
|
||||
let out = c.output().map_err(|e| format!("can't run {program}: {e}"))?;
|
||||
if out.status.success() {
|
||||
return Ok(String::from_utf8_lossy(&out.stdout).into_owned());
|
||||
}
|
||||
let err = String::from_utf8_lossy(&out.stderr).trim().to_string();
|
||||
Err(if err.is_empty() { format!("{program} failed ({})", out.status) } else { err })
|
||||
}
|
||||
|
||||
/// PowerShell's `<Default>\t<Name>` lines → the printers.
|
||||
fn windows_printers(text: &str) -> Vec<Printer> {
|
||||
text.lines()
|
||||
.filter_map(|l| l.trim_end_matches('\r').split_once('\t'))
|
||||
.filter(|(_, name)| !name.trim().is_empty())
|
||||
.map(|(default, name)| Printer { name: name.trim().to_string(), default: default.trim().eq_ignore_ascii_case("true") })
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// `s` as a PowerShell single-quoted string.
|
||||
fn ps_quote(s: &str) -> String {
|
||||
format!("'{}'", s.replace('\'', "''"))
|
||||
}
|
||||
|
||||
fn powershell(script: &str) -> Command {
|
||||
use std::os::windows::process::CommandExt as _;
|
||||
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
||||
let mut c = Command::new(
|
||||
std::path::PathBuf::from(std::env::var_os("SystemRoot").unwrap_or_else(|| "C:\\Windows".into()))
|
||||
.join("System32")
|
||||
.join("WindowsPowerShell")
|
||||
.join("v1.0")
|
||||
.join("powershell.exe"),
|
||||
);
|
||||
c.args([
|
||||
"-NoProfile",
|
||||
"-NonInteractive",
|
||||
"-Command",
|
||||
&format!("$ErrorActionPreference = 'Stop'; [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false); {script}"),
|
||||
])
|
||||
.creation_flags(CREATE_NO_WINDOW);
|
||||
c
|
||||
}
|
||||
|
||||
pub fn printers() -> Vec<Printer> {
|
||||
let script = "Get-WmiObject Win32_Printer | ForEach-Object { \"$($_.Default)`t$($_.Name)\" }";
|
||||
output(&mut powershell(script)).map(|t| windows_printers(&t)).unwrap_or_default()
|
||||
}
|
||||
|
||||
fn submit(job: &PrintJob, file: &std::path::Path) -> Result<String, String> {
|
||||
// The PDF viewer's print verb reads the file after this returns: it stays for a while.
|
||||
let path = ps_quote(&file.to_string_lossy());
|
||||
let script = match job.printer {
|
||||
Some(p) => format!(
|
||||
"Start-Process -FilePath {path} -Verb PrintTo -ArgumentList {} -WindowStyle Hidden",
|
||||
ps_quote(&format!("\"{}\"", p.replace('"', "")))
|
||||
),
|
||||
None => format!("Start-Process -FilePath {path} -Verb Print -WindowStyle Hidden"),
|
||||
};
|
||||
output(&mut powershell(&script)).map(|_| String::new()).map_err(|e| format!("no app prints PDF files here ({e})"))
|
||||
}
|
||||
|
||||
pub fn setup(_printer: Option<&str>) -> Result<(), String> {
|
||||
let mut command = {
|
||||
let mut command = Command::new("control.exe");
|
||||
command.arg("printers");
|
||||
command
|
||||
};
|
||||
command.spawn().map(|_| ()).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
pub fn print(job: &PrintJob) -> Result<String, String> {
|
||||
let file = job_file(job.pdf)?;
|
||||
let result = submit(job, &file);
|
||||
if result.is_err() {
|
||||
// No viewer accepted the launch, so no asynchronous reader needs this document.
|
||||
let _ = std::fs::remove_file(file);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn powershell_lines_and_quotes_are_preserved() {
|
||||
assert_eq!(windows_printers("True\tOffice Laser\r\nFalse\t "), [Printer { name: "Office Laser".into(), default: true }]);
|
||||
assert_eq!(ps_quote("it's.pdf"), "'it''s.pdf'");
|
||||
}
|
||||
#[test]
|
||||
fn job_files_hold_the_pdf_for_the_async_viewer() {
|
||||
let path = job_file(b"%PDF-1.7 test").unwrap();
|
||||
assert_eq!(std::fs::read(&path).unwrap(), b"%PDF-1.7 test");
|
||||
std::fs::remove_file(path).unwrap();
|
||||
}
|
||||
}
|
||||
@@ -115,8 +115,6 @@ pub(crate) fn native_options(custom_titlebar: bool) -> eframe::NativeOptions {
|
||||
.with_title_shown(false)
|
||||
.with_icon(app_icon())
|
||||
.with_app_id("ai.storyteller.vectorcraft"),
|
||||
#[cfg(feature = "windows7")]
|
||||
renderer: eframe::Renderer::Glow,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
//! mouse message that Windows did not make from a pen or a touch
|
||||
//! (<https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages>)
|
||||
//! clears the feed.
|
||||
#![cfg_attr(not(all(windows, not(target_vendor = "win7"))), allow(dead_code))]
|
||||
#![cfg_attr(not(windows), allow(dead_code))]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::sync::OnceLock;
|
||||
@@ -68,7 +68,7 @@ pub fn start() -> StylusFeed {
|
||||
/// message it takes from the thread's queue, before dispatching it: notes each pointer contact's id
|
||||
/// and whether the barrel button was held, and writes the pen's pressure and end into the feed.
|
||||
/// It never consumes the message.
|
||||
#[cfg(all(windows, not(target_vendor = "win7")))]
|
||||
#[cfg(windows)]
|
||||
#[allow(unsafe_code)]
|
||||
pub fn msg_hook(msg: *const std::ffi::c_void) -> bool {
|
||||
use windows::Win32::UI::Input::Pointer::{GetPointerPenInfo, POINTER_FLAG_INCONTACT, POINTER_PEN_INFO};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Architecture
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (shared PDF reader and writer; app output policy and editable-import adapter retained; verified PngSuite downloads, #1729; synthetic control-input budgets, #1709; desktop printing uses craft-print; Windows 7 fallback retained) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (shared PDF reader and writer; app output policy and editable-import adapter retained; verified PngSuite downloads, #1729; synthetic control-input budgets, #1709; desktop printing uses craft-print) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
How VectorCraft is built today. The design rationale lives in the local, gitignored `plan/architecture.md`;
|
||||
this file describes what is committed. Day-to-day rules (clean-room, never crash, quality gates) are in
|
||||
@@ -55,9 +55,7 @@ lists every format read or written; importers are fuzzed (`crates/engine/tests/i
|
||||
Desktop printer discovery and PDF submission use `craft-print`, pinned to an immutable
|
||||
craft-libs revision. The engine still owns sheet composition, copies, separations and colour
|
||||
management. Submission runs on the existing background worker; its receipt or refusal
|
||||
reaches the status bar, and Quit waits for pending submissions. Windows 7 retains WMI discovery
|
||||
and the installed viewer's Print/PrintTo verb;
|
||||
its target excludes the shared backend because Windows.Data.Pdf is unavailable there.
|
||||
reaches the status bar, and Quit waits for pending submissions.
|
||||
|
||||
PDF writing uses the optional `craft-pdf` writer at an immutable craft-libs revision. Shared
|
||||
configuration, metadata, font preparation and guarded serialization leave drawing, colour
|
||||
|
||||
@@ -167,11 +167,6 @@ Root workspace (`Cargo.toml`):
|
||||
`6d518fc7…`, `winit` to `storytold/winit` rev `a517b384…`, and `hayro-*`/`krilla` to craft-libs rev
|
||||
`a0916808…`. The hayro/krilla patches are unrelated to egui and must remain unless a separate comparison proves
|
||||
replacement.
|
||||
- `vendor/windows-link` is the only vendored package. `vendor/windows-link/VECTORCRAFT-PATCH.md` records the
|
||||
provenance (Microsoft windows-link 0.2.1, crates.io, MIT OR Apache-2.0), the sole change (`CoTaskMemFree` from
|
||||
`ole32.dll` on the Windows 7 target), and the removal condition. It is applied only by
|
||||
`packaging/windows/windows7.ps1` through `--config "patch.crates-io.windows-link.path='vendor/windows-link'"`.
|
||||
**Keep it.** Do not add a root path patch for it, and re-run the Windows 7 packaging check after the egui bump.
|
||||
- Nested workspaces: `crates/affinity/fuzz` (libfuzzer only; no egui) and `crates/plugins/example` (wasm plug-in
|
||||
example; no egui). `crates/plugins/example/Cargo.lock` is separate and must not acquire egui.
|
||||
- `crates/affinity/fuzz` has no lockfile in the checkout. Do not create one merely for this migration.
|
||||
@@ -181,7 +176,7 @@ Manifests that participate in the egui graph (the table records the plan-time de
|
||||
| Manifest | Plan-time UI declaration | Required change |
|
||||
|---|---|---|
|
||||
| `crates/ui-egui/Cargo.toml` | `egui` workspace + `bytemuck`; `egui_extras`; dev `egui_kittest` `wgpu`,`snapshot` | `egui` must also enable `default_fonts` for library tests/embedders and for downstream kittest tests, which do not inherit kittest's own dev-dependency fonts; `egui_extras`/`egui_kittest` to 0.37; no feature rename assumed |
|
||||
| `apps/vectorcraft/Cargo.toml` | `eframe` features `default_fonts`, `wayland`, `x11`; default features `wgpu`, `accessibility`; `windows7 = ["eframe/glow"]`; direct `winit 0.30` | add **`eframe/clipboard`**; keep `links` off (existing native `open_url` service); keep `system_fonts` off; retain winit feature set |
|
||||
| `apps/vectorcraft/Cargo.toml` | `eframe` features `default_fonts`, `wayland`, `x11`; default features `wgpu`, `accessibility`; direct `winit 0.30` | add **`eframe/clipboard`**; keep `links` off (existing native `open_url` service); keep `system_fonts` off; retain winit feature set |
|
||||
| `apps/vectorcraft-web/Cargo.toml` | wasm `eframe` features `default_fonts`, `wgpu`, `accesskit` | keep; add `clipboard` only if the chosen eframe 0.37 web path needs the feature (the web clipboard code is not gated by it, but test it); web `open_url` is handled by the web runner |
|
||||
| `craft-ui` / `craft-window` pins | 0.36-era craft-libs revisions | final L2 craft-libs revision on `3832c47…` with workspace `egui = "0.37"` and the CL-2F capture helper |
|
||||
| `Cargo.lock` | one coherent 0.36 graph | one coherent 0.37 graph; no second `egui`, `eframe`, `egui-winit`, `egui-wgpu`, `epaint`/`emath`/`ecolor`, or `winit`; external `kittest`/`accesskit*` are separate audited registry identities |
|
||||
@@ -196,7 +191,7 @@ never against a candidate, an intermediate fork stage or a provisional craft-lib
|
||||
|
||||
| Target | Path | Current role |
|
||||
|---|---|---|
|
||||
| `vectorcraft` binary | `apps/vectorcraft/src/main.rs` | Native eframe/wgpu app, control server, macOS menu, Linux stylus/XWayland, Windows stylus, printing, Windows 7 glow fallback |
|
||||
| `vectorcraft` binary | `apps/vectorcraft/src/main.rs` | Native eframe/wgpu app, control server, macOS menu, Linux stylus/XWayland, Windows stylus, printing |
|
||||
| `vectorcraft-web` binary | `apps/vectorcraft-web/src/main.rs`, `web.rs` | wasm eframe web runner, WebGPU/WebGL2, DOM paste/drop, `window.vectorcraft` control API |
|
||||
| `vectorcraft-cli` binary | `apps/vectorcraft-cli/src/main.rs`, `perf.rs` | Headless run/convert/bench/perf and MCP stdio |
|
||||
| `vectorcraft-ui-egui` library | `crates/ui-egui/src/lib.rs` | All frontend state, panels, dialogs, canvas, control methods, i18n, clipboard, fonts, workers |
|
||||
@@ -424,8 +419,7 @@ Required design (shared weak completion slot, per the suite capture contract):
|
||||
|
||||
Required design:
|
||||
|
||||
- Add `eframe/clipboard` to the native eframe features (unconditionally, so `--no-default-features --features
|
||||
windows7` keeps it). Keep the app's `SystemClipboard` as the multi-format owner for Copy/Cut (SVG/PDF/PNG/text)
|
||||
- Add `eframe/clipboard` to the native eframe features (unconditionally). Keep the app's `SystemClipboard` as the multi-format owner for Copy/Cut (SVG/PDF/PNG/text)
|
||||
and for image/PDF/EPS/SVG paste.
|
||||
- Consume `Event::PasteImage` in `shortcuts::handle` rather than letting it reach a `TextEdit` or the Type tool:
|
||||
- with a `system_clipboard`, treat it as the textless paste signal and let `adopt_system_clipboard` read the
|
||||
@@ -639,7 +633,6 @@ Source-grounded from the 0.37 changelog and code, with tests rather than assumpt
|
||||
- default style tweaks (roomier buttons, larger corners); app sets most tokens but screenshots will move.
|
||||
- text tessellation (#8731) and DX12 FXC shader compile (#8736) are upstream reports, not reproduced here. Measure
|
||||
our own fixtures before changing anything; preserve Repeat/MirroredRepeat semantics and color emoji.
|
||||
- `eframe` now falls back to a compatibility-profile OpenGL context; Windows 7/glow path must be re-tested.
|
||||
- #8748 (hidden-parent deferred children) concerns child/deferred viewports. P7c owns the hidden-parent/child fix
|
||||
and its regression. VectorCraft has no child viewport, so it verifies only the root window's
|
||||
occluded/minimized logic-only path and that any `Area`/`Window` owned by the root does not assume a parent
|
||||
@@ -674,8 +667,7 @@ One coherent 0.37 family:
|
||||
```
|
||||
eframe 0.37 ─┬─ egui 0.37 ── epaint/emath/ecolor/epaint_default_fonts 0.37
|
||||
├─ egui-winit 0.37 ── winit 0.30.13 (approved storytold fork)
|
||||
├─ egui-wgpu 0.37 ── wgpu 30.0.x
|
||||
└─ egui_glow 0.37 (windows7)
|
||||
└─ egui-wgpu 0.37 ── wgpu 30.0.x
|
||||
egui_extras 0.37
|
||||
egui_kittest 0.37 ── kittest 0.5.0 (registry)
|
||||
craft-ui (final craft-libs rev) ── egui 0.37
|
||||
@@ -683,7 +675,7 @@ craft-window (final craft-libs rev) ── egui 0.37
|
||||
```
|
||||
|
||||
- **Required-used fork-source IDs** (each must appear once from the D1b revision): `egui`, `eframe`, `egui-winit`,
|
||||
`egui-wgpu`, `egui_glow` (`windows7` target only), `egui_extras`, `epaint`, `emath`, `ecolor`,
|
||||
`egui-wgpu`, `egui_extras`, `epaint`, `emath`, `ecolor`,
|
||||
`epaint_default_fonts`, `egui_kittest`.
|
||||
- **Optional or forbidden-if-present IDs:** `egui_demo_lib`, `egui_inspection`, `egui_system_font_provider` (only
|
||||
with the disabled `system_fonts` feature) and `egui_demo_app` (workspace-only binary). Absence is a pass; if one
|
||||
@@ -704,8 +696,7 @@ craft-window (final craft-libs rev) ── egui 0.37
|
||||
dependencies from `craft-ui`/`craft-window` resolve to the same source. A dependency's `[patch]` section is
|
||||
ignored by the consumer.
|
||||
- Do not use a branch or a machine-local path in publication. The winit fork's own patch is not inherited.
|
||||
- Keep `vendor/windows-link` and its separate Windows 7 packaging check, and keep the existing hayro/krilla root
|
||||
patches and PDF fixes. These are unrelated to the egui graph and must not be removed, folded into the fork pin, or
|
||||
- Keep the existing hayro/krilla root patches and PDF fixes. These are unrelated to the egui graph and must not be removed, folded into the fork pin, or
|
||||
blanket-deleted with PdfCraft's vendors. Do not add `vendor` copies of egui/winit for VectorCraft.
|
||||
- Add `cargo xtask ui-deps` (modelled on `xtask/src/pdf_deps.rs`) that runs `cargo metadata --locked` and checks a
|
||||
canonical ledger of every package ID and source: required-used fork IDs, optional IDs with an `absent` or
|
||||
@@ -1105,8 +1096,6 @@ Add accessibility tests in the existing `role_and_state` style and via kittest:
|
||||
pass. The existing unsafe `mac_window::center_buttons` may be replaceable by 0.37's
|
||||
`Frame::set_traffic_lights_position`, but do not adopt that without macOS evidence; keep the existing code and
|
||||
test it on real hardware later.
|
||||
- **Windows 7:** compile/package only under `packaging/windows/windows7.ps1 -Test`; no support claim without a real
|
||||
Windows 7 run. The `vendor/windows-link` patch remains.
|
||||
- **Windows ARM64 and FreeBSD:** keep the existing `.github/workflows/windows-arm64.yml` and `freebsd.yml` checks:
|
||||
compile/package and the smoke they actually run. Do not treat a cross/QEMU build as GUI, IME, clipboard or GPU
|
||||
evidence; record those rows as unavailable unless a real machine is used.
|
||||
@@ -1342,22 +1331,19 @@ These are not “future work”; they block calling the migration done:
|
||||
and isolate it from performance comparisons (§6.2). Recheck if main advanced further.
|
||||
9. **macOS evidence.** No macOS host/display is available here. Keyboard layouts, IME (including press-and-hold),
|
||||
Metal/GL, native pickers, termination and traffic-light positioning remain an explicit release gate.
|
||||
10. **Windows 7.** 0.37 + glow + clipboard + the separate `vendor/windows-link` packaging patch must
|
||||
compile/package and be smoke-tested; no support claim from a modern runner alone. Keep the hayro/krilla PDF
|
||||
patches independent.
|
||||
11. **Performance.** Paired control at `4a7cba0…` and candidate with the same engine delta, plus a stock-0.37.0
|
||||
10. **Performance.** Paired control at `4a7cba0…` and candidate with the same engine delta, plus a stock-0.37.0
|
||||
arm in the first report and every investigated regression, using the shared sample floors and the 5%
|
||||
median / 10% p95 / 5% RSS gates. Upstream #8731, #8736 and #8512 are reports, not results; do not claim a
|
||||
regression or a fix without ours.
|
||||
12. **Dependency identities.** Enumerate every fork-family package at one storytold source; audit external
|
||||
11. **Dependency identities.** Enumerate every fork-family package at one storytold source; audit external
|
||||
`kittest`/`accesskit*` as compatible registry identities, not egui-git crates. Skrifa/harfrust/glifo duplicates
|
||||
are expected; measure binary size and confirm no public type crossing. A new `egui`/winit duplicate is a hard
|
||||
failure.
|
||||
13. **Role semantics.** Review the `SelectableLabel → Button`, `Checkbox → CheckBox`, `CollapsingHeader →
|
||||
12. **Role semantics.** Review the `SelectableLabel → Button`, `Checkbox → CheckBox`, `CollapsingHeader →
|
||||
DisclosureTriangle` and `Other → Unknown` mappings against actual screen-reader semantics, not just compile.
|
||||
14. **Wayland/X11/GPU backend.** The host has an i915 render device but no inherited display session; a managed
|
||||
13. **Wayland/X11/GPU backend.** The host has an i915 render device but no inherited display session; a managed
|
||||
Linux job must qualify the actual compositor/backend/DPI. Availability is not a qualified result.
|
||||
15. **Web.** A wasm `check` is not a browser workflow; headless Chrome WebGPU/WebGL2, paste/drop, save/download and
|
||||
14. **Web.** A wasm `check` is not a browser workflow; headless Chrome WebGPU/WebGL2, paste/drop, save/download and
|
||||
screenshots are required.
|
||||
|
||||
**Done means:** one coherent 0.37 graph; `cargo xtask ci` and `ui-deps` pass from a clean checkout; lifecycle
|
||||
@@ -1391,7 +1377,7 @@ Every finding in `plan-reviews/vectorcraft-v2.md` is closed below by source-grou
|
||||
|
||||
| # | Finding | Disposition |
|
||||
|---|---|---|
|
||||
| 1 | No stock-0.37.0 control arm | **Accepted and fixed.** Stock 0.37.0 (`841a328b`) is a measured arm in the first baseline report and every investigated regression, with the same environment and a pinned minimal adapter where fork-only code cannot compile; retained even when app acceptance pairs 0.36 with the candidate. §5.3, §6.2, §7.1 V1, §8.11. |
|
||||
| 1 | No stock-0.37.0 control arm | **Accepted and fixed.** Stock 0.37.0 (`841a328b`) is a measured arm in the first baseline report and every investigated regression, with the same environment and a pinned minimal adapter where fork-only code cannot compile; retained even when app acceptance pairs 0.36 with the candidate. §5.3, §6.2, §7.1 V1, §8.10. |
|
||||
| 2 | Capture admission and geometry under-specified; 64 MiB too small | **Accepted and fixed.** Adopted the shared 4 requests / 128 MiB per image / 256 MiB aggregate defaults (stricter only if the documented intended surface fits), checked bytes reserved before issue, no eviction; records logical/screen bounds, viewport, DPI/zoom and surface epoch at issuance and rejects/retries any change before save, including change-back, then verifies scale/aspect. §3.5, §4.4, §5.2, §8.5. |
|
||||
| 3 | W27 old-epoch invalidation missing | **Accepted and fixed.** Old-epoch `done` is rejected and invalidates that epoch, never edits the new owner; current-epoch mismatch applies incoming once and defers outgoing. §3.9, §4.6, §5.6, §5.7. |
|
||||
| 4 | P7c ownership of #8763/#8748 absent | **Accepted and fixed.** P7c owns both fixes and their pointer/keyboard and hidden-parent regressions; D1b includes P7c, V2 depends on it, and an app workaround needs equivalent tests plus a removal condition. §3.11, §7.1, §8.1. |
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,86 +0,0 @@
|
||||
# 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
|
||||
PowerShell version included with Windows 7, and printer setup opens Control Panel.
|
||||
Printing retains the PDF viewer's Print/PrintTo verb on this build: Windows 7 has no
|
||||
Windows.Data.Pdf renderer. The win7 target excludes `craft-print` from its dependency
|
||||
tree; normal desktop builds use the shared spooler. The `windows7` feature and dedicated win7 target must be selected together; the
|
||||
existing compile-time guards reject mixing this feature with the ordinary Windows target.
|
||||
The normal desktop and web builds retain their existing defaults. A vendor graphics driver providing **OpenGL 3.3 or newer**
|
||||
is required; the Windows built-in generic display driver is insufficient. GPU selection
|
||||
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** (it
|
||||
also runs weekly and on pull requests changing the compatibility path).
|
||||
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.
|
||||
|
||||
To build locally, use a **Windows 10/11 build computer**, with Rust/rustup and Visual Studio
|
||||
2022 C++ build tools (x64 compiler and Windows SDK). Open an **x64 Native Tools Command
|
||||
Prompt for VS 2022**, change to your clone's repository root (the directory containing
|
||||
`Cargo.toml`), and run:
|
||||
|
||||
```powershell
|
||||
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
|
||||
the Windows 7 machine. The optional `CRAFT_FONTS_DIR` setting works as in the normal build.
|
||||
Without it, install fonts for the languages you need on the destination machine.
|
||||
|
||||
The Windows 7 target matters: modern Rust's ordinary `x86_64-pc-windows-msvc` target
|
||||
requires Windows 10, including standard-library and random-number APIs. Selecting OpenGL
|
||||
alone or changing an installer version check cannot fix that.
|
||||
|
||||
References: [Rust's Windows 7 target](https://doc.rust-lang.org/rustc/platform-support/win7-windows-msvc.html)
|
||||
and [Windows baseline change](https://blog.rust-lang.org/2024/02/26/Windows-7/).
|
||||
|
||||
The packaging script checks x64 PE headers, the subsystem version, and known incompatible
|
||||
imports (including `GetSystemTimePreciseAsFileTime`) before creating the ZIP. This is a
|
||||
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. 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
|
||||
|
||||
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, and the maintainers have not reproduced it,
|
||||
so the build remains experimental and unsupported.
|
||||
|
||||
## Runtime acceptance checklist
|
||||
|
||||
A successful build on the Windows 2022 CI runner does **not** prove Windows 7 runtime
|
||||
compatibility. Before declaring support, test on a Windows 7 SP1 x64 machine and record
|
||||
its GPU, driver version, Windows updates and any missing-DLL/entry-point error:
|
||||
|
||||
- Start `vectorcraft.exe`; verify a visible canvas, resizing, minimize/restore and exit.
|
||||
- Draw a shape, save a `.vectorcraft` document, close and reopen it.
|
||||
- Open `examples/dusk-poster.vectorcraft`; export PNG and PDF and inspect both.
|
||||
- Exercise native Open/Save dialogs, clipboard text/images and drag-and-drop.
|
||||
- Change a preference, exit and verify it survives restarting.
|
||||
- Run `vectorcraft-cli.exe --version` and a headless export from a Command Prompt in the
|
||||
extracted application folder.
|
||||
|
||||
This build is experimental until that checklist passes. New dependency versions can add
|
||||
newer Windows imports, so retain Cargo.lock and repeat runtime QA after dependency updates.
|
||||
@@ -1,94 +0,0 @@
|
||||
<# 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. -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'
|
||||
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|craft-print) 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'
|
||||
$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') {
|
||||
$Exe = Join-Path $Bin $Name
|
||||
$Bytes = [IO.File]::ReadAllBytes($Exe)
|
||||
$Pe = [BitConverter]::ToInt32($Bytes, 0x3c)
|
||||
if ([BitConverter]::ToUInt16($Bytes, $Pe + 4) -ne 0x8664) { throw "$Name is not x64" }
|
||||
$Major = [BitConverter]::ToUInt16($Bytes, $Pe + 0x48)
|
||||
$Minor = [BitConverter]::ToUInt16($Bytes, $Pe + 0x4a)
|
||||
if ($Major -gt 6 -or ($Major -eq 6 -and $Minor -gt 1)) { throw "$Name requires subsystem $Major.$Minor" }
|
||||
$Imports = & dumpbin /nologo /imports $Exe
|
||||
if ($LASTEXITCODE -ne 0) { throw "Could not inspect $Name imports" }
|
||||
# Regression gate for known loader failures; actual Win7 runtime QA remains necessary.
|
||||
if ($Imports -match '(?i)\b(GetSystemTimePreciseAsFileTime|ProcessPrng|WaitOnAddress|WakeByAddressSingle|WakeByAddressAll)\b|combase\.dll|bcryptprimitives\.dll|d3d12\.dll|api-ms-win-core-path-') {
|
||||
throw "$Name directly imports a known post-Windows-7 API"
|
||||
}
|
||||
}
|
||||
Invoke-Checked { & (Join-Path $Bin 'vectorcraft-cli.exe') --version }
|
||||
$Stage = Join-Path $TargetDir ('windows7-portable-' + [Guid]::NewGuid().ToString('N'))
|
||||
New-Item -ItemType Directory -Force $Stage | Out-Null
|
||||
Copy-Item (Join-Path $Bin 'vectorcraft.exe'), (Join-Path $Bin 'vectorcraft-cli.exe') $Stage
|
||||
Copy-Item LICENSE-MIT, LICENSE-APACHE, NOTICE, ASSETS.md $Stage
|
||||
Copy-Item -Recurse licenses $Stage
|
||||
Copy-Item vendor/windows-link/license-mit (Join-Path $Stage 'LICENSE-windows-link-MIT')
|
||||
Copy-Item vendor/windows-link/license-apache-2.0 (Join-Path $Stage 'LICENSE-windows-link-Apache-2.0')
|
||||
Copy-Item docs/windows7.md (Join-Path $Stage 'WINDOWS7.md')
|
||||
# portable.txt switches on portable mode, as in the regular portable zip (#1366).
|
||||
Copy-Item (Join-Path $PSScriptRoot 'portable.txt') $Stage
|
||||
if ($env:CRAFT_FONTS_DIR) {
|
||||
foreach ($ofl in Get-ChildItem (Join-Path $env:CRAFT_FONTS_DIR 'fonts\*\OFL.txt')) {
|
||||
Copy-Item $ofl.FullName (Join-Path $Stage "OFL-$($ofl.Directory.Name).txt")
|
||||
}
|
||||
}
|
||||
New-Item -ItemType Directory -Force dist/release | Out-Null
|
||||
$Zip = Join-Path $Root 'dist/release/vectorcraft-windows7-x64-portable.zip'
|
||||
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
|
||||
}
|
||||
Vendored
-39
@@ -1,39 +0,0 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
rust-version = "1.71"
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
build = false
|
||||
autolib = false
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
autobenches = false
|
||||
description = "Linking for Windows"
|
||||
readme = "readme.md"
|
||||
categories = ["os::windows-apis"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/microsoft/windows-rs"
|
||||
|
||||
[lib]
|
||||
name = "windows_link"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[lints.rust]
|
||||
missing_unsafe_on_extern = "warn"
|
||||
|
||||
[lints.rust.unexpected_cfgs]
|
||||
level = "warn"
|
||||
priority = 0
|
||||
check-cfg = ["cfg(windows_raw_dylib, windows_slim_errors)"]
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
# Windows 7 x64 import compatibility
|
||||
|
||||
Upstream: Microsoft windows-link 0.2.1, from crates.io, MIT OR Apache-2.0.
|
||||
Source: https://crates.io/crates/windows-link/0.2.1
|
||||
The original license texts are retained here.
|
||||
|
||||
Only the non-x86 win7-target macro differs: CoTaskMemFree is imported from
|
||||
ole32.dll rather than combase.dll. windows-sys 0.61.2 otherwise causes native
|
||||
file dialogs to introduce a DLL absent on Windows 7. Ordinary targets retain
|
||||
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.
|
||||
-201
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Vendored
-21
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
Vendored
-26
@@ -1,26 +0,0 @@
|
||||
## Linking for Windows
|
||||
|
||||
The [windows-link](https://crates.io/crates/windows-link) crate provides the `link` macro that simplifies linking. The `link` macro is much the same as the one provided by [windows-targets](https://crates.io/crates/windows-targets) but uses `raw-dylib` and thus does not require import lib files.
|
||||
|
||||
* [Getting started](https://kennykerr.ca/rust-getting-started/)
|
||||
* [Samples](https://github.com/microsoft/windows-rs/tree/master/crates/samples)
|
||||
* [Releases](https://github.com/microsoft/windows-rs/releases)
|
||||
|
||||
Start by adding the following to your Cargo.toml file:
|
||||
|
||||
```toml
|
||||
[dependencies.windows-link]
|
||||
version = "0.2"
|
||||
```
|
||||
|
||||
Use the `link` macro to define the external functions you wish to call:
|
||||
|
||||
```rust
|
||||
windows_link::link!("kernel32.dll" "system" fn SetLastError(code: u32));
|
||||
windows_link::link!("kernel32.dll" "system" fn GetLastError() -> u32);
|
||||
|
||||
unsafe {
|
||||
SetLastError(1234);
|
||||
assert_eq!(GetLastError(), 1234);
|
||||
}
|
||||
```
|
||||
Vendored
-57
@@ -1,57 +0,0 @@
|
||||
#![doc = include_str!("../readme.md")]
|
||||
#![no_std]
|
||||
|
||||
/// Defines an external function to import.
|
||||
#[cfg(all(windows, target_arch = "x86"))]
|
||||
#[macro_export]
|
||||
macro_rules! link {
|
||||
($library:literal $abi:literal $($link_name:literal)? fn $($function:tt)*) => (
|
||||
#[link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated")]
|
||||
extern $abi {
|
||||
$(#[link_name=$link_name])?
|
||||
pub fn $($function)*;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Defines an external function to import.
|
||||
#[cfg(all(windows, not(target_arch = "x86"), not(target_vendor = "win7")))]
|
||||
#[macro_export]
|
||||
macro_rules! link {
|
||||
($library:literal $abi:literal $($link_name:literal)? fn $($function:tt)*) => (
|
||||
#[link(name = $library, kind = "raw-dylib", modifiers = "+verbatim")]
|
||||
extern $abi {
|
||||
$(#[link_name=$link_name])?
|
||||
pub fn $($function)*;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Defines an external function to import.
|
||||
#[cfg(not(windows))]
|
||||
#[macro_export]
|
||||
macro_rules! link {
|
||||
($library:literal $abi:literal $($link_name:literal)? fn $($function:tt)*) => (
|
||||
extern $abi {
|
||||
pub fn $($function)*;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// VectorCraft compatibility patch: windows-sys 0.61.2 binds CoTaskMemFree to
|
||||
// combase.dll (Windows 8+). The same API is exported by ole32.dll on Windows 7.
|
||||
// Redirect only this known API; leave every other binding unchanged.
|
||||
#[cfg(all(windows, not(target_arch = "x86"), target_vendor = "win7"))]
|
||||
#[macro_export]
|
||||
macro_rules! link {
|
||||
("combase.dll" $abi:literal fn CoTaskMemFree $($signature:tt)*) => (
|
||||
$crate::link!("ole32.dll" $abi fn CoTaskMemFree $($signature)*);
|
||||
);
|
||||
($library:literal $abi:literal $($link_name:literal)? fn $($function:tt)*) => (
|
||||
#[link(name = $library, kind = "raw-dylib", modifiers = "+verbatim")]
|
||||
extern $abi {
|
||||
$(#[link_name=$link_name])?
|
||||
pub fn $($function)*;
|
||||
}
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user