Skip to content

Commit 41b3b7d

Browse files
committed
Update for compatibility with LLVM 18
This update makes the library compatible with the new version of Alusus (0.15) which is based on LLVM18. This change involves: * Switching to a new version of binaryen (129) * Switching from stdlib-min to wasi-libc * Update build sccript to fetch pre-built binaries for binaryen and wasi-libc.
1 parent 9cded33 commit 41b3b7d

8 files changed

Lines changed: 81 additions & 115 deletions

File tree

Scripts/build.alusus

Lines changed: 60 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -21,55 +21,64 @@ import "Srl/System";
2121
import "Srl/Console";
2222
import "Srl/Net";
2323
import "Srl/String";
24+
import "Srl/Regex";
2425
import "Srl/Fs";
2526
import "Core/Data";
2627
import "Spp";
2728
import "Zip";
2829

2930
use Srl;
3031

31-
function downloadPackage (url: ptr[array[Char]], targetDir: ptr[array[Char]]) {
32-
def result: ptr[array[Char]];
33-
def size: Int;
34-
if !Net.getFile(url, "/tmp/package.zip") {
35-
System.fail(1, String("Failed to download ") + url);
36-
};
37-
38-
if Zip.extractFromFile("/tmp/package.zip", targetDir, 0, 0) != 0 {
39-
System.fail(1, String("Failed to extract downloaded package ") + url);
40-
}
32+
function getFilenameFromPath (path: ptr[array[Char]]): String {
33+
return String((String.findLast(path, '/') + 1)~cast[CharsPtr]);
4134
}
4235

4336
function getDirectoryFromPath (path: ptr[array[Char]]): Srl.String {
4437
return Srl.String(path, Srl.String.findLast(path, '/')~cast[ArchInt] - path~cast[ArchInt]);
4538
}
4639

40+
function downloadPackage (url: ptr[array[Char]], targetDir: ptr[array[Char]]) {
41+
def filename: String = getFilenameFromPath(url);
42+
Console.print(String("Downloading ") + url + " to " + targetDir + "\n");
43+
Console.print(String("Filename extracted from URL: ") + filename + "\n");
44+
45+
if System.exec(String.format("curl -L -o /tmp/%s %s", filename.buf, url)) != 0 {
46+
System.fail(1, String("Failed to download ") + url);
47+
}
48+
49+
// Is it a zip file?
50+
if Regex.match("\\.zip$", filename, 1).getLength() != 0 {
51+
if Zip.extractFromFile(String.format("/tmp/%s", filename.buf), targetDir, 0, 0) != 0 {
52+
System.fail(1, String("Failed to extract downloaded package ") + url);
53+
}
54+
} else if Regex.match("\\.tar\\.gz$", filename, 1).getLength() != 0 {
55+
if System.exec(String.format("tar -xzf /tmp/%s -C %s", filename.buf, targetDir)) != 0 {
56+
System.fail(1, String("Failed to extract downloaded package ") + url);
57+
}
58+
} else {
59+
System.fail(1, String("Unknown package format for ") + url);
60+
}
61+
Console.print("Download and extraction successful\n\n");
62+
}
63+
4764
def rootPath: Srl.String = getDirectoryFromPath(getThisSourceFullPath[]) + "/..";
4865
def buildPath: Srl.String = rootPath + "/Builds";
4966

5067
System.exec(String.format("mkdir -p %s", buildPath.buf));
5168

52-
// Build wabt
53-
def wabtVersion: "1.0.20";
54-
if !Fs.exists(String.format("%s/wabt-%s/bin/wat2wasm", buildPath.buf, wabtVersion)) {
55-
Console.print("<<<< Building wabt >>>>\n\n");
56-
System.exec(String.format("rm -rf %s/wabt-%s", buildPath.buf, wabtVersion));
57-
downloadPackage(String("https://github.com/WebAssembly/wabt/archive/") + wabtVersion + ".zip", buildPath + "/");
58-
System.exec(String.format(
59-
"mkdir -p %s/wabt-%s/build && cd %s/wabt-%s/build && cmake -DBUILD_TESTS=OFF -DBUILD_LIBWASM=OFF .. && cmake --build .",
60-
buildPath.buf, wabtVersion, buildPath.buf, wabtVersion
61-
));
62-
} else {
63-
Console.print("<<<< wabt already available, skipping... >>>>\n\n");
64-
}
65-
66-
// Build binaryen
67-
def binaryenVersion: "version_98";
68-
if !Fs.exists(String.format("%s/binaryen-%s/bin/wasm-opt", buildPath.buf, binaryenVersion)) {
69-
Console.print("<<<< Building binaryen >>>>\n\n");
70-
System.exec(String.format("rm -rf %s/binaryen-%s", buildPath.buf, binaryenVersion));
71-
downloadPackage(String("https://github.com/WebAssembly/binaryen/archive/") + binaryenVersion + ".zip", buildPath + "/");
72-
System.exec(String.format("cd %s/binaryen-%s/ && cmake . && make", buildPath.buf, binaryenVersion));
69+
// Fetch binaryen
70+
def binaryenVersion: "129";
71+
if !Fs.exists(String.format("%s/binaryen-version_%s/bin/wasm-opt", buildPath.buf, binaryenVersion)) {
72+
Console.print("<<<< Fetching binaryen >>>>\n\n");
73+
System.exec(String.format("rm -rf %s/binaryen-version_%s", buildPath.buf, binaryenVersion));
74+
downloadPackage(
75+
String.format(
76+
"https://github.com/WebAssembly/binaryen/releases/download/version_%s/binaryen-version_%s-x86_64-linux.tar.gz",
77+
binaryenVersion,
78+
binaryenVersion
79+
),
80+
buildPath + "/"
81+
);
7382
} else {
7483
Console.print("<<<< binaryen already available, skipping... >>>>\n\n");
7584
}
@@ -78,98 +87,36 @@ function getFilenameFromPath (path: ptr[array[Char]]): String {
7887
return String((String.findLast(path, '/') + 1)~cast[CharsPtr]);
7988
}
8089

81-
// Build stdlib
82-
def stdlibPath: Srl.String = buildPath + "/wasm-stdlib-hack-master";
83-
def clangCmd: "clang-11 --target=wasm32-unknown-unknown-wasm -Iinclude/libc -Oz";
84-
def disableWarn: "-Wno-bitwise-op-parentheses -Wno-shift-op-parentheses";
85-
def mallocOpts: "-DMORECORE_CANNOT_TRIM=1 -DHAVE_MMAP=0 -DHAVE_MREMAP=0 -DLACKS_TIME_H=1 -DNO_MALLOC_STATS=1 "
86-
"-Dmalloc_getpagesize=65536 -Wno-expansion-to-defined";
87-
if !Fs.exists(String.format("%s/dist/stdlib-min.wasm", stdlibPath.buf)) {
88-
Console.print("<<<< Building wasm-stdlib-hack >>>>\n\n");
89-
System.exec(String.format("rm -rf %s", stdlibPath.buf));
90-
downloadPackage("https://github.com/guybedford/wasm-stdlib-hack/archive/master.zip", buildPath + "/");
91-
92-
System.exec(String.format("mkdir -p %s/lib", stdlibPath.buf));
93-
94-
// Build stdlib-base
95-
System.exec(String.format(
96-
"cd %s && ../wabt-%s/bin/wat2wasm -r -o lib/stdlib-base.wasm src/stdlib-base.wast", stdlibPath.buf, wabtVersion
97-
));
98-
// Build malloc.wasm
99-
System.exec(String.format(
100-
"cd %s && %s -c src/dlmalloc.c -o lib/malloc.wasm %s %s", stdlibPath.buf, clangCmd, mallocOpts, disableWarn
101-
));
102-
// Build other functions.
103-
def fnFilenames: Array[String]({
104-
String("stdlib/abs"),
105-
String("string/memcpy"),
106-
String("string/memset"),
107-
String("string/memrchr"),
108-
String("string/memcmp"),
109-
String("string/memmove"),
110-
String("string/stpcpy"),
111-
String("string/stpncpy"),
112-
String("string/strchr"),
113-
String("string/memchr"),
114-
String("string/strrchr"),
115-
String("string/strstr"),
116-
String("string/strcmp"),
117-
String("string/strncmp"),
118-
String("string/strcpy"),
119-
String("string/strncpy"),
120-
String("string/strcat"),
121-
String("string/strncat"),
122-
String("string/strlen"),
123-
String("string/strchrnul"),
124-
String("math/sin"),
125-
String("math/sinf"),
126-
String("math/__sin"),
127-
String("math/__sindf"),
128-
String("math/cos"),
129-
String("math/cosf"),
130-
String("math/__cos"),
131-
String("math/__cosdf"),
132-
String("math/__rem_pio2"),
133-
String("math/__rem_pio2f"),
134-
String("math/__rem_pio2_large"),
135-
String("math/scalbn"),
136-
String("math/powf"),
137-
// String("math/abs"),
138-
String("math/fabsf")
139-
});
140-
def i: Int;
141-
for i = 0, i < fnFilenames.getLength(), ++i {
142-
System.exec(String.format(
143-
"cd %s && %s -Isrc/internal/ -fvisibility=hidden -c src/%s.c -o lib/%s.wasm %s",
144-
stdlibPath.buf, clangCmd, fnFilenames(i).buf, getFilenameFromPath(fnFilenames(i)).buf, disableWarn
145-
));
146-
}
147-
148-
// Link into stdlib-min.wasm
149-
def cmd: String = String.format(
150-
"cd %s && wasm-ld-11 --no-entry --export-dynamic -r lib/stdlib-base.wasm lib/malloc.wasm", stdlibPath.buf
90+
// Fetch wasi-libc
91+
def wasiLibcVersion: "24";
92+
def wasiLibcInnerPath: "share/wasi-sysroot/lib/wasm32-wasi";
93+
if !Fs.exists(String.format("%s/wasi-sdk-%s.0-x86_64-linux/%s/libc.a", buildPath.buf, wasiLibcVersion, wasiLibcInnerPath)) {
94+
Console.print("<<<< Fetching wasi-libc >>>>\n\n");
95+
System.exec(String.format("rm -rf %s/wasi-sdk-%s.0-x86_64-linux", buildPath.buf, wasiLibcVersion));
96+
downloadPackage(
97+
String.format(
98+
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-%s/wasi-sdk-%s.0-x86_64-linux.tar.gz",
99+
wasiLibcVersion,
100+
wasiLibcVersion
101+
),
102+
buildPath + "/"
151103
);
152-
for i = 0, i < fnFilenames.getLength(), ++i {
153-
cmd += " lib/";
154-
cmd += getFilenameFromPath(fnFilenames(i));
155-
cmd += ".wasm";
156-
}
157-
cmd += " -o dist/stdlib-min.wasm";
158-
System.exec(cmd);
159104
} else {
160-
Console.print("<<<< wasm-stdlib-hack already available, skipping... >>>>\n\n");
105+
Console.print("<<<< wasi-libc already available, skipping... >>>>\n\n");
161106
}
162107

163108
// Copy needed files.
164-
Console.print("<<<< Installing generated files >>>>\n\n");
109+
Console.print("<<<< Installing fetched files >>>>\n\n");
165110
System.exec(String.format("mkdir -p %s/Tools/bin && mkdir -p %s/Tools/lib", rootPath.buf, rootPath.buf));
166111
System.exec(
167-
String.format("cp %s/binaryen-%s/bin/wasm-opt %s/Tools/bin/", buildPath.buf, binaryenVersion, rootPath.buf)
112+
String.format("cp %s/binaryen-version_%s/bin/wasm-opt %s/Tools/bin/", buildPath.buf, binaryenVersion, rootPath.buf)
113+
);
114+
System.exec(
115+
String.format("cp %s/wasi-sdk-%s.0-x86_64-linux/%s/libc.a %s/Tools/lib/", buildPath.buf, wasiLibcVersion, wasiLibcInnerPath, rootPath.buf)
168116
);
169117
System.exec(
170-
String.format("cp %s/binaryen-%s/lib/libbinaryen.so %s/Tools/lib/", buildPath.buf, binaryenVersion, rootPath.buf)
118+
String.format("cp %s/wasi-sdk-%s.0-x86_64-linux/%s/crt1.o %s/Tools/lib/", buildPath.buf, wasiLibcVersion, wasiLibcInnerPath, rootPath.buf)
171119
);
172-
System.exec(String.format("cp %s/dist/stdlib-min.wasm %s", stdlibPath.buf, rootPath.buf));
173120

174121
Console.print("<<<< Build successful >>>>\n\n");
175122

Tools/bin/wasm-opt

19 MB
Binary file not shown.

Tools/lib/crt1.o

2.02 KB
Binary file not shown.

Tools/lib/libbinaryen.so

-13.2 MB
Binary file not shown.

Tools/lib/libc.a

2.55 MB
Binary file not shown.

WebPlatform/server.alusus

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@
124124
def binding: ref[Core.Basic.Binding](Core.Basic.getInterface[fn, Core.Basic.Binding]);
125125
binding.setMember("name", Core.Basic.TiStr("wasmStart"));
126126
def wasm: Build.Wasm(fn, uiEndpointsPath + "_intermediate.wasm");
127-
wasm.addDependency(webPlatformPath + String("stdlib-min.wasm"));
127+
wasm.addDependency(webPlatformPath + String("Tools/lib/crt1.o"));
128+
wasm.addDependency(webPlatformPath + String("Tools/lib/libc.a"));
128129
wasm.addFlags({ String("--export=malloc"), String("--export=realloc") });
129130
wasm.generate();
130131
def fnName: String = Spp.astMgr.getDefinitionName(fn);

api.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1105,14 +1105,32 @@ function toLocalISOString(date) {
11051105

11061106
// Main Functions
11071107

1108+
const wasiShim = {
1109+
proc_exit: (code) => console.log(`Process exited with code ${code}`),
1110+
fd_write: () => 0,
1111+
fd_close: () => 0,
1112+
fd_seek: () => 0,
1113+
fd_fdstat_get: () => 0,
1114+
args_get: () => 0,
1115+
args_sizes_get: () => 0,
1116+
environ_sizes_get: (outCount, outSize) => 0,
1117+
environ_get: (outPtr, outBuf) => 0,
1118+
};
1119+
11081120
async function loadWasm(filename, importTable) {
11091121
let response = await fetch(filename);
11101122
let binary = await response.arrayBuffer();
1111-
return WebAssembly.instantiate( binary, { "env": importTable } );
1123+
return WebAssembly.instantiate( binary, { "env": importTable, wasi_snapshot_preview1: wasiShim } );
11121124
}
11131125

11141126
async function start(moduleName) {
11151127
program = await loadWasm(moduleName, wasmApi);
1128+
1129+
// Initialize wasi-libc
1130+
if (program.instance.exports._initialize) {
1131+
program.instance.exports._initialize();
1132+
}
1133+
11161134
wasmMemory = program.instance.exports.memory;
11171135

11181136
asyncifyDataPtr = program.instance.exports.malloc(STACK_SIZE + 8);

stdlib-min.wasm

-34.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)