MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

add comprehensive BUILDING.md guide

+589 -16
+431
BUILDING.md
··· 1 + # Building Ant 2 + 3 + Depending on what platform or features you need, the build process may 4 + differ. After you've built a binary, running the 5 + test suite to confirm that the binary works as intended is a good next step. 6 + 7 + ## Table of contents 8 + 9 + - [Supported platforms](#supported-platforms) 10 + - [Platform list](#platform-list) 11 + - [Supported toolchains](#supported-toolchains) 12 + - [Official binary platforms and toolchains](#official-binary-platforms-and-toolchains) 13 + - [Building Ant on supported platforms](#building-ant-on-supported-platforms) 14 + - [Prerequisites](#prerequisites) 15 + - [Unix and macOS](#unix-and-macos) 16 + - [Unix prerequisites](#unix-prerequisites) 17 + - [macOS prerequisites](#macos-prerequisites) 18 + - [Building Ant](#building-ant-1) 19 + - [Installing Ant](#installing-ant) 20 + - [Running tests](#running-tests) 21 + - [Building a debug build](#building-a-debug-build) 22 + - [Building an ASan build](#building-an-asan-build) 23 + - [Speeding up frequent rebuilds when developing](#speeding-up-frequent-rebuilds-when-developing) 24 + - [Troubleshooting Unix and macOS builds](#troubleshooting-unix-and-macos-builds) 25 + - [Windows](#windows) 26 + - [Windows prerequisites](#windows-prerequisites) 27 + - [Building Ant](#building-ant-2) 28 + - [Meson build options](#meson-build-options) 29 + - [TLS library selection](#tls-library-selection) 30 + 31 + ## Supported platforms 32 + 33 + ### Platform list 34 + 35 + Ant builds and runs on the following platforms. Official CI builds are 36 + produced for each platform listed below. 37 + 38 + | Operating System | Architectures | Variant | Static | Notes | 39 + | ---------------- | ------------- | ---------- | ------ | ---------------------------- | 40 + | GNU/Linux | x64 | glibc | No | Ubuntu 22.04 (CI) | 41 + | GNU/Linux | aarch64 | glibc | No | Ubuntu 22.04 (CI) | 42 + | GNU/Linux | x64 | musl | Yes | Alpine Edge (CI) | 43 + | GNU/Linux | aarch64 | musl | Yes | Alpine Edge (CI) | 44 + | macOS | x64 | openssl | No | macOS 15 (CI) | 45 + | macOS | aarch64 | openssl | No | macOS 15 (CI) | 46 + | macOS | x64 | mbedtls | No | macOS 15 (CI) | 47 + | macOS | aarch64 | mbedtls | No | macOS 15 (CI) | 48 + | Windows | x64 | mingw/msys | No | MSYS2 MINGW64 toolchain (CI) | 49 + 50 + ### Supported toolchains 51 + 52 + Ant is built with the GNU C23 standard (`-std=gnu23`). A compiler with 53 + C23 support is required. 54 + 55 + | Operating System | Compiler Versions | 56 + | ---------------- | ------------------------------------- | 57 + | Linux | GCC >= 14 or Clang >= 18 | 58 + | macOS | Xcode CLT (Apple Clang) or LLVM >= 18 | 59 + | Windows | MinGW-w64 GCC via MSYS2 (MINGW64) | 60 + 61 + ### Official binary platforms and toolchains 62 + 63 + CI binaries are produced using: 64 + 65 + | Binary package | Platform and Toolchain | 66 + | -------------------------- | -------------------------------------------- | 67 + | ant-linux-x64 | Ubuntu 22.04 (glibc), LLVM/Clang | 68 + | ant-linux-aarch64 | Ubuntu 22.04 (glibc), LLVM/Clang | 69 + | ant-linux-x64-musl | Alpine Edge (musl), statically linked, Clang | 70 + | ant-linux-aarch64-musl | Alpine Edge (musl), statically linked, Clang | 71 + | ant-darwin-x64 | macOS 15 Intel, LLVM/Clang | 72 + | ant-darwin-aarch64 | macOS 15 ARM, LLVM/Clang | 73 + | ant-darwin-x64-mbedtls | macOS 15 Intel, LLVM/Clang, mbedTLS | 74 + | ant-darwin-aarch64-mbedtls | macOS 15 ARM, LLVM/Clang, mbedTLS | 75 + | ant-windows-x64 | MSYS2 MINGW64 toolchain | 76 + 77 + ## Building Ant on supported platforms 78 + 79 + ### Prerequisites 80 + 81 + The following tools are required to build Ant regardless of platform: 82 + 83 + - **C compiler** with C23 support (GCC >= 14 or Clang >= 18) 84 + - **[Meson](https://mesonbuild.com/)** build system (and Ninja backend) 85 + - **[CMake](https://cmake.org/)** (for the tlsuv subproject) 86 + - **pkg-config** 87 + - **Node.js** >= 22 (used to generate the JS snapshot at build time) 88 + - **[Rust](https://rustup.rs/)** toolchain (stable) with `cargo` (builds the OXC type-strip library) 89 + - **[Zig](https://ziglang.org/)** >= 0.15 (builds the package manager component) 90 + - **Git** 91 + 92 + System libraries required: 93 + 94 + - **OpenSSL** (default) or **mbedTLS** (alternative TLS backend) 95 + - **libsodium** 96 + - **libuuid** (Linux/macOS) 97 + - **llhttp** (if not building from source via cmake) 98 + 99 + The remaining dependencies are vendored as Meson subprojects under `vendor/` 100 + and are fetched automatically: 101 + 102 + - libuv 1.51.0 103 + - yyjson 0.12.0 104 + - zlib-ng 2.3.2 105 + - nghttp2 106 + - pcre2 107 + - libffi 108 + - lmdb (OpenLDAP LMDB 0.9.33) 109 + - minicoro 110 + - argtable3 111 + - uthash 112 + - uuidv7 113 + - tlsuv (cmake subproject) 114 + 115 + ### Unix and macOS 116 + 117 + #### Unix prerequisites 118 + 119 + Installation via package manager: 120 + 121 + - Ubuntu/Debian: 122 + 123 + ```bash 124 + sudo apt-get install python3 python3-pip gcc-14 g++-14 ninja-build cmake \ 125 + pkg-config uuid-dev libssl-dev libsodium-dev nodejs npm 126 + pip3 install meson 127 + ``` 128 + 129 + - Fedora: 130 + 131 + ```bash 132 + sudo dnf install python3 gcc gcc-c++ ninja-build cmake pkgconf \ 133 + libuuid-devel openssl-devel libsodium-devel nodejs npm 134 + pip3 install meson 135 + ``` 136 + 137 + - Alpine (musl): 138 + ```sh 139 + apk add clang lld llvm meson ninja cmake pkgconf nodejs npm \ 140 + musl-dev openssl-dev openssl-libs-static libsodium-dev libsodium-static \ 141 + util-linux-dev util-linux-static linux-headers libunwind-dev libunwind-static 142 + ``` 143 + 144 + You will also need Rust and Zig installed. The recommended approach: 145 + 146 + ```bash 147 + # Rust (via rustup) 148 + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 149 + 150 + # Zig (download from https://ziglang.org/download/) 151 + # Or via package manager if available 152 + ``` 153 + 154 + #### macOS prerequisites 155 + 156 + - Xcode Command Line Tools (provides Apple Clang): 157 + 158 + ```bash 159 + xcode-select --install 160 + ``` 161 + 162 + - Install remaining tools via [Homebrew](https://brew.sh): 163 + 164 + ```bash 165 + brew install meson ninja llvm openssl@3 libsodium node 166 + ``` 167 + 168 + - Rust and Zig: 169 + 170 + ```bash 171 + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 172 + brew install zig 173 + ``` 174 + 175 + #### Building Ant 176 + 177 + To build Ant: 178 + 179 + ```bash 180 + meson subprojects download 181 + meson setup build 182 + meson compile -C build 183 + ``` 184 + 185 + Alternatively, if you have [maid](https://github.com/exact-labs/maid) installed, <br> 186 + you can use the task runner: 187 + 188 + ```bash 189 + maid setup # downloads subprojects + configures with ccache and lld 190 + maid build # compiles 191 + maid run <file> # builds and runs a JS file 192 + ``` 193 + 194 + To verify the build: 195 + 196 + ```bash 197 + ./build/ant --version 198 + ./build/ant -e "console.log('Hello from Ant ' + Ant.version)" 199 + ``` 200 + 201 + #### Installing Ant 202 + 203 + You can install the built binary using: 204 + 205 + ```bash 206 + maid install 207 + ``` 208 + 209 + This copies the binary to the directory of an existing `ant` installation, or 210 + falls back to `~/.ant/bin/`. It also creates an `antx` symlink. 211 + 212 + Alternatively, copy the binary manually: 213 + 214 + ```bash 215 + cp ./build/ant /usr/local/bin/ant 216 + ``` 217 + 218 + #### Running tests 219 + 220 + To run a single test: 221 + 222 + ```bash 223 + ./build/ant tests/test_async.cjs 224 + ``` 225 + 226 + To run the spec suite: 227 + 228 + ```bash 229 + ./build/ant examples/spec/run.js 230 + ``` 231 + 232 + #### Building a debug build 233 + 234 + A debug build disables optimizations and LTO, and preserves debug symbols: 235 + 236 + ```bash 237 + meson subprojects download 238 + CC="ccache $(which clang)" \ 239 + meson setup build --wipe --buildtype=debug \ 240 + -Doptimization=0 -Db_lto=false -Dstrip=false -Db_lundef=false -Dunity=off 241 + meson compile -C build 242 + ``` 243 + 244 + Or with maid: 245 + 246 + ```bash 247 + maid debug 248 + maid build 249 + ``` 250 + 251 + When using the debug build, core dumps will be generated in case of crashes. 252 + Use `lldb` or `gdb` with the debug binary to inspect them: 253 + 254 + ```bash 255 + lldb ./build/ant core.ant 256 + (lldb) bt 257 + ``` 258 + 259 + #### Building an ASan build 260 + 261 + [ASan](https://github.com/google/sanitizers) can help detect memory bugs: 262 + 263 + ```bash 264 + meson subprojects download 265 + CC="ccache $(which clang)" \ 266 + meson setup build --wipe \ 267 + -Db_sanitize=address -Doptimization=0 -Db_lto=false -Dstrip=false -Db_lundef=false 268 + meson compile -C build 269 + ``` 270 + 271 + Or with maid: 272 + 273 + ```bash 274 + maid asan 275 + maid build 276 + ``` 277 + 278 + Then run tests against the ASan build: 279 + 280 + ```bash 281 + ./build/ant tests/test_gc.js 282 + ``` 283 + 284 + #### Speeding up frequent rebuilds when developing 285 + 286 + If you plan to frequently rebuild Ant, installing `ccache` can greatly 287 + reduce build times. The `maid setup` task configures ccache automatically. 288 + 289 + On GNU/Linux: 290 + 291 + ```bash 292 + sudo apt install ccache 293 + export CC="ccache gcc" # add to your .profile 294 + ``` 295 + 296 + On macOS: 297 + 298 + ```bash 299 + brew install ccache 300 + export CC="ccache cc" # add to ~/.zshrc 301 + ``` 302 + 303 + Using `lld` as the linker also speeds up link times: 304 + 305 + ```bash 306 + export CC_LD="$(which ld64.lld)" # macOS with brew llvm 307 + # or 308 + export CC_LD="$(which lld)" # Linux 309 + ``` 310 + 311 + Note: LTO is enabled by default with 8 threads (`b_lto=true`, 312 + `b_lto_threads=8`). Disable it with `-Db_lto=false` for faster iteration 313 + during development. 314 + 315 + #### Troubleshooting Unix and macOS builds 316 + 317 + Stale builds can sometimes result in errors. Clean the build directory and 318 + reconfigure: 319 + 320 + ```bash 321 + rm -rf build 322 + meson setup build 323 + meson compile -C build 324 + ``` 325 + 326 + If you encounter "file not found" errors for vendored dependencies: 327 + 328 + ```bash 329 + meson subprojects download 330 + ``` 331 + 332 + If the build runs out of memory, reduce parallelism: 333 + 334 + ```bash 335 + meson compile -C build -j2 336 + ``` 337 + 338 + ### Windows 339 + 340 + #### Windows prerequisites 341 + 342 + Ant on Windows is built using the MSYS2 MINGW64 toolchain. Native MSVC 343 + builds are not currently supported. 344 + 345 + 1. Install [MSYS2](https://www.msys2.org/) 346 + 2. Open the **MINGW64** shell and install dependencies: 347 + ```bash 348 + pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-meson \ 349 + mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake \ 350 + mingw-w64-x86_64-openssl mingw-w64-x86_64-libsodium \ 351 + mingw-w64-x86_64-lld mingw-w64-x86_64-nodejs git 352 + ``` 353 + 3. Install Rust via [rustup](https://rustup.rs/) (select the 354 + `x86_64-pc-windows-gnu` target) 355 + 4. Install [Zig](https://ziglang.org/download/) 356 + 357 + #### Building Ant 358 + 359 + From the MSYS2 MINGW64 shell: 360 + 361 + ```bash 362 + git clone https://github.com/theMackabu/ant.git 363 + cd ant 364 + meson subprojects download 365 + meson setup build -Dc_std=gnu2x 366 + meson compile -C build 367 + ``` 368 + 369 + Note: Windows builds use `-Dc_std=gnu2x` instead of `gnu23` due to MinGW 370 + toolchain compatibility. 371 + 372 + To verify: 373 + 374 + ```bash 375 + ./build/ant.exe --version 376 + ``` 377 + 378 + Windows builds require bundling the following DLLs alongside `ant.exe`: 379 + 380 + - `libssl-3-x64.dll` 381 + - `libcrypto-3-x64.dll` 382 + - `libsodium-26.dll` 383 + 384 + These are found in the MSYS2 MINGW64 bin directory 385 + (`/mingw64/bin/` or equivalent). 386 + 387 + ## Meson build options 388 + 389 + Configure options are set via `meson setup` or `meson configure`: 390 + 391 + | Option | Type | Default | Description | 392 + | ------------------- | ------- | --------- | ------------------------------------------ | 393 + | `static_link` | boolean | `false` | Statically link the final binary | 394 + | `build_timestamp` | string | (auto) | Build timestamp (defaults to current time) | 395 + | `tls_library` | combo | `openssl` | TLS backend: `openssl` or `mbedtls` | 396 + | `deps_prefix_cmake` | string | (empty) | Prefix path for cmake dependency lookup | 397 + 398 + Standard Meson built-in options used by Ant: 399 + 400 + | Option | Default | Description | 401 + | --------------- | --------- | --------------------------------- | 402 + | `buildtype` | `release` | Build type (release, debug, etc.) | 403 + | `optimization` | `3` | Optimization level (0-3) | 404 + | `c_std` | `gnu23` | C language standard | 405 + | `b_lto` | `true` | Link-time optimization | 406 + | `b_lto_threads` | `8` | LTO parallelism | 407 + | `strip` | `true` | Strip debug symbols from binary | 408 + | `b_sanitize` | `none` | Sanitizer (e.g. `address`) | 409 + 410 + Example: 411 + 412 + ```bash 413 + meson setup build -Dtls_library=mbedtls -Dstatic_link=true --prefer-static 414 + ``` 415 + 416 + ## TLS library selection 417 + 418 + Ant supports two TLS backends: 419 + 420 + - **OpenSSL** (default): Widely available, used on all platforms by default. 421 + - **mbedTLS**: Lighter alternative, useful for embedded or constrained 422 + environments. Currently only tested on macOS CI. 423 + 424 + To build with mbedTLS: 425 + 426 + ```bash 427 + meson setup build -Dtls_library=mbedtls 428 + ``` 429 + 430 + When using mbedTLS, the target triple in the version string will include 431 + `-mbedtls` as a suffix.
+7 -7
CONTRIBUTING.md
··· 4 4 5 5 ## Getting Started 6 6 7 - ### Prerequisites 8 - 9 - - C compiler with C23 support (GCC 14+ or Clang 18+) 10 - - Meson build system 11 - - Git 12 - - OpenSSL 13 - - libSodium 7 + For the full list of prerequisites and platform-specific setup instructions, <br> 8 + see [BUILDING.md](BUILDING.md#prerequisites). 14 9 15 10 ### Building from Source 16 11 ··· 21 16 meson setup build 22 17 meson compile -C build 23 18 ``` 19 + 20 + For detailed build instructions including debug builds, ASan builds, <br> 21 + ccache setup, and Windows/Linux/macOS specifics, see [BUILDING.md](BUILDING.md). 24 22 25 23 ## How to Contribute 26 24 ··· 65 63 tests/ # JavaScript test files 66 64 vendor/ # External dependencies 67 65 ``` 66 + 67 + For more information about Ant's internal structure, read the [Ant DeepWiki](https://deepwiki.com/theMackabu/ant). 68 68 69 69 ## Testing 70 70
+3 -9
README.md
··· 16 16 curl -fsSL https://ant.themackabu.com/install | MBEDTLS=1 bash 17 17 ``` 18 18 19 - ## Building from Source 20 - 21 - ```bash 22 - git clone https://github.com/theMackabu/ant.git && cd ant 19 + ## Building Ant 23 20 24 - meson subprojects download 25 - meson setup build 26 - meson compile -C build 27 - ``` 21 + See [BUILDING.md](BUILDING.md) for instructions on how to build Ant from source and a list of supported platforms. 28 22 29 23 ## Security 30 24 ··· 33 27 ## Contributing to Ant 34 28 35 29 We welcome contributions through pull request. See [CONTRIBUTING.md](CONTRIBUTING.md) for more details. <br> 36 - For more information about the internals, read the [ant deepwiki](https://deepwiki.com/theMackabu/ant). 30 + For more information about Ant's internal structure, read the [Ant DeepWiki](https://deepwiki.com/theMackabu/ant). 37 31 38 32 ## Current project team members 39 33
+148
tests/test_concurrent_scope.cjs
··· 1 + // Test concurrent async scope isolation 2 + // Verifies that closure variables survive across await boundaries 3 + // when multiple async functions run concurrently 4 + 5 + let passed = 0; 6 + let failed = 0; 7 + 8 + function assert(condition, msg) { 9 + if (condition) { 10 + passed++; 11 + } else { 12 + failed++; 13 + console.log('FAIL:', msg); 14 + } 15 + } 16 + 17 + // Test 1: Basic concurrent closure variable preservation 18 + async function worker(id, delayMs) { 19 + const myId = id; 20 + const myPrefix = 'worker-' + id; 21 + const myArray = [id, id * 10, id * 100]; 22 + const myObj = { name: myPrefix, value: id * 42 }; 23 + 24 + await new Promise(resolve => setTimeout(resolve, delayMs)); 25 + 26 + // After await, all closure variables should be intact 27 + assert(myId === id, `worker ${id}: myId was ${myId}, expected ${id}`); 28 + assert(myPrefix === 'worker-' + id, `worker ${id}: myPrefix was ${myPrefix}`); 29 + assert(myArray.length === 3, `worker ${id}: myArray.length was ${myArray.length}`); 30 + assert(myArray[0] === id, `worker ${id}: myArray[0] was ${myArray[0]}`); 31 + assert(myArray[2] === id * 100, `worker ${id}: myArray[2] was ${myArray[2]}`); 32 + assert(myObj.name === myPrefix, `worker ${id}: myObj.name was ${myObj.name}`); 33 + assert(myObj.value === id * 42, `worker ${id}: myObj.value was ${myObj.value}`); 34 + 35 + return myPrefix; 36 + } 37 + 38 + // Test 2: Multiple sequential awaits with closure vars 39 + async function multiAwait(id) { 40 + const step1 = 'step1-' + id; 41 + await new Promise(resolve => setTimeout(resolve, 10)); 42 + 43 + assert(step1 === 'step1-' + id, `multiAwait ${id} after 1st await: step1 was ${step1}`); 44 + 45 + const step2 = 'step2-' + id; 46 + await new Promise(resolve => setTimeout(resolve, 10)); 47 + 48 + assert(step1 === 'step1-' + id, `multiAwait ${id} after 2nd await: step1 was ${step1}`); 49 + assert(step2 === 'step2-' + id, `multiAwait ${id} after 2nd await: step2 was ${step2}`); 50 + 51 + const step3 = 'step3-' + id; 52 + await new Promise(resolve => setTimeout(resolve, 10)); 53 + 54 + assert(step1 === 'step1-' + id, `multiAwait ${id} after 3rd await: step1 was ${step1}`); 55 + assert(step2 === 'step2-' + id, `multiAwait ${id} after 3rd await: step2 was ${step2}`); 56 + assert(step3 === 'step3-' + id, `multiAwait ${id} after 3rd await: step3 was ${step3}`); 57 + 58 + return [step1, step2, step3]; 59 + } 60 + 61 + // Test 3: Arrow function closures in async context 62 + async function closureTest(id) { 63 + const captured = 'captured-' + id; 64 + const transform = x => captured + '-' + x; 65 + 66 + await new Promise(resolve => setTimeout(resolve, 15)); 67 + 68 + const result = transform('test'); 69 + assert(result === 'captured-' + id + '-test', `closureTest ${id}: transform result was ${result}`); 70 + assert(captured === 'captured-' + id, `closureTest ${id}: captured was ${captured}`); 71 + 72 + return result; 73 + } 74 + 75 + // Test 4: Nested async calls with closure isolation 76 + async function outer(id) { 77 + const outerVar = 'outer-' + id; 78 + 79 + async function inner(suffix) { 80 + const innerVar = outerVar + '-inner-' + suffix; 81 + await new Promise(resolve => setTimeout(resolve, 5)); 82 + assert(innerVar === 'outer-' + id + '-inner-' + suffix, `inner ${id}/${suffix}: innerVar was ${innerVar}`); 83 + assert(outerVar === 'outer-' + id, `inner ${id}/${suffix}: outerVar was ${outerVar}`); 84 + return innerVar; 85 + } 86 + 87 + const r1 = await inner('a'); 88 + assert(outerVar === 'outer-' + id, `outer ${id} after inner a: outerVar was ${outerVar}`); 89 + 90 + const r2 = await inner('b'); 91 + assert(outerVar === 'outer-' + id, `outer ${id} after inner b: outerVar was ${outerVar}`); 92 + 93 + return [r1, r2]; 94 + } 95 + 96 + // Test 5: Parameter preservation across await 97 + async function paramTest(a, b, c) { 98 + const sum = a + b + c; 99 + await new Promise(resolve => setTimeout(resolve, 10)); 100 + 101 + assert(a + b + c === sum, `paramTest: sum was ${a + b + c}, expected ${sum}`); 102 + assert(typeof a === 'number', `paramTest: a type was ${typeof a}`); 103 + assert(typeof b === 'string', `paramTest: b type was ${typeof b}`); 104 + assert(typeof c === 'boolean', `paramTest: c type was ${typeof c}`); 105 + 106 + return sum; 107 + } 108 + 109 + // Launch all tests concurrently 110 + async function main() { 111 + const promises = []; 112 + 113 + // Launch 5 concurrent workers with different delays 114 + for (let i = 1; i <= 5; i++) { 115 + promises.push(worker(i, 10 + i * 5)); 116 + } 117 + 118 + // Launch 3 concurrent multi-await chains 119 + for (let i = 1; i <= 3; i++) { 120 + promises.push(multiAwait(i)); 121 + } 122 + 123 + // Launch 3 concurrent closure tests 124 + for (let i = 1; i <= 3; i++) { 125 + promises.push(closureTest(i)); 126 + } 127 + 128 + // Launch 3 concurrent nested async tests 129 + for (let i = 1; i <= 3; i++) { 130 + promises.push(outer(i)); 131 + } 132 + 133 + // Launch concurrent param tests 134 + promises.push(paramTest(42, 'hello', true)); 135 + promises.push(paramTest(99, 'world', false)); 136 + 137 + await Promise.all(promises); 138 + 139 + console.log(`Results: ${passed} passed, ${failed} failed`); 140 + if (failed > 0) { 141 + console.log('FAIL: concurrent scope isolation test'); 142 + Ant.exit(1); 143 + } else { 144 + console.log('PASS: concurrent scope isolation test'); 145 + } 146 + } 147 + 148 + main();