Skip to content

Commit c07b282

Browse files
authored
Merge pull request #4 from jappeace-sloth/remove-haskell-nix
Remove haskell.nix, use nixpkgs cross-compilation for Android
2 parents 2bd4301 + 32947e7 commit c07b282

7 files changed

Lines changed: 74 additions & 157 deletions

File tree

‎.github/workflows/ci.yaml‎

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- uses: cachix/cachix-action@v15
2727
with:
2828
name: jappie
29-
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
29+
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
3030
- run: nix-build
3131
- run: nix-shell --run "echo OK"
3232
- name: Cancel workflow on failure
@@ -49,13 +49,11 @@ jobs:
4949
with:
5050
extra_nix_config: |
5151
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
52-
extra-substituters = https://cache.iog.io
53-
extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=
5452
- uses: cachix/cachix-action@v15
5553
with:
5654
name: jappie
57-
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
58-
- run: nix-build nix/android.nix -A lib
55+
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
56+
- run: nix-build nix/android.nix
5957
- name: Cancel workflow on failure
6058
if: failure()
6159
continue-on-error: true
@@ -76,12 +74,10 @@ jobs:
7674
with:
7775
extra_nix_config: |
7876
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
79-
extra-substituters = https://cache.iog.io
80-
extra-trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=
8177
- uses: cachix/cachix-action@v15
8278
with:
8379
name: jappie
84-
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
80+
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
8581
- run: nix-build nix/ios.nix
8682
- name: Cancel workflow on failure
8783
if: failure()

‎ci.nix‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ let
33
|| builtins.currentSystem == "x86_64-darwin";
44
in {
55
native = import ./default.nix {};
6-
android = (import ./nix/android.nix {}).lib;
6+
android = import ./nix/android.nix {};
77
apk = import ./nix/apk.nix {};
88
} // (if isDarwin then {
99
ios = import ./nix/ios.nix {};

‎nix/android.nix‎

Lines changed: 68 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,73 @@
1+
# Android shared library build pipeline.
2+
# Builds Haskell to a shared .so for aarch64-android using nixpkgs
3+
# cross-compilation (pkgsCross.aarch64-android-prebuilt) instead of
4+
# haskell.nix, which builds GHC from source without cache hits.
5+
#
6+
# Uses Google's prebuilt NDK toolchain via nixpkgs, avoiding the
7+
# LLVM 19 compiler-rt issue (NixOS/nixpkgs#380604).
18
{ sources ? import ../npins }:
29
let
3-
# Import haskell.nix from the armv7a branch (provides Android cross-compiler)
4-
haskellNix = import sources."haskell.nix" {};
5-
6-
# Use nixpkgs-2305 which has LLVM 14. nixpkgs-unstable has LLVM 19 whose
7-
# compiler-rt is broken for Android (os_version_check.c needs pthread.h
8-
# which is unavailable in the builtins-only sysroot).
9-
# See: https://github.com/NixOS/nixpkgs/issues/380604
10-
11-
# Android API 26 (Android 8.0 Oreo) overlay — re-imports nixpkgs with
12-
# modified crossSystem, same approach as simplex-chat.
13-
android26 = final: prev: {
14-
pkgsCross = prev.pkgsCross // {
15-
aarch64-android = import prev.path {
16-
crossSystem = prev.lib.systems.examples.aarch64-android // {
17-
sdkVer = "26";
18-
};
19-
localSystem = prev.buildPlatform;
20-
inherit (prev) config overlays;
21-
};
22-
};
10+
pkgs = import sources.nixpkgs {
11+
config.allowUnfree = true;
12+
config.android_sdk.accept_license = true;
2313
};
2414

