@crossbind/port-expat-wasi 2.0.0-beta.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/e2e/main.c ADDED
@@ -0,0 +1,29 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ #include <expat.h>
4
+
5
+ static int starts = 0;
6
+ static void XMLCALL onStart(void *ud, const XML_Char *name, const XML_Char **atts)
7
+ {
8
+ (void)ud; (void)name; (void)atts;
9
+ starts++;
10
+ }
11
+
12
+ int main(void)
13
+ {
14
+ const char *xml = "<a><b/><b/></a>";
15
+ XML_Parser p = XML_ParserCreate(NULL);
16
+ XML_SetStartElementHandler(p, onStart);
17
+ if (XML_Parse(p, xml, (int)strlen(xml), 1) != XML_STATUS_OK) return 1;
18
+ XML_ParserFree(p);
19
+ if (starts != 3) return 2;
20
+ printf("expat %s: PASS (3 start elements parsed)\n", XML_ExpatVersion());
21
+ return 0;
22
+ }
23
+
24
+ /* wasi runtime stubs: no dynamic loading / fork on WASI */
25
+ void *dlopen(const char *f, int m) { (void)f; (void)m; return 0; }
26
+ char *dlerror(void) { return (char *)"no dynamic loading on WASI"; }
27
+ void *dlsym(void *h, const char *s) { (void)h; (void)s; return 0; }
28
+ int dlclose(void *h) { (void)h; return -1; }
29
+ int pthread_atfork(void (*a)(void), void (*b)(void), void (*c)(void)) { (void)a; (void)b; (void)c; return 0; }
package/e2e/run.mjs ADDED
@@ -0,0 +1,80 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { createRequire } from 'node:module';
3
+ import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
4
+ import { homedir, tmpdir } from 'node:os';
5
+ import { dirname, join, resolve } from 'node:path';
6
+
7
+ // Compile e2e/main.c against the shipped archives and assert the marker under wasmtime.
8
+ const P = 'wasi-wasm32-st-release';
9
+ const pkgDir = resolve(import.meta.dirname, '..');
10
+
11
+ let sdk = process.env.CROSSBIND_WASI_SDK_PATH;
12
+ if (!sdk) {
13
+ try { sdk = JSON.parse(readFileSync(join(homedir(), '.crossbind.json'), 'utf8')).WASI_SDK_PATH; } catch { /* unset */ }
14
+ }
15
+ if (!sdk || !existsSync(sdk)) {
16
+ console.log('SKIP: wasi-sdk not configured (CROSSBIND_WASI_SDK_PATH or ~/.crossbind.json WASI_SDK_PATH).');
17
+ process.exit(0);
18
+ }
19
+ if (!existsSync(join(sdk, 'share/wasi-sysroot/lib/wasm32-wasip3'))) {
20
+ console.log('SKIP: configured wasi-sdk has no wasm32-wasip3 sysroot (need wasi-sdk >= 34).');
21
+ process.exit(0);
22
+ }
23
+ try {
24
+ execFileSync('wasmtime', ['--version'], { stdio: 'ignore' });
25
+ } catch {
26
+ console.log('SKIP: wasmtime not installed (brew install wasmtime).');
27
+ process.exit(0);
28
+ }
29
+ const own = join(pkgDir, 'dist/prebuilt', P);
30
+ if (!existsSync(own)) {
31
+ console.log('SKIP: wasi prebuilt missing - run `pnpm build` first.');
32
+ process.exit(0);
33
+ }
34
+
35
+ // Dep archives resolve through the dependency chain, so strict installs work.
36
+ const hop = (fromDir, name) => dirname(createRequire(join(fromDir, 'package.json')).resolve(`${name}/package.json`));
37
+ const depDist = (...names) => {
38
+ let dir = pkgDir;
39
+ for (const name of names) dir = hop(dir, name);
40
+ return join(dir, 'dist/prebuilt', P);
41
+ };
42
+
43
+ const includes = [
44
+ join(own, 'include'),
45
+ ];
46
+ const archives = [
47
+ join(own, 'lib', 'libexpat.a'),
48
+ ];
49
+
50
+ const work = mkdtempSync(join(tmpdir(), 'crossbind-wasi-e2e-'));
51
+ try {
52
+ const obj = join(work, 'main.o');
53
+ const wasm = join(work, 'main.wasm');
54
+ execFileSync(join(sdk, 'bin/clang'), [
55
+ '--target=wasm32-wasip3', '-c', join(pkgDir, 'e2e/main.c'), '-o', obj, '-O2',
56
+ '-D_WASI_EMULATED_SIGNAL', '-D_WASI_EMULATED_PROCESS_CLOCKS',
57
+ '-D_WASI_EMULATED_MMAN', '-D_WASI_EMULATED_GETPID',
58
+ ...includes.map((i) => `-I${i}`),
59
+ ], { stdio: 'inherit' });
60
+ execFileSync(join(sdk, 'bin/clang++'), [
61
+ '--target=wasm32-wasip3',
62
+ obj, ...archives,
63
+ '-fwasm-exceptions', '-mexception-handling',
64
+ '-mllvm', '-wasm-enable-sjlj', '-mllvm', '-wasm-use-legacy-eh=false',
65
+ '-lunwind', '-lsetjmp', '-lwasi-emulated-signal', '-lwasi-emulated-process-clocks',
66
+ '-lwasi-emulated-mman', '-lwasi-emulated-getpid',
67
+ '-o', wasm,
68
+ ], { stdio: 'inherit' });
69
+ const out = execFileSync('wasmtime', [
70
+ 'run', `--dir=${work}::/work`,
71
+ wasm,
72
+ ], { encoding: 'utf8', timeout: 120000 });
73
+ process.stdout.write(out);
74
+ if (!out.includes(': PASS')) {
75
+ console.error('FAIL: PASS marker missing');
76
+ process.exit(1);
77
+ }
78
+ } finally {
79
+ rmSync(work, { recursive: true, force: true });
80
+ }
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@crossbind/port-expat-wasi",
3
+ "version": "2.0.0-beta.50",
4
+ "nativeVersion": "2.8.3",
5
+ "description": "WASI build of the precompiled Expat XML parser library, built with crossbind. Use it together with the main package @crossbind/port-expat.",
6
+ "homepage": "https://github.com/crossbind/crossbind/tree/main/ports/expat#readme",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/crossbind/crossbind.git"
10
+ },
11
+ "type": "module",
12
+ "license": "MIT",
13
+ "keywords": [
14
+ "expat",
15
+ "libexpat",
16
+ "xml",
17
+ "crossbind",
18
+ "crossbind-package",
19
+ "webassembly",
20
+ "wasi"
21
+ ],
22
+ "dependencies": {
23
+ "@crossbind/port-expat": "^2.0.0-beta.50"
24
+ },
25
+ "devDependencies": {
26
+ "crossbind": "^2.0.0-beta.50"
27
+ },
28
+ "scripts": {
29
+ "build": "crossbind build -p wasi",
30
+ "e2e": "node e2e/run.mjs",
31
+ "clear": "rm -rf .crossbind dist"
32
+ }
33
+ }