Share the mobile export manifest with desktop build guards

This commit is contained in:
Moritz Angermann committed 2026-10-17 00:51:06 +09:00
1 parent 7d045945a3
commit 75cb52df6a
9 files changed
+131 -37

No files matched your search

+1 -28
View File
@@ -158,34 +158,7 @@
let drv = pkgs': drv' { extra-modules = []; inherit pkgs'; }; in
let inherit (import ./scripts/nix/mobile-library.nix { inherit pkgs; })
withComponentPhases withMobileLibrary; in
let chatExports = [
"chat_close_store"
"chat_decrypt_file"
"chat_decrypt_media"
"chat_encrypt_file"
"chat_encrypt_media"
"chat_migrate_init"
"chat_migrate_init_key"
"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_reopen_store"
"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"
]; in
let chatExports = import ./scripts/nix/chat-exports.nix; in
# This will package up all *.a in $out into a pkg.zip that can
# be downloaded from hydra.
let withHydraLibPkg = pkg: pkg.overrideAttrs (old: {
+1 -3
View File
@@ -21,9 +21,7 @@ root_dir="$(dirname "$(dirname "$(readlink "$0")")")"
cd $root_dir
BUILD_DIR=dist-newstyle/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
scripts/desktop/check-exports.sh
#rm -rf $BUILD_DIR
if [[ "$DATABASE_BACKEND" == "postgres" ]]; then
+1 -3
View File
@@ -20,9 +20,7 @@ GHC_LIBS_DIR=$(ghc --print-libdir)
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
scripts/desktop/check-exports.sh
rm -rf $BUILD_DIR
+1 -3
View File
@@ -17,9 +17,7 @@ fi
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
scripts/desktop/check-exports.sh
# 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
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail
# Run from the repository root, as the desktop build scripts do.
manifest=scripts/nix/chat-exports.txt
awk '
{ sub(/\r$/, "") }
$0 !~ /^[A-Za-z_][A-Za-z_0-9]*$/ || seen[$0]++ {
print "Invalid or duplicate export in " FILENAME ": " $0 > "/dev/stderr"
exit 1
}
END { if (NR == 0) exit 1 }
' "$manifest"
# Keep the historical exclusions shared by the desktop DLL/export guards.
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 symbol in "${exports[@]}"; do
count=$(awk -v symbol="$symbol" '
{ sub(/\r$/, ""); sub(/^[[:space:]]+/, ""); if ($0 == symbol) count++ }
END { print count + 0 }
' libsimplex.dll.def)
if [ "$count" -ne 1 ]; then
echo "Wrong exports in libsimplex.dll.def. Expected exactly one $symbol" >&2
exit 1
fi
count=$(awk -v symbol="$symbol" '
{ sub(/\r$/, ""); if ($0 == symbol) count++ }
END { print count + 0 }
' "$manifest")
if [ "$count" -ne 1 ]; then
echo "Wrong exports in $manifest. Expected exactly one $symbol" >&2
exit 1
fi
done
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
set -eu
repo=$(cd "$(dirname "$0")/../.." && pwd)
fixture=$(mktemp -d)
trap 'rm -rf "$fixture"' EXIT
mkdir -p "$fixture/bin"
cat > "$fixture/bin/ghc" <<'STUB'
#!/usr/bin/env bash
case "$1" in
--numeric-version) echo 9.6.3 ;;
--print-libdir) echo /unused-ghc-libdir ;;
*) exit 99 ;;
esac
STUB
cat > "$fixture/bin/cabal" <<'STUB'
#!/usr/bin/env bash
echo BUILD_REACHED
exit 77
STUB
chmod +x "$fixture/bin/ghc" "$fixture/bin/cabal"
for scenario in current missing duplicate similar-name crlf dll-missing dll-duplicate excluded; do
for platform in linux mac windows; do
work="$fixture/$scenario-$platform"
mkdir -p "$work/scripts/desktop" "$work/scripts/nix" "$work/src/Simplex/Chat"
cp "$repo/scripts/desktop/build-lib-$platform.sh" "$repo/scripts/desktop/check-exports.sh" "$work/scripts/desktop/"
cp "$repo/scripts/nix/chat-exports.txt" "$work/scripts/nix/"
cp "$repo/src/Simplex/Chat/Mobile.hs" "$work/src/Simplex/Chat/"
cp "$repo/libsimplex.dll.def" "$work/"
cp "$fixture/bin/cabal" "$work/scripts/desktop/prepare-openssl-windows.sh"
manifest="$work/scripts/nix/chat-exports.txt"
case "$scenario" in
missing) sed '/^chat_migrate_init$/d' "$manifest" > "$manifest.new"; mv "$manifest.new" "$manifest" ;;
duplicate) echo chat_migrate_init >> "$manifest" ;;
similar-name) sed 's/^chat_migrate_init$/chat_migrate_init_extra/' "$manifest" > "$manifest.new"; mv "$manifest.new" "$manifest" ;;
crlf) awk '{ printf "%s\r\n", $0 }' "$manifest" > "$manifest.new"; mv "$manifest.new" "$manifest" ;;
dll-missing) sed '/^ chat_migrate_init$/d' "$work/libsimplex.dll.def" > "$work/def.new"; mv "$work/def.new" "$work/libsimplex.dll.def" ;;
dll-duplicate) echo ' chat_migrate_init' >> "$work/libsimplex.dll.def" ;;
excluded)
for file in "$manifest" "$work/libsimplex.dll.def"; do
sed '/chat_migrate_init_key/d; /chat_reopen_store/d' "$file" > "$file.new"; mv "$file.new" "$file"
done ;;
esac
if output=$(cd "$work" && PATH="$fixture/bin:$PATH" bash "scripts/desktop/build-lib-$platform.sh" 2>&1); then
status=0
else
status=$?
fi
case "$scenario" in
current|crlf|excluded)
[ "$status" -eq 77 ] && [[ "$output" == *BUILD_REACHED* ]] || { echo "$platform/$scenario did not reach the build stub: $output" >&2; exit 1; } ;;
*)
[ "$status" -eq 1 ] && [[ "$output" != *BUILD_REACHED* ]] || { echo "$platform/$scenario did not stop at the export guard: $output" >&2; exit 1; } ;;
esac
echo "PASS $platform/$scenario"
done
done
+4
View File
@@ -76,6 +76,10 @@ that store is pruned. iOS ZIPs contain both the plain `libHSsimplex-chat-*.a` an
the rolled `libHSsimplex-chat-*-ghc*.a` used by `update-pbxproj.sh`. Android and
Windows clients link the threaded RTS into `libsimplex.so` or `libsimplex.dll`;
Android's separate `libsupport.so` resolves RTS symbols from the client library.
Android client export flags use the ordered `chat-exports.txt` manifest. The
desktop library scripts check that manifest and `libsimplex.dll.def` against the
Haskell exports before building; update the manifest when adding an export.
Run `scripts/desktop/test-exports.sh` to check all three guards without compiling.
ARM64 Android libraries retain the 16 KiB linker alignment. These steps run in
the derivation's build/install phases because v2 component overrides do not run
the older `postBuild` and `postInstall` hooks.
+3
View File
@@ -0,0 +1,3 @@
# Preserve the manifest order for the final mobile library linker flags.
builtins.filter (line: builtins.isString line && line != "")
(builtins.split "\r?\n" (builtins.readFile ./chat-exports.txt))
+26
View File
@@ -0,0 +1,26 @@
chat_close_store
chat_decrypt_file
chat_decrypt_media
chat_encrypt_file
chat_encrypt_media
chat_migrate_init
chat_migrate_init_key
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_reopen_store
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