Skip to content

Commit d2e3993

Browse files
feat: cross-compile for android (! for termux users) (#264)
* feat: cross-compile for android (! for termux users) * chore: Update docs for - feat: cross-compile for android (! for termux users)
1 parent a411100 commit d2e3993

6 files changed

Lines changed: 67 additions & 24 deletions

File tree

.cargo/config.toml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,7 @@ rustflags = ["-C", "target-feature=-crt-static"]
1010
[target.aarch64-unknown-linux-musl]
1111
rustflags = ["-C", "target-feature=-crt-static"]
1212

13+
# Android/Termux: no hardcoded linker so native Termux builds use the system cc.
14+
# For CI cross-compilation the linker is set via CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER env var.
1315
[target.aarch64-linux-android]
14-
rustflags = [
15-
"-C",
16-
"linker=aarch64-linux-android-clang",
17-
"-C",
18-
"link-args=-rdynamic",
19-
"-C",
20-
"default-linker-libraries",
21-
]
16+
rustflags = ["-C", "link-args=-rdynamic"]

.github/workflows/release.yaml

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Prebuild
22

33
on:
44
push:
5-
branches: [main, feat/interchangable-ffi]
5+
branches: [main, feat/interchangable-ffi, feat/termux]
66
pull_request:
77

88
jobs:
@@ -36,6 +36,12 @@ jobs:
3636
artifact_name: target/aarch64-unknown-linux-musl/release/libfff_nvim.so
3737
ext: so
3838

39+
## Android (Termux)
40+
- os: ubuntu-latest
41+
target: aarch64-linux-android
42+
artifact_name: target/aarch64-linux-android/release/libfff_nvim.so
43+
ext: so
44+
3945
## macOS builds
4046
- os: macos-latest
4147
target: x86_64-apple-darwin
@@ -73,11 +79,25 @@ jobs:
7379
run: cargo install cargo-zigbuild
7480

7581
- name: Build for Linux
76-
if: contains(matrix.os, 'ubuntu')
82+
if: contains(matrix.os, 'ubuntu') && !contains(matrix.target, 'android')
7783
run: |
7884
cargo zigbuild --release --target ${{ matrix.zigbuild_target || matrix.target }} -p fff-nvim
7985
mv "${{ matrix.artifact_name }}" "${{ matrix.target }}.${{ matrix.ext }}"
8086
87+
- name: Build for Android (Termux)
88+
if: contains(matrix.target, 'android')
89+
run: |
90+
NDK_BIN="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin"
91+
92+
# NDK clang for C deps (libgit2, lmdb, blake3) that need Bionic sysroot headers
93+
export CC_aarch64_linux_android="$NDK_BIN/aarch64-linux-android24-clang"
94+
export CXX_aarch64_linux_android="$NDK_BIN/aarch64-linux-android24-clang++"
95+
export AR_aarch64_linux_android="$NDK_BIN/llvm-ar"
96+
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$NDK_BIN/aarch64-linux-android24-clang"
97+
98+
cargo build --release --target ${{ matrix.target }} -p fff-nvim
99+
mv "${{ matrix.artifact_name }}" "${{ matrix.target }}.${{ matrix.ext }}"
100+
81101
- name: Build for macOS
82102
if: contains(matrix.os, 'macos')
83103
run: |
@@ -137,6 +157,13 @@ jobs:
137157
lib_filename: libfff_c.so
138158
ext: so
139159

160+
## Android (Termux)
161+
- os: ubuntu-latest
162+
target: aarch64-linux-android
163+
artifact_name: target/aarch64-linux-android/release/libfff_c.so
164+
lib_filename: libfff_c.so
165+
ext: so
166+
140167
## macOS builds
141168
- os: macos-latest
142169
target: x86_64-apple-darwin
@@ -183,11 +210,24 @@ jobs:
183210
run: cargo install cargo-zigbuild
184211

185212
- name: Build for Linux
186-
if: contains(matrix.os, 'ubuntu')
213+
if: contains(matrix.os, 'ubuntu') && !contains(matrix.target, 'android')
187214
run: |
188215
cargo zigbuild --release --target ${{ matrix.zigbuild_target || matrix.target }} -p fff-c
189216
mv "${{ matrix.artifact_name }}" "c-lib-${{ matrix.target }}.${{ matrix.ext }}"
190217
218+
- name: Build for Android (Termux)
219+
if: contains(matrix.target, 'android')
220+
run: |
221+
NDK_BIN="$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin"
222+
223+
export CC_aarch64_linux_android="$NDK_BIN/aarch64-linux-android24-clang"
224+
export CXX_aarch64_linux_android="$NDK_BIN/aarch64-linux-android24-clang++"
225+
export AR_aarch64_linux_android="$NDK_BIN/llvm-ar"
226+
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$NDK_BIN/aarch64-linux-android24-clang"
227+
228+
cargo build --release --target ${{ matrix.target }} -p fff-c
229+
mv "${{ matrix.artifact_name }}" "c-lib-${{ matrix.target }}.${{ matrix.ext }}"
230+
191231
- name: Build for macOS
192232
if: contains(matrix.os, 'macos')
193233
run: |
@@ -206,6 +246,7 @@ jobs:
206246
mv "${{ matrix.artifact_name }}" "c-lib-${{ matrix.target }}.${{ matrix.ext }}"
207247
208248
- name: Prepare npm package
249+
if: "!contains(matrix.target, 'android')"
209250
shell: bash
210251
run: |
211252
# Copy the built binary into the platform npm package directory
@@ -218,6 +259,7 @@ jobs:
218259
path: c-lib-${{ matrix.target }}.*
219260

220261
- name: Upload npm package artifact
262+
if: "!contains(matrix.target, 'android')"
221263
uses: actions/upload-artifact@v4
222264
with:
223265
name: npm-${{ matrix.npm_package }}

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ heed = "0.22.0"
2828
ignore = "0.4.22"
2929
memmap2 = "0.9"
3030
mimalloc = "0.1.47"
31-
zlob = "1.2.9"
31+
zlob = "1.3.0"
3232

3333
mlua = { version = "0.11.1", features = ["module", "luajit"] }
3434
neo_frizbee = "0.8.1"

doc/fff.nvim.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*fff.nvim.txt* For Neovim >= 0.10.0 Last change: 2026 February 26
1+
*fff.nvim.txt* For Neovim >= 0.10.0 Last change: 2026 February 28
22

33
==============================================================================
44
Table of Contents *fff.nvim-table-of-contents*

lua/fff/utils/system.lua

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,24 @@ function M.get_triple()
1111
if os_name == 'darwin' then
1212
os_name = 'apple-darwin'
1313
elseif os_name == 'linux' then
14-
-- Detect if we're on musl or glibc
15-
local handle = io.popen('ldd --version 2>&1')
16-
if handle then
17-
local output = handle:read('*a')
18-
handle:close()
19-
if output and output:match('musl') then
20-
os_name = 'unknown-linux-musl'
14+
-- Detect Android/Termux before checking musl/glibc.
15+
-- Termux uses Bionic libc (not glibc or musl) and has no ldd.
16+
if os.getenv('TERMUX_VERSION') or os.getenv('ANDROID_ROOT') then
17+
os_name = 'linux-android'
18+
else
19+
-- Detect if we're on musl or glibc
20+
local handle = io.popen('ldd --version 2>&1')
21+
if handle then
22+
local output = handle:read('*a')
23+
handle:close()
24+
if output and output:match('musl') then
25+
os_name = 'unknown-linux-musl'
26+
else
27+
os_name = 'unknown-linux-gnu'
28+
end
2129
else
2230
os_name = 'unknown-linux-gnu'
2331
end
24-
else
25-
os_name = 'unknown-linux-gnu'
2632
end
2733
elseif os_name:match('windows') or os_name:match('mingw') or os_name:match('msys') then
2834
os_name = 'pc-windows-msvc'

0 commit comments

Comments
 (0)