nix: build armv7a from master with ghc 8.10.7 (#7763)

This commit is contained in:
sh
2026-10-19 09:07:52 +01:00
committed by GitHub
parent 924f2b9644
commit bdc4edc524
8 changed files with 974 additions and 119 deletions
+4 -13
View File
@@ -57,11 +57,7 @@ You will have to add `/opt/homebrew/opt/openssl@3.0/bin` to your PATH in order t
- `stable` - stable release of the apps, can be used for updates to the previous stable release (GHC 9.6.3).
- `stable-android` - used to build stable Android core library with Nix (GHC 8.10.7) - only for Android armv7a.
- `master` - branch for beta version releases (compatible with both GHC 9.6.3 and 8.10.7).
- `master-android` - used to build beta Android core library with Nix (GHC 8.10.7) - only for Android armv7a.
- `master` - branch for beta version releases (compatible with both GHC 9.6.3 and 8.10.7). Nix builds Android armv7a core library with GHC 8.10.7 and all other core libraries with GHC 9.6.3.
**In simplexmq repo**
@@ -71,18 +67,13 @@ You will have to add `/opt/homebrew/opt/openssl@3.0/bin` to your PATH in order t
1. Make PRs to `master` branch _only_ for both simplex-chat and simplexmq repos.
2. To build core libraries for Android, iOS and Windows:
- merge `master` branch to `master-android` branch.
- push to GitHub.
2. To build core libraries for Android, iOS and Windows, push `master` branch to GitHub.
3. All libraries should be built from `master` branch, Android armv7a - from `master-android` branch.
3. All libraries should be built from `master` branch.
4. To build Desktop and CLI apps, make tag in `master` branch, APK files should be attached to the release.
5. After the public release to App Store and Play Store, merge:
- `master` to `stable`
- `master` to `master-android` (and compile/update code)
- `master-android` to `stable-android`
5. After the public release to App Store and Play Store, merge `master` to `stable`.
6. Independently, `master` branch of simplexmq repo should be merged to `stable` branch on stable releases.
Generated
+916 -2
View File
File diff suppressed because it is too large Load Diff
+42 -92
View File
@@ -8,8 +8,17 @@
flake = false;
};
inputs.haskellNix.inputs.hackage.follows = "hackage";
# armv7a android is built with GHC 8.10.7; its toolchain is pinned by revision so updates of the inputs above don't move it.
inputs.haskellNix-ghc8107.url = "github:input-output-hk/haskell.nix/ab5efd87ce3fd8ade38a01d97693d29a4f1ae7e4";
inputs.nixpkgs-ghc8107.url = "github:angerman/nixpkgs/729469087592bdea58b360de59dadf6d58714c42";
inputs.hackage-ghc8107 = {
url = "github:input-output-hk/hackage.nix/24617c569995e38bf3b83b48eec6628a50fdb4fb";
flake = false;
};
inputs.haskellNix-ghc8107.inputs.nixpkgs.follows = "nixpkgs-ghc8107";
inputs.haskellNix-ghc8107.inputs.hackage.follows = "hackage-ghc8107";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, haskellNix, nixpkgs, flake-utils, mac2ios, ... }:
outputs = { self, haskellNix, haskellNix-ghc8107, nixpkgs, flake-utils, mac2ios, ... }:
let systems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; in
flake-utils.lib.eachSystem systems (system:
# this android26 overlay makes the pkgsCross.{aarch64-android,armv7a-android-prebuilt} to set stdVer to 26 (Android 8).
@@ -29,8 +38,9 @@
}; in
# `appendOverlays` with a singleton is identical to `extend`.
let pkgs = haskellNix.legacyPackages.${system}.appendOverlays [android26]; in
let drv' = { extra-modules, pkgs', ... }: pkgs'.haskell-nix.project {
compiler-nix-name = "ghc963";
let pkgs8107 = haskellNix-ghc8107.legacyPackages.${system}.appendOverlays [android26]; in
let drv' = { extra-modules, pkgs', compiler-nix-name ? "ghc963", ... }: pkgs'.haskell-nix.project {
inherit compiler-nix-name;
index-state = "2023-12-12T00:00:00Z";
# We need this, to specify we want the cabal project.
# If the stack.yaml was dropped, this would not be necessary.
@@ -126,16 +136,20 @@
"x86_64-linux" =
let
androidPkgs = pkgs.pkgsCross.aarch64-android;
android32Pkgs = pkgs.pkgsCross.armv7a-android-prebuilt;
android32Pkgs = pkgs8107.pkgsCross.armv7a-android-prebuilt;
# For some reason building libiconv with nixpgks android setup produces
# LANGINFO_CODESET to be found, which is not compatible with android sdk 23;
# so we'll patch up iconv to not include that.
androidIconv = (androidPkgs.libiconv.override { enableStatic = true; }).overrideAttrs (old: {
mkAndroidIconv = androidPkgs: (androidPkgs.libiconv.override { enableStatic = true; }).overrideAttrs (old: {
postConfigure = ''
echo "#undef HAVE_LANGINFO_CODESET" >> libcharset/config.h
echo "#undef HAVE_LANGINFO_CODESET" >> lib/config.h
'';
});
androidIconv = mkAndroidIconv androidPkgs;
# Only interpolated in a commented-out line of armv7a postInstall; it must come from the
# GHC 8.10.7 nixpkgs to keep that derivation identical to the former master-android build.
androidIconv8107 = mkAndroidIconv pkgs8107.pkgsCross.aarch64-android;
# Similarly to icovn, for reasons beyond my current knowledge, nixpkgs andorid
# toolchain makes configure believe we have MEMFD_CREATE, which we don't in
# sdk 23.
@@ -275,37 +289,22 @@
# STATIC aarch64-linux
"${pkgs.pkgsCross.aarch64-multiplatform-musl.hostPlatform.system}-static:exe:simplex-chat" = (drv pkgs.pkgsCross.aarch64-multiplatform-musl).simplex-chat.components.exes.simplex-chat;
"armv7a-android:lib:support" = (drv android32Pkgs).android-support.components.library.override (p: {
smallAddressSpace = true;
# we won't want -dyamic (see aarch64-android:lib:simplex-chat)
enableShared = false;
# we also do not want to have any dependencies listed (especially no rts!)
enableStatic = false;
# This used to work with 8.10.7...
# setupBuildFlags = p.component.setupBuildFlags ++ map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsupport.so" ];
# ... but now with 9.6+
# we have to do the -shared thing by hand.
postBuild = ''
armv7a-unknown-linux-androideabi-ghc -shared -o libsupport.so \
-optl-Wl,-u,setLineBuffering \
-optl-Wl,-u,pipe_std_to_socket \
dist/build/*.a
'';
"armv7a-android:lib:support" = (drv' { pkgs' = android32Pkgs; extra-modules = []; compiler-nix-name = "ghc8107"; }).android-support.components.library.override {
smallAddressSpace = true; enableShared = false;
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsupport.so" ];
postInstall = ''
mkdir -p $out/_pkg
cp libsupport.so $out/_pkg
${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsupport.so
(cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 $out/pkg-armv7a-android-libsupport.zip *)
${pkgs8107.patchelf}/bin/patchelf --remove-needed libunwind.so.1 $out/_pkg/libsupport.so
(cd $out/_pkg; ${pkgs8107.zip}/bin/zip -r -9 $out/pkg-armv7a-android-libsupport.zip *)
rm -fR $out/_pkg
mkdir -p $out/nix-support
echo "file binary-dist \"$(echo $out/*.zip)\"" \
> $out/nix-support/hydra-build-products
'';
});
};
# The android-support package is at
# https://github.com/simplex-chat/android-support
"aarch64-android:lib:support" = (drv androidPkgs).android-support.components.library.override (p: {
@@ -340,10 +339,10 @@
});
"armv7a-android:lib:simplex-chat" = (drv' {
pkgs' = android32Pkgs;
compiler-nix-name = "ghc8107";
extra-modules = [{
packages.text.flags.simdutf = false;
packages.direct-sqlcipher.flags.openssl = true;
packages.direct-sqlcipher.components.library.libs = pkgs.lib.mkForce [
packages.direct-sqlcipher.components.library.libs = pkgs8107.lib.mkForce [
(android32Pkgs.openssl.override { static = true; enableKTLS = false; })
];
packages.direct-sqlcipher.patches = [
@@ -351,70 +350,21 @@
];
packages.simplex-chat.flags.client_library = true;
packages.simplexmq.flags.client_library = true;
packages.simplexmq.components.library.libs = pkgs.lib.mkForce [
packages.simplexmq.components.library.libs = pkgs8107.lib.mkForce [
(android32Pkgs.openssl.override { static = true; enableKTLS = false; })
];
# 32 bit patches
packages.basement.patches = [
./scripts/nix/basement-pr-573.patch
];
packages.memory.patches = [
./scripts/nix/memory-pr-99.patch
];
}];
}).simplex-chat.components.library.override (p: {
smallAddressSpace = true;
# we want -shared, but not -dyanmic, hence `enableShared = false`.
enableShared = false;
# we _do_ want rts, and other libs. Hence `enableStatic = true`.
enableStatic = true;
}).simplex-chat.components.library.override {
smallAddressSpace = true; enableShared = false;
# for android we build a shared library, passing these arguments is a bit tricky, as
# we want only the threaded rts (HSrts_thr) and ffi to be linked, but not fed into iserv for
# template haskell cross compilation. Thus we just pass them as linker options (-optl).
setupBuildFlags = p.component.setupBuildFlags
# flags to tell GHC we want to produce a -shared object, and we want to also link
# - the ffi library (ffi)
++ map (x: "--ghc-option=${x}") [
"-shared" "-o" "libsimplex.so"
"-threaded"
# "-debug"
"-optl-lffi"
"-j1"
]
# This is fairly idiotic. LLD will strip out foreign exported
# symbols (a GHC bug? Codegen bug?). So we need to pass `-u <sym>`
# to ensure they stay in the produced library. Having them
# _undefined_ and _lazy_ (lld will tell with -y <sym> that the
# symbol is lazy), makes them _defined_. m(
++ map (sym: "--ghc-option=-optl-Wl,-u,${sym}") [
"chat_close_store"
"chat_decrypt_file"
"chat_decrypt_media"
"chat_encrypt_file"
"chat_encrypt_media"
"chat_migrate_init"
"chat_migrate_init_queue"
"chat_parse_markdown"
"chat_parse_server"
"chat_parse_uri"
"chat_password_hash"
"chat_read_file"
"chat_recv_msg"
"chat_recv_msg_wait"
"chat_send_cmd"
"chat_send_cmd_retry"
"chat_send_remote_cmd"
"chat_send_remote_cmd_retry"
"chat_valid_name"
"chat_parse_badge_code"
"chat_json_length"
"chat_badge_keygen"
"chat_badge_issue"
"chat_write_file"
];
# 32-bit ARM only: processAgentMessageConn is too large for ARM's PC-relative constant-pool
# range at -O2; -O1 is appended after the cabal -O2 here, so it wins (aarch64 stays -O2).
setupBuildFlags = map (x: "--ghc-option=${x}") [ "-shared" "-o" "libsimplex.so" "-optl-lHSrts_thr" "-optl-lffi" "-j1" "-O1"];
postInstall = ''
set -x
${pkgs.tree}/bin/tree $out
${pkgs8107.tree}/bin/tree $out
mkdir -p $out/_pkg
# copy over includes, we might want those, but maybe not.
# cp -r $out/lib/*/*/include $out/_pkg/
@@ -425,7 +375,7 @@
# find ./dist -name "libHS*-ghc*.a" -exec cp {} $out/_pkg \;
# find ${android32FFI}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${android32Pkgs.gmp6.override { withStatic = true; }}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidIconv}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${androidIconv8107}/lib -name "*.a" -exec cp {} $out/_pkg \;
# find ${android32Pkgs.stdenv.cc.libc}/lib -name "*.a" -exec cp {} $out/_pkg \;
echo ${android32Pkgs.openssl.override { enableKTLS = false; }}
find ${(android32Pkgs.openssl.override { enableKTLS = false; }).out}/lib -name "*.so" -exec cp {} $out/_pkg \;
@@ -433,22 +383,22 @@
# remove the .1 and other version suffixes from .so's. Androids linker
# doesn't play nice with them.
for lib in $out/_pkg/*.so; do
for dep in $(${pkgs.patchelf}/bin/patchelf --print-needed "$lib"); do
for dep in $(${pkgs8107.patchelf}/bin/patchelf --print-needed "$lib"); do
if [[ "''${dep##*.so}" ]]; then
echo "$lib : $dep -> ''${dep%%.so*}.so"
chmod +w "$lib"
${pkgs.patchelf}/bin/patchelf --replace-needed "$dep" "''${dep%%.so*}.so" "$lib"
${pkgs8107.patchelf}/bin/patchelf --replace-needed "$dep" "''${dep%%.so*}.so" "$lib"
fi
done
done
for lib in $out/_pkg/*.so; do
chmod +w "$lib"
${pkgs.patchelf}/bin/patchelf --remove-needed libunwind.so "$lib"
[[ "$lib" != *libsimplex.so ]] && ${pkgs.patchelf}/bin/patchelf --set-soname "$(basename -a $lib)" "$lib"
${pkgs8107.patchelf}/bin/patchelf --remove-needed libunwind.so "$lib"
[[ "$lib" != *libsimplex.so ]] && ${pkgs8107.patchelf}/bin/patchelf --set-soname "$(basename -a $lib)" "$lib"
done
${pkgs.tree}/bin/tree $out/_pkg
${pkgs8107.tree}/bin/tree $out/_pkg
# Strip from debug symbols
find "$out/_pkg" -type f -name "*.so" -exec ${android32Pkgs.stdenv.cc.targetPrefix}strip --strip-unneeded {} +
@@ -458,13 +408,13 @@
find "$out/_pkg" -type d -exec chmod 755 {} +
find "$out/_pkg" -exec touch -h -d '@1764547200' {} +
(cd $out/_pkg; ${pkgs.zip}/bin/zip -r -9 -X $out/pkg-armv7a-android-libsimplex.zip *)
(cd $out/_pkg; ${pkgs8107.zip}/bin/zip -r -9 -X $out/pkg-armv7a-android-libsimplex.zip *)
rm -fR $out/_pkg
mkdir -p $out/nix-support
echo "file binary-dist \"$(echo $out/*.zip)\"" \
> $out/nix-support/hydra-build-products
'';
});
};
"aarch64-android:lib:simplex-chat" = (drv' {
pkgs' = androidPkgs;
extra-modules = [{
+3 -8
View File
@@ -105,14 +105,9 @@ build() {
sed -i.bak "s/android.version_code=.*/android.version_code=${vercode}/" "$folder/apps/multiplatform/gradle.properties"
for arch in $arches; do
if [ "$arch" = "armv7a" ]; then
android_simplex_lib="${folder}#hydraJobs.${arch}-android:lib:simplex-chat.x86_64-linux"
android_support_lib="${folder}#hydraJobs.${arch}-android:lib:support.x86_64-linux"
else
android_simplex_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:simplex-chat"
android_support_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:support"
fi
android_simplex_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:simplex-chat"
android_support_lib="${folder}#hydraJobs.x86_64-linux.${arch}-android:lib:support"
android_simplex_lib_output="${PWD}/result/pkg-${arch}-android-libsimplex.zip"
android_support_lib_output="${PWD}/result/pkg-${arch}-android-libsupport.zip"
+1 -1
View File
@@ -24,7 +24,7 @@ BUILD_DIR=$DIST_DIR/build/$ARCH-$OS/ghc-${GHC_VERSION}/simplex-chat-*
exports=( $(sed 's/foreign export ccall "chat_migrate_init_key"//' src/Simplex/Chat/Mobile.hs | sed 's/foreign export ccall "chat_reopen_store"//' |grep "foreign export ccall" | cut -d '"' -f2) )
for elem in "${exports[@]}"; do count=$(grep -R "$elem$" libsimplex.dll.def | wc -l); if [ $count -ne 1 ]; then echo Wrong exports in libsimplex.dll.def. Add \"$elem\" to that file; exit 1; fi ; done
for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 2 ]; then echo Wrong exports in flake.nix. Add \"$elem\" in two places of the file; exit 1; fi ; done
for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 1 ]; then echo Wrong exports in flake.nix. Add \"$elem\" to aarch64-android:lib:simplex-chat; exit 1; fi ; done
#rm -rf $BUILD_DIR
if [[ "$DATABASE_BACKEND" == "postgres" ]]; then
+1 -1
View File
@@ -22,7 +22,7 @@ BUILD_DIR=dist-newstyle/build/$ARCH-*/ghc-*/simplex-chat-*
exports=( $(sed 's/foreign export ccall "chat_migrate_init_key"//' src/Simplex/Chat/Mobile.hs | sed 's/foreign export ccall "chat_reopen_store"//' |grep "foreign export ccall" | cut -d '"' -f2) )
for elem in "${exports[@]}"; do count=$(grep -R "$elem$" libsimplex.dll.def | wc -l); if [ $count -ne 1 ]; then echo Wrong exports in libsimplex.dll.def. Add \"$elem\" to that file; exit 1; fi ; done
for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 2 ]; then echo Wrong exports in flake.nix. Add \"$elem\" in two places of the file; exit 1; fi ; done
for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 1 ]; then echo Wrong exports in flake.nix. Add \"$elem\" to aarch64-android:lib:simplex-chat; exit 1; fi ; done
rm -rf $BUILD_DIR
+1 -1
View File
@@ -19,7 +19,7 @@ BUILD_DIR=dist-newstyle/build/$ARCH-$OS/ghc-*/simplex-chat-*
exports=( $(sed 's/foreign export ccall "chat_migrate_init_key"//' src/Simplex/Chat/Mobile.hs | sed 's/foreign export ccall "chat_reopen_store"//' |grep "foreign export ccall" | cut -d '"' -f2) )
for elem in "${exports[@]}"; do count=$(grep -R "$elem$" libsimplex.dll.def | wc -l); if [ $count -ne 1 ]; then echo Wrong exports in libsimplex.dll.def. Add \"$elem\" to that file; exit 1; fi ; done
for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 2 ]; then echo Wrong exports in flake.nix. Add \"$elem\" in two places of the file; exit 1; fi ; done
for elem in "${exports[@]}"; do count=$(grep -R "\"$elem\"" flake.nix | wc -l); if [ $count -ne 1 ]; then echo Wrong exports in flake.nix. Add \"$elem\" to aarch64-android:lib:simplex-chat; exit 1; fi ; done
# IMPORTANT: in order to get a working build you should use x86_64 MinGW with make, cmake, gcc.
# 100% working MinGW is https://github.com/brechtsanders/winlibs_mingw/releases/download/13.1.0-16.0.5-11.0.0-ucrt-r5/winlibs-x86_64-posix-seh-gcc-13.1.0-mingw-w64ucrt-11.0.0-r5.zip
@@ -246,7 +246,12 @@ Continue?'
for arch in $ARCHES; do
case "$arch" in
armv7a)
build_tag="${tag}-armv7a"
# Releases made before the master-android branch was merged have armv7a in a separate tag.
if git -C "$build_directory" rev-parse -q --verify "refs/tags/${tag}-armv7a" > /dev/null; then
build_tag="${tag}-armv7a"
else
build_tag="${tag}"
fi
;;
aarch64)
build_tag="${tag}"