25-
pkgs = import haskellNix.sources.nixpkgs-2305 (haskellNix.nixpkgsArgs // {
26-
overlays = haskellNix.nixpkgsArgs.overlays ++ [ android26 ];
27-
});
28-
29-
androidPkgs = pkgs.pkgsCross.aarch64-android;
30-
31-
# Android doesn't have LANGINFO_CODESET, but nixpkgs autoconf detects it.
32-
# Patch libiconv to undefine it and enable static linking.
33-
androidIconv = (androidPkgs.libiconv.override {
34-
enableStatic = true;
35-
}).overrideAttrs (old: {
36-
postConfigure = ''
37-
echo "#undef HAVE_LANGINFO_CODESET" >> libcharset/config.h
38-
echo "#undef HAVE_LANGINFO_CODESET" >> lib/config.h
39-
'';
40-
});
41-
42-
# Disable fortify hardening (incompatible with Android NDK) and enable static.
43-
androidFFI = androidPkgs.libffi.overrideAttrs (old: {
44-
dontDisableStatic = true;
45-
hardeningDisable = [ "fortify" ];
46-
});
47-
48-
project = import ./project.nix { inherit pkgs; };
49-
50-
in {
51-
inherit pkgs androidPkgs androidIconv androidFFI;
52-
lib = project.projectCross.aarch64-android.hsPkgs.haskell-mobile.components.library;
53-
crossLib = project.projectCross.aarch64-android.hsPkgs.haskell-mobile.components.library;
54-
# Expose all cross-compiled haskell packages for linking
55-
hsPkgs = project.projectCross.aarch64-android.hsPkgs;
15+
# Cross-compilation packages for Android using prebuilt NDK toolchain
16+
androidPkgs = pkgs.pkgsCross.aarch64-android-prebuilt;
17+
18+
# Cross-GHC: runs on x86_64-linux, produces aarch64-android code
19+
ghc = androidPkgs.haskellPackages.ghc;
20+
ghcCmd = "${ghc}/bin/${ghc.targetPrefix}ghc";
21+
22+
# NDK toolchain for compiling the JNI bridge C code
23+
androidComposition = pkgs.androidenv.composeAndroidPackages {
24+
includeNDK = true;
25+
};
26+
ndk = "${androidComposition.ndk-bundle}/libexec/android-sdk/ndk/${androidComposition.ndk-bundle.version}";
27+
ndkCc = "${ndk}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang";
28+
sysroot = "${ndk}/toolchains/llvm/prebuilt/linux-x86_64/sysroot";
29+
30+
in pkgs.stdenv.mkDerivation {
31+
pname = "haskell-mobile-android";
32+
version = "0.1.0.0";
33+
34+
src = ../src;
35+
36+
nativeBuildInputs = [ ghc ];
37+
buildInputs = [ androidPkgs.libffi androidPkgs.gmp ];
38+
39+
buildPhase = ''
40+
# Discover RTS include path for HsFFI.h
41+
GHC_LIBDIR=$(${ghcCmd} --print-libdir)
42+
RTS_INCLUDE=$(dirname $(find $GHC_LIBDIR -name "HsFFI.h" | head -1))
43+
44+
echo "GHC: ${ghcCmd}"
45+
echo "GHC libdir: $GHC_LIBDIR"
46+
echo "RTS include: $RTS_INCLUDE"
47+
48+
# Step 1: Compile JNI bridge with NDK clang
49+
${ndkCc} -c -fPIC \
50+
-I${sysroot}/usr/include \
51+
-I$RTS_INCLUDE \
52+
-o jni_bridge.o \
53+
${../cbits/jni_bridge.c}
54+
55+
# Step 2: Compile Haskell to shared library with cross-GHC
56+
${ghcCmd} -shared -O2 \
57+
-o libhaskellmobile.so \
58+
HaskellMobile.hs \
59+
${../cbits/android_stubs.c} \
60+
-optl-L${androidPkgs.gmp}/lib \
61+
-optl-L${androidPkgs.libffi}/lib \
62+
-optl-lffi \
63+
-optl-Wl,-z,max-page-size=16384 \
64+
-optl$(pwd)/jni_bridge.o \
65+
-optl-Wl,-u,haskellInit \
66+
-optl-Wl,-u,haskellGreet
67+
'';
68+
69+
installPhase = ''
70+
mkdir -p $out/lib/arm64-v8a
71+
cp libhaskellmobile.so $out/lib/arm64-v8a/
72+
'';
5673
}

‎nix/apk.nix‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ let
55
config.android_sdk.accept_license = true;
66
};
77

8-
sharedLib = import ./shared-lib.nix { inherit sources; };
8+
sharedLib = import ./android.nix { inherit sources; };
99

1010
androidComposition = pkgs.androidenv.composeAndroidPackages {
1111
buildToolsVersions = [ "34.0.0" ];

‎nix/project.nix‎

Lines changed: 0 additions & 11 deletions
This file was deleted.

‎nix/shared-lib.nix‎

Lines changed: 0 additions & 72 deletions
This file was deleted.

‎npins/sources.json‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
{
22
"pins": {
3-
"haskell.nix": {
4-
"type": "Git",
5-
"repository": {
6-
"type": "GitHub",
7-
"owner": "input-output-hk",
8-
"repo": "haskell.nix"
9-
},
10-
"branch": "armv7a",
11-
"submodules": false,
12-
"revision": "d0c35e75cbbc6858770af42ac32b0b85495fbd71",
13-
"url": "https://github.com/input-output-hk/haskell.nix/archive/d0c35e75cbbc6858770af42ac32b0b85495fbd71.tar.gz",
14-
"hash": "sha256-rUIr6JNbCedt1g4gVYVvE9t0oFU6FUspCA0DS5cA8Bg="
15-
},
163
"mobile-core-tools": {
174
"type": "Git",
185
"repository": {

0 commit comments

Comments
 (0)