Skip to content

Commit 479d8e5

Browse files
authored
Initial updates for windows support (#19)
* Initial updates for windows support Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Add CI Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Fixups after rebase Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Further clean up for windows Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * fix invalidate cachces Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Further just file clean up Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * only invalidate if missing Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * only invalidate if missing Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * trying stale cahce cleanup Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * trying stale cahce cleanup inline Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Remove unicode for windows Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Remove more unicocde Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Don't fail on windows when not present Signed-off-by: James Sturtevant <jsturtevant@gmail.com> --------- Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
1 parent 2f8b3bd commit 479d8e5

31 files changed

Lines changed: 491 additions & 318 deletions

File tree

.copilot/skills/justfile-ci/SKILL.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ This repo uses a **hierarchical Justfile** structure with a matching **GitHub Ac
1919
```
2020
Justfile (root) ← orchestrates everything
2121
├── mod wasm 'src/wasm_sandbox/Justfile'
22-
├── mod jssandbox 'src/javascript_sandbox/Justfile'
22+
├── mod js 'src/javascript_sandbox/Justfile'
2323
├── mod nanvix 'src/nanvix_sandbox/Justfile'
2424
├── mod python 'src/sdk/python/Justfile'
2525
└── mod examples_mod 'examples/Justfile'
@@ -99,3 +99,47 @@ test-rust:
9999
lint-rust:
100100
cargo clippy -p hyperlight-sandbox --all-targets --features test-utils -- -D warnings
101101
```
102+
103+
## Cross-Platform (Windows/Linux) Patterns
104+
105+
### Windows Shell
106+
- Add `set windows-shell := ["pwsh", "-NoLogo", "-Command"]` at the top of subproject Justfiles that need Windows support
107+
- Each recipe line is passed as a `-Command` argument; use `\` line continuations for multi-line PowerShell
108+
- Do NOT use `#!/usr/bin/env pwsh` shebangs — `just` writes temp files without `.ps1` extension and PowerShell refuses to run them
109+
110+
### Paths on Windows
111+
- `invocation_directory()` returns MSYS-style paths (`/c/Users/...`) when `just` is invoked with `set windows-shell` it breaks
112+
- Use `invocation_directory_native()` instead — always returns native OS paths (`C:\Users\...` on Windows, `/home/...` on Linux)
113+
- No `replace()` needed — PowerShell and cargo handle both `\` and `/`
114+
- Standard pattern: `repo-root := invocation_directory_native()`
115+
116+
### Environment Variables
117+
- Use `export WIT_WORLD := ...` instead of `WIT_WORLD=... command` prefix (bash-only syntax)
118+
- `export` is cross-platform and sets the env var for all recipes automatically
119+
120+
### Platform-Specific Recipes
121+
- Use `[unix]` and `[windows]` attributes for platform-specific recipe variants
122+
- Both variants must have the same recipe name; `just` picks the right one automatically
123+
- Prefix with `_` to hide helper recipes from `just --list`
124+
125+
```just
126+
[unix]
127+
_clean-stale:
128+
#!/usr/bin/env bash
129+
rm -rf some/path
130+
131+
[windows]
132+
_clean-stale:
133+
Remove-Item -Recurse -Force 'some/path' -ErrorAction SilentlyContinue
134+
```
135+
136+
### Bash → PowerShell Equivalents
137+
138+
| Bash | PowerShell |
139+
|------|------------|
140+
| `compgen -G "pattern"` | `Get-ChildItem -Path $dir -Filter 'pattern' -ErrorAction SilentlyContinue` |
141+
| `[ ! -f path ]` | `-not (Test-Path path)` |
142+
| `rm -rf path` | `Remove-Item -Recurse -Force path -ErrorAction SilentlyContinue` |
143+
| `echo "msg"` | `Write-Host 'msg'` |
144+
| `for x in a b; do ... done` | `foreach ($x in @('a','b')) { ... }` |
145+
| `command -v tool` | `Get-Command tool -ErrorAction SilentlyContinue` |

.copilot/skills/justfile-ci/references/architecture.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
| Recipe | Delegates to | Purpose |
66
|--------|-------------|---------|
7-
| `build-all` | `wasm::build`, `jssandbox::build`, `nanvix::build`, `python::build` | Build everything |
7+
| `build-all` | `wasm::build`, `jss::build`, `nanvix::build`, `python::build` | Build everything |
88
| `test` | `test-rust`, `wasm::test`, `python::python-test` | All tests |
99
| `test-rust` | (direct cargo) | Core crate unit + integration tests |
10-
| `lint` | `lint-rust`, `wasm::lint`, `jssandbox::lint`, `python::lint` | All linters |
10+
| `lint` | `lint-rust`, `wasm::lint`, `js::lint`, `python::lint` | All linters |
1111
| `fmt` | `fmt-rust`, `python::fmt` | Format all code |
1212
| `fmt-check` | `fmt-check-rust`, `python::fmt-check` | Check formatting |
13-
| `examples` | `wasm::examples`, `jssandbox::examples`, `python::examples` | Run all examples |
13+
| `examples` | `wasm::examples`, `js::examples`, `python::examples` | Run all examples |
1414
| `fuzz` | `python::python-fuzz` | Python fuzz tests |
1515
| `benchmark` | `python::python-sandbox-benchmark` | Python benchmark |
1616
| `clean` | `wasm::clean`, `python::clean` | Clean build artifacts |
@@ -21,7 +21,7 @@
2121
ci.yml
2222
├── rust — fmt-check-rust, lint-rust, test-rust
2323
├── wasm-sandbox — wasm build, lint, test, examples + python fmt-check/lint/build/examples/python-test/fuzz/benchmark/integration-examples
24-
├── javascript-sandbox — jssandbox build, lint, test, examples
24+
├── javascript-sandbox — js build, lint, test, examples
2525
└── nanvix-sandbox — nanvix build (examples skipped pending upstream)
2626
```
2727

@@ -34,7 +34,7 @@ ci.yml
3434
- Recipes: `guest-build`, `js-guest-build`, `build`, `test`, `examples`, `lint`, `clean`
3535
- `examples` is a flat recipe listing all `cargo run` commands (no per-example sub-recipes)
3636

37-
### jssandbox (`src/javascript_sandbox/Justfile`)
37+
### js (`src/javascript_sandbox/Justfile`)
3838
- Needs WIT world from wasm for compilation
3939
- Recipes: `build`, `test`, `examples`, `lint`
4040
- `examples` is a flat recipe listing all `cargo run` commands

.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
- When running examples in this repository, use the `Justfile` recipes instead of invoking `cargo run` or `python` directly.
44
- Use `just examples` from the repository root to run the full example suite.
5-
- To run examples for a specific sandbox, use module-scoped recipes: `just wasm examples`, `just jssandbox examples`, `just python examples`.
5+
- To run examples for a specific sandbox, use module-scoped recipes: `just wasm examples`, `just js examples`, `just python examples`.
66
- Use `just build-all` from the repository root to build all subprojects and SDKs.
77
- Reason: the example commands depend on `WIT_WORLD` being set to `src/wasm_sandbox/wit/sandbox-world.wasm`; the `Justfile` handles that setup.
88

.github/workflows/ci.yml

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ env:
1717

1818
jobs:
1919
rust:
20-
name: Rust · fmt / lint / test
21-
runs-on: ubuntu-latest
20+
name: Rust (${{ matrix.os }})
21+
runs-on: ${{ matrix.os }}
22+
strategy:
23+
matrix:
24+
os: [ubuntu-latest, windows-latest]
2225
steps:
2326
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2427

@@ -41,8 +44,11 @@ jobs:
4144
run: just test-rust
4245

4346
wasm-sandbox:
44-
name: WASM Sandbox · lint / build / examples
45-
runs-on: ubuntu-latest
47+
name: WASM Sandbox (${{ matrix.os }})
48+
runs-on: ${{ matrix.os }}
49+
strategy:
50+
matrix:
51+
os: [ubuntu-latest, windows-latest]
4652
steps:
4753
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
4854

@@ -65,11 +71,16 @@ jobs:
6571
- name: Install just
6672
run: cargo install --locked just
6773

68-
- name: Install clang
74+
- name: Install clang (Linux)
75+
if: runner.os == 'Linux'
6976
run: sudo apt-get update && sudo apt-get install -y clang
7077

78+
- name: Install LLVM (Windows)
79+
if: runner.os == 'Windows'
80+
run: choco install llvm -y
81+
7182
- name: Enable KVM
72-
if: ${{ !env.ACT }}
83+
if: runner.os == 'Linux' && !env.ACT
7384
run: |
7485
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
7586
sudo udevadm control --reload-rules
@@ -92,7 +103,7 @@ jobs:
92103
# Build JS sandbox first — the Python hyperlight-js backend shares the root
93104
# workspace target/ and needs hyperlight-js-runtime to be compiled.
94105
- name: Build JS sandbox
95-
run: just jssandbox build
106+
run: just js build
96107

97108
- name: Python SDK Format check
98109
run: just python fmt-check
@@ -111,7 +122,7 @@ jobs:
111122

112123
- name: Python SDK Fuzz
113124
run: just fuzz 30
114-
125+
115126
# this is too flaky in github actions to run on PRs
116127
# copilot fails to repsond in a timely fashion
117128
# - name: Run Python SDK integration examples
@@ -124,8 +135,11 @@ jobs:
124135
run: just benchmark
125136

126137
python-wheelhouse:
127-
name: Python SDK · wheelhouse test
128-
runs-on: ubuntu-latest
138+
name: Python SDK wheelhouse test (${{ matrix.os }})
139+
runs-on: ${{ matrix.os }}
140+
strategy:
141+
matrix:
142+
os: [ubuntu-latest, windows-latest]
129143
steps:
130144
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
131145

@@ -148,11 +162,16 @@ jobs:
148162
- name: Install just
149163
run: cargo install --locked just
150164

151-
- name: Install clang
165+
- name: Install clang (Linux)
166+
if: runner.os == 'Linux'
152167
run: sudo apt-get update && sudo apt-get install -y clang
153168

169+
- name: Install LLVM (Windows)
170+
if: runner.os == 'Windows'
171+
run: choco install llvm -y
172+
154173
- name: Enable KVM
155-
if: ${{ !env.ACT }}
174+
if: runner.os == 'Linux' && !env.ACT
156175
run: |
157176
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
158177
sudo udevadm control --reload-rules
@@ -163,8 +182,11 @@ jobs:
163182
run: just python-wheelhouse-test
164183

165184
javascript-sandbox:
166-
name: JS Sandbox · lint / build / examples
167-
runs-on: ubuntu-latest
185+
name: JS Sandbox (${{ matrix.os }})
186+
runs-on: ${{ matrix.os }}
187+
strategy:
188+
matrix:
189+
os: [ubuntu-latest, windows-latest]
168190
steps:
169191
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
170192

@@ -176,11 +198,16 @@ jobs:
176198
- name: Install just
177199
run: cargo install --locked just
178200

179-
- name: Install clang
201+
- name: Install clang (Linux)
202+
if: runner.os == 'Linux'
180203
run: sudo apt-get update && sudo apt-get install -y clang
181204

205+
- name: Install LLVM (Windows)
206+
if: runner.os == 'Windows'
207+
run: choco install llvm -y
208+
182209
- name: Enable KVM
183-
if: ${{ !env.ACT }}
210+
if: runner.os == 'Linux' && !env.ACT
184211
run: |
185212
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
186213
sudo udevadm control --reload-rules
@@ -191,20 +218,20 @@ jobs:
191218
run: just wasm guest-compile-wit
192219

193220
- name: Build
194-
run: just jssandbox build
221+
run: just js build
195222

196223
- name: Lint
197-
run: just jssandbox lint
224+
run: just js lint
198225

199226
- name: Tests
200-
run: just jssandbox test
227+
run: just js test
201228

202229
- name: Run examples
203-
run: just jssandbox examples
230+
run: just js examples
204231

205232
nanvix-sandbox:
206233
name: Nanvix Sandbox · build
207-
runs-on: ubuntu-latest
234+
runs-on: ubuntu-latest #current linux only
208235
steps:
209236
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
210237

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ target/
44
*.wasm
55
__pycache__/
66
*.so
7+
*.pyd
8+
*.pdb
79
*.pyc
810
node_modules/
911
build/

Justfile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
set unstable := true
22

33
mod wasm 'src/wasm_sandbox/Justfile'
4-
mod jssandbox 'src/javascript_sandbox/Justfile'
4+
mod js 'src/javascript_sandbox/Justfile'
55
mod nanvix 'src/nanvix_sandbox/Justfile'
66
mod python 'src/sdk/python/Justfile'
77
mod examples_mod 'examples/Justfile'
@@ -13,9 +13,9 @@ clean: wasm::clean python::clean
1313

1414
#### BUILD TARGETS ####
1515

16-
build-all target=default-target: (wasm::build target) (jssandbox::build target) nanvix::build python::build
16+
build-all target=default-target: (wasm::build target) (js::build target) nanvix::build python::build
1717

18-
lint: lint-rust wasm::lint jssandbox::lint python::lint
18+
lint: lint-rust wasm::lint js::lint python::lint
1919

2020
lint-rust:
2121
cargo clippy -p hyperlight-sandbox --all-targets --features test-utils -- -D warnings
@@ -41,11 +41,11 @@ test-rust:
4141

4242
benchmark: python::python-sandbox-benchmark
4343

44-
python-dist: (wasm::build "release") (jssandbox::build "release") python::python-dist
44+
python-dist: (wasm::build "release") (js::build "release") python::python-dist
4545

4646
python-wheelhouse-test: python-dist python::python-wheelhouse-test
4747

48-
examples target=default-target: (wasm::examples target) (jssandbox::examples target) python::examples
48+
examples target=default-target: (wasm::examples target) (js::examples target) python::examples
4949

5050
integration-examples target=default-target: (wasm::guest-build target) wasm::js-guest-build python::build examples_mod::integration-examples
5151

@@ -60,13 +60,14 @@ slides:
6060

6161
##### Run GitHub Actions CI locally using act (https://nektosact.com) #######
6262

63+
[unix]
6364
ci job="":
6465
#!/usr/bin/env bash
6566
if ! command -v act &>/dev/null; then
6667
echo "act is not installed. Install it from: https://nektosact.com/installation/index.html"
6768
exit 1
6869
fi
69-
args=(-e {{ justfile_directory() }}/.github/act-event.json)
70+
args=(-e {{ replace(justfile_directory(), "\\", "/") }}/.github/act-event.json)
7071
if [ -e /dev/kvm ]; then
7172
args+=(--container-options "--device /dev/kvm")
7273
fi

examples/Justfile

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
repo-root := invocation_directory()
2-
wit-world := if os() == "windows" { "$env:WIT_WORLD=\"" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm\";" } else { "WIT_WORLD=" + repo-root + "/src/wasm_sandbox/wit/sandbox-world.wasm" }
3-
1+
repo-root := invocation_directory_native()
42
integration-copilot-sdk-deps:
53
uv sync --group copilot-sdk --inexact --no-install-package hyperlight-sandbox-backend-wasm --no-install-package hyperlight-sandbox-backend-hyperlight-js
64

@@ -11,15 +9,15 @@ integration-agent-framework-devui-deps:
119
uv sync --group agent-framework-devui
1210

1311
copilot-sdk-example: integration-copilot-sdk-deps
14-
{{ wit-world }} uv run python {{repo-root}}/examples/copilot-sdk/copilot_sdk_tools.py
12+
uv run python {{repo-root}}/examples/copilot-sdk/copilot_sdk_tools.py
1513

1614
agent-framework-example: integration-agent-framework-deps
17-
{{ wit-world }} uv run python {{repo-root}}/examples/agent-framework/copilot_agent.py --no-wait
15+
uv run python {{repo-root}}/examples/agent-framework/copilot_agent.py --no-wait
1816

1917
agent-framework-example-interactive: integration-agent-framework-deps
20-
{{ wit-world }} uv run python {{repo-root}}/examples/agent-framework/copilot_agent.py --interactive
18+
uv run python {{repo-root}}/examples/agent-framework/copilot_agent.py --interactive
2119

2220
agent-framework-example-devui: integration-agent-framework-deps integration-agent-framework-devui-deps
23-
{{ wit-world }} uv run python {{repo-root}}/examples/agent-framework/copilot_agent.py --devui
21+
uv run python {{repo-root}}/examples/agent-framework/copilot_agent.py --devui
2422

2523
integration-examples: copilot-sdk-example agent-framework-example

src/hyperlight_sandbox/src/lib.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ pub use tools::{ArgType, ToolRegistry, ToolSchema};
2626
// Configuration
2727
// ---------------------------------------------------------------------------
2828

29+
/// Default guest heap size in bytes (platform-dependent).
30+
#[cfg(windows)]
31+
pub const DEFAULT_HEAP_SIZE: u64 = 400 * 1024 * 1024;
32+
#[cfg(not(windows))]
33+
pub const DEFAULT_HEAP_SIZE: u64 = 200 * 1024 * 1024;
34+
35+
/// Default guest stack / scratch size in bytes (platform-dependent).
36+
#[cfg(windows)]
37+
pub const DEFAULT_STACK_SIZE: u64 = 200 * 1024 * 1024;
38+
#[cfg(not(windows))]
39+
pub const DEFAULT_STACK_SIZE: u64 = 100 * 1024 * 1024;
40+
2941
/// Configuration for building a sandbox guest.
3042
#[derive(Debug, Clone)]
3143
pub struct SandboxConfig {
@@ -41,8 +53,8 @@ impl Default for SandboxConfig {
4153
fn default() -> Self {
4254
Self {
4355
module_path: String::new(),
44-
heap_size: 200 * 1024 * 1024,
45-
stack_size: 100 * 1024 * 1024,
56+
heap_size: DEFAULT_HEAP_SIZE,
57+
stack_size: DEFAULT_STACK_SIZE,
4658
}
4759
}
4860
}

0 commit comments

Comments
 (0)