From 96184b614c13adfdbb079a9cb5ce479f49f97e05 Mon Sep 17 00:00:00 2001 From: ASDAlexander77 Date: Mon, 12 Oct 2026 10:26:48 +0100 Subject: [PATCH] Android: armeabi-v7a (32-bit ARM) joins arm64-v8a and x86_64 The collector and async runtime scripts build it too (no argument builds all three), the release workflow stages android/armeabi-v7a/lib into the zip, and default-lib-dir.cmake pins where its default library goes (defaultlib/lib/arm/unknown/linux/android/...). README updated. Checked: tslang -mtriple=armv7a-linux-androideabi29 emits ELF32 ARM objects, links an executable and a shared library against the three libraries, and the executable runs on an armeabi-v7a device. Co-Authored-By: Claude Sonnet 5.5 --- .github/workflows/create-release.yml | 6 +++--- README.md | 11 ++++++----- scripts/build_gc_release_android.bat | 3 ++- scripts/build_tslang_runtime_release_android.bat | 3 ++- tslang/test/tester/default-lib-dir.cmake | 1 + 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index f9e9b2f3b..56a9efcbf 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -201,7 +201,7 @@ jobs: if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } shell: pwsh - # Android (API 29, arm64-v8a and x86_64): the collector, the async runtime and the default + # Android (API 29, arm64-v8a, armeabi-v7a and x86_64): the collector, the async runtime and the default # library, cross-built with the runner's Android NDK by the same scripts a developer runs. # tslang links for Android through the NDK too (--android-ndk-path / ANDROID_NDK_HOME). - name: Install Ninja (Android builds) @@ -261,10 +261,10 @@ jobs: # (findResourceDir's "release package" candidate), so stage that layout too - its headers # only: the official LLVM package also puts compiler-rt's libraries under # lib/clang//lib, which neither tsbindgen nor tslang uses. - # Android, per ABI (arm64-v8a, x86_64): android//lib/{libgc.a,libTypeScriptAsyncRuntime.a} + # Android, per ABI (arm64-v8a, armeabi-v7a, x86_64): android//lib/{libgc.a,libTypeScriptAsyncRuntime.a} # (--gc-lib-path and --tslang-lib-path); its default library is in the defaultlib tree above. run: | - foreach ($abi in 'arm64-v8a', 'x86_64') { + foreach ($abi in 'arm64-v8a', 'armeabi-v7a', 'x86_64') { $dest = ".\android_stage\android\$abi" New-Item -ItemType Directory -Force -Path "$dest\lib" | Out-Null Copy-Item -Path "..\3rdParty\gc\android\$abi\release\lib\libgc.a", ".\tslang-runtime\release\android\$abi\libTypeScriptAsyncRuntime.a" -Destination "$dest\lib" -ErrorAction Stop diff --git a/README.md b/README.md index 247271ef3..f42dda914 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ on the fly via a built-in JIT — no Node.js or JavaScript runtime required. - **25 samples**, TypeScript ports of NVIDIA's Donut samples on the [Donut](https://github.com/NVIDIA-RTX/Donut) rendering framework, on **Direct3D 12** and **Vulkan**: from `basic_triangle` and `deferred_shading` to ray tracing (`rt_reflections`, `rt_shadows`, `rt_particles`), meshlets, compute n-body, order-independent transparency, terrain tessellation, variable-rate shading and work graphs - **Mixed C++/TypeScript** through CMake: `.ts` files are a first-class CMake language (`TSLANG`), compiled with `tslang --emit=obj` and linked with the C++ code, with incremental rebuilds -- Runs on **Windows** and **Android** (Vulkan, `arm64-v8a` and `x86_64`): the Vulkan samples are packaged as APKs, with a script that builds the samples, starts an emulator and tests them +- Runs on **Windows** and **Android** (Vulkan, `arm64-v8a`, `armeabi-v7a` and `x86_64`): the Vulkan samples are packaged as APKs, with a script that builds the samples, starts an emulator and tests them - Choose the memory model at configure time: `-DTSLANG_MEMORY_MODEL=gc|rc|none` It is a good place to see how TypeScript code drives a native C++ framework: the samples call Donut through a C interop layer (`donut_interop.d.ts`) wrapped in TypeScript classes. @@ -50,7 +50,7 @@ It is a good place to see how TypeScript code drives a native C++ framework: the ## What's new - New memory model **`-mm=own`**: single ownership inferred at compile time, like Rust's borrow checker. There is no collector and no reference counting, and a program whose ownership cannot be proven is a compile error. Shared ownership is opt-in with `Shared`. See [Memory models](#memory-models) -- **Android** targets (`arm64-v8a`, `x86_64`, API 29+): executables and shared libraries linked through the Android NDK. The release zip carries the collector, async runtime and default library for both ABIs. See [Compile for Android](#compile-for-android) +- **Android** targets (`arm64-v8a`, `armeabi-v7a`, `x86_64`, API 29+): executables and shared libraries linked through the Android NDK. The release zip carries the collector, async runtime and default library for all three ABIs. See [Compile for Android](#compile-for-android) - Implemented `try/catch` exception handling in the **JIT** on Windows (x64 SEH unwinding via a custom LLJIT runtime) - Migrared to **LLVM 22.1.8** - Migrated to **Visual Studio 2026** (Windows build chain) @@ -358,12 +358,13 @@ Hello World! ## Compile for Android `tslang` cross-compiles for Android from a Windows host. It targets `arm64-v8a` -(`-mtriple=aarch64-linux-android29`) and `x86_64` (`-mtriple=x86_64-linux-android29`), and links +(`-mtriple=aarch64-linux-android29`), `armeabi-v7a` (`-mtriple=armv7a-linux-androideabi29`) and +`x86_64` (`-mtriple=x86_64-linux-android29`), and links through the Android NDK (tested with r29 and r30). The triple has to carry the API level, and 29 is the lowest the default library supports. Point `--android-ndk-path` (or `ANDROID_NDK_HOME`) at the NDK. -The Windows release zip carries the Android libraries for both ABIs: +The Windows release zip carries the Android libraries for all three ABIs: | Library | Option | | --- | --- | @@ -793,7 +794,7 @@ chmod +x *.sh The release zip already carries these libraries. To build them yourself, use a Windows host with the Android NDK (r29 or r30) in `ANDROID_NDK_HOME` and Ninja on `PATH`. Run these after `prepare_3rdParty.bat`, which provides the gc sources and the LLVM headers they use. Each script builds both -`arm64-v8a` and `x86_64` for API level 29, or only the ABI you pass: +`arm64-v8a`, `armeabi-v7a` and `x86_64` for API level 29, or only the ABI you pass: ```bat cd TypeScriptCompiler diff --git a/scripts/build_gc_release_android.bat b/scripts/build_gc_release_android.bat index 5b5cf3247..ac6fe60ef 100644 --- a/scripts/build_gc_release_android.bat +++ b/scripts/build_gc_release_android.bat @@ -1,6 +1,6 @@ @rem Android Boehm, static, for programs compiled with -mtriple=-linux-android29. @rem -@rem scripts\build_gc_release_android.bat [arm64-v8a|x86_64] (no argument: both) +@rem scripts\build_gc_release_android.bat [arm64-v8a|armeabi-v7a|x86_64] (no argument: all three) @rem @rem Needs the Android NDK (tested with r30) in ANDROID_NDK_HOME, and Ninja. Installs into @rem 3rdParty\gc\android\\release. API level 29 is the floor the default library needs @@ -24,6 +24,7 @@ if not exist "%ANDROID_NDK_HOME%\build\cmake\android.toolchain.cmake" ( if "%~1"=="" ( call "%~f0" arm64-v8a || exit /b 1 + call "%~f0" armeabi-v7a || exit /b 1 call "%~f0" x86_64 || exit /b 1 exit /b 0 ) diff --git a/scripts/build_tslang_runtime_release_android.bat b/scripts/build_tslang_runtime_release_android.bat index e1e0e952f..9b3d97999 100644 --- a/scripts/build_tslang_runtime_release_android.bat +++ b/scripts/build_tslang_runtime_release_android.bat @@ -1,7 +1,7 @@ @rem TypeScriptAsyncRuntime for Android, linked into programs compiled with @rem -mtriple=-linux-android29. @rem -@rem scripts\build_tslang_runtime_release_android.bat [arm64-v8a|x86_64] (no argument: both) +@rem scripts\build_tslang_runtime_release_android.bat [arm64-v8a|armeabi-v7a|x86_64] (no argument: all three) @rem @rem Needs the Android NDK in ANDROID_NDK_HOME, Ninja, the Android gc @rem (scripts\build_gc_release_android.bat) for gc.h, and 3rdParty\llvm\x64\release\include for @@ -17,6 +17,7 @@ if "%ANDROID_NDK_HOME%"=="" ( if "%~1"=="" ( call "%~f0" arm64-v8a || exit /b 1 + call "%~f0" armeabi-v7a || exit /b 1 call "%~f0" x86_64 || exit /b 1 exit /b 0 ) diff --git a/tslang/test/tester/default-lib-dir.cmake b/tslang/test/tester/default-lib-dir.cmake index 8617b2733..fc6b4d20a 100644 --- a/tslang/test/tester/default-lib-dir.cmake +++ b/tslang/test/tester/default-lib-dir.cmake @@ -25,6 +25,7 @@ check("defaultlib/lib/x86_64/pc/windows/msvc/release/gc" --print-default-lib-dir check("defaultlib/dll/x86_64/pc/windows/msvc/debug/rc" --print-default-lib-dir=dll --di -mm=rc -mtriple=x86_64-pc-windows-msvc) check("defaultlib/lib/x86_64/unknown/linux/gnu/release/none" --print-default-lib-dir=lib -mm=none -mtriple=x86_64-unknown-linux-gnu) check("defaultlib/lib/aarch64/unknown/linux/android/release/gc" --print-default-lib-dir=lib -mtriple=aarch64-linux-android29) +check("defaultlib/lib/arm/unknown/linux/android/release/gc" --print-default-lib-dir=lib -mtriple=armv7a-linux-androideabi29) # the spellings of one target share its tree: the canonical arch name, no API level or version check("defaultlib/lib/i386/pc/windows/msvc/release/gc" --print-default-lib-dir=lib -mtriple=i686-pc-windows-msvc)