Skip to content

Commit f2aec74

Browse files
authored
Add Android precompile workflow (#346)
- add Android `aarch64-linux-android` and `armv7a-linux-androideabi` targets to the existing `cc_precompiler` configuration - map Android precompile targets to the Android NDK clang toolchain while keeping the existing Linux/macOS/Windows targets unchanged by default - add an Android precompile workflow that builds one Android target per matrix job and publishes matching release artifacts on tags Note: I validated the normal native build/test path locally on macOS. The Android cross-compile path depends on the GitHub-hosted Linux runner's Android NDK installation, so the new workflow is the first full NDK validation point. Fixes #165
1 parent 3e45199 commit f2aec74

3 files changed

Lines changed: 91 additions & 1 deletion

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: android-precompile
2+
3+
on:
4+
push:
5+
branches:
6+
- "main"
7+
tags:
8+
- 'v*'
9+
10+
permissions:
11+
contents: write
12+
13+
jobs:
14+
precompile:
15+
runs-on: ubuntu-latest
16+
env:
17+
ImageOS: ubuntu22
18+
MIX_ENV: prod
19+
ANDROID_API_LEVEL: "24"
20+
CC_PRECOMPILER_ONLY_LISTED_TARGETS: "true"
21+
CC_PRECOMPILER_PRECOMPILE_ONLY_LOCAL: "true"
22+
strategy:
23+
matrix:
24+
target:
25+
- triplet: aarch64-linux-android
26+
arch: aarch64
27+
os: linux
28+
abi: android
29+
- triplet: armv7a-linux-androideabi
30+
arch: armv7a
31+
os: linux
32+
abi: androideabi
33+
job:
34+
- {otp: "27", elixir: "1.17"}
35+
- {otp: "25", elixir: "1.16"}
36+
37+
name: Android ${{ matrix.target.triplet }} - OTP ${{ matrix.job.otp }} - Elixir ${{ matrix.job.elixir }}
38+
steps:
39+
- name: Checkout
40+
uses: actions/checkout@v6
41+
42+
- uses: erlef/setup-beam@v1
43+
with:
44+
otp-version: ${{ matrix.job.otp }}
45+
elixir-version: ${{ matrix.job.elixir }}
46+
47+
- name: Add Android NDK toolchain to PATH
48+
run: |
49+
ANDROID_NDK="${ANDROID_NDK_LATEST_HOME:-${ANDROID_NDK_HOME:-${ANDROID_NDK_ROOT:-}}}"
50+
51+
if [ -z "${ANDROID_NDK}" ]; then
52+
echo "No Android NDK path is set on this runner" >&2
53+
exit 1
54+
fi
55+
56+
echo "${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin" >> "${GITHUB_PATH}"
57+
58+
- name: Create precompiled ${{ matrix.target.triplet }} library
59+
env:
60+
TARGET_ARCH: ${{ matrix.target.arch }}
61+
TARGET_OS: ${{ matrix.target.os }}
62+
TARGET_ABI: ${{ matrix.target.abi }}
63+
ELIXIR_MAKE_CACHE_DIR: ${{ github.workspace }}/cache
64+
run: |
65+
mkdir -p "${ELIXIR_MAKE_CACHE_DIR}"
66+
mix deps.get
67+
mix elixir_make.precompile
68+
69+
- uses: softprops/action-gh-release@v1
70+
if: startsWith(github.ref, 'refs/tags/')
71+
with:
72+
files: |
73+
cache/*${{ matrix.target.triplet }}*.tar.gz

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ endif
4343

4444
KERNEL_NAME := $(shell uname -s)
4545

46+
ifneq ($(findstring android,$(CC_PRECOMPILER_CURRENT_TARGET)),)
47+
CROSSCOMPILE ?= Android
48+
endif
49+
4650
PREFIX = $(MIX_APP_PATH)/priv
4751
BUILD = $(MIX_APP_PATH)/obj
4852
LIB_NAME = $(PREFIX)/sqlite3_nif.so

mix.exs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,16 @@ defmodule Exqlite.MixProject do
137137
defp cc_precompiler do
138138
[
139139
cleanup: "clean",
140+
only_listed_targets:
141+
System.get_env("CC_PRECOMPILER_ONLY_LISTED_TARGETS") == "true",
140142
compilers: %{
141143
{:unix, :linux} => %{
142144
:include_default_ones => true,
143145
"x86_64-linux-musl" => "x86_64-linux-musl-",
144146
"aarch64-linux-musl" => "aarch64-linux-musl-",
145-
"riscv64-linux-musl" => "riscv64-linux-musl-"
147+
"riscv64-linux-musl" => "riscv64-linux-musl-",
148+
"aarch64-linux-android" => android_compilers("aarch64-linux-android"),
149+
"armv7a-linux-androideabi" => android_compilers("armv7a-linux-androideabi")
146150
},
147151
{:unix, :darwin} => %{
148152
:include_default_ones => true
@@ -153,4 +157,13 @@ defmodule Exqlite.MixProject do
153157
}
154158
]
155159
end
160+
161+
defp android_compilers(target) do
162+
api_level = System.get_env("ANDROID_API_LEVEL", "24")
163+
164+
{
165+
"#{target}#{api_level}-clang",
166+
"#{target}#{api_level}-clang++"
167+
}
168+
end
156169
end

0 commit comments

Comments
 (0)