signal-desktop-from-src: closer to working

This commit is contained in:
Colin 2023-11-04 14:52:09 +00:00
parent 5adf6c0194
commit c30e131aa7
3 changed files with 189 additions and 7 deletions

View File

@ -0,0 +1,45 @@
--- a/binding.gyp
+++ b/binding.gyp
@@ -7,7 +7,16 @@
'targets': [
{
'target_name': 'better_sqlite3',
- 'dependencies': ['deps/sqlite3.gyp:sqlite3'],
+ 'include_dirs': [
+ '@sqlcipher@/include/sqlcipher',
+ '@signal_fts5_extension@/include',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '-lsqlcipher',
+ '@signal_fts5_extension@/lib/libsignal_tokenizer.a',
+ ]
+ },
'sources': ['src/better_sqlite3.cpp'],
'cflags_cc': ['-std=c++17'],
'xcode_settings': {
@@ -24,14 +33,22 @@
['OS=="linux"', {
'ldflags': [
'-Wl,-Bsymbolic',
- '-Wl,--exclude-libs,ALL',
],
}],
],
},
{
'target_name': 'test_extension',
- 'dependencies': ['deps/sqlite3.gyp:sqlite3'],
+ 'include_dirs': [
+ '@sqlcipher@/include/sqlcipher',
+ '@signal_fts5_extension@/include',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '-lsqlcipher',
+ '@signal_fts5_extension@/lib/libsignal_tokenizer.a',
+ ]
+ },
'conditions': [['sqlite3 == ""', { 'sources': ['deps/test_extension.c'] }]],
},
],

View File

@ -84,6 +84,78 @@
# at exports.emitMessage (node:internal/per_context/messageport:23:28)
# ```
#
# runtime hang:
# - during boot, this message looks sus:
# - `{"level":50,"time":"2023-11-02T15:45:33.925Z","msg":"Preload error in [REDACTED]/preload.bundle.js: Cannot read properties of undefined (reading 'PureComponent')"}`
# - worth trying to build better-sqlite.
# - `make: *** No rule to make target '../deps/sqlcipher.tar.gz', needed by 'b857c92884e9598d609f6be182a2595df7a8e00f.intermediate'. Stop.`
# - alpine patches it to use system sqlcipher.
# - nixpkgs has sqlcipher: should try the same thing
#
# - after shipping sqlcipher:
# ```
# In file included from ../src/better_sqlite3.cpp:4:
# ./src/better_sqlite3.lzz:14:10: fatal error: signal-tokenizer.h: No such file or directory
# - signal-tokenizer: <https://github.com/signalapp/Signal-FTS5-Extension>
# - allows full-text-search for sqlite CJK languages
# - i should just disable it, if possible?
# - somehow signal-desktop doesn't contain any tokenizer files, even though it's a rust binary?
# - text references to signal_tokenizer, though
# - oh: static linking (against (SHARED_INTERMEDIATE_DIR)/sqlite3/signal-tokenizer/>(rust_arch)-unknown-linux-gnu/libsignal_tokenizer.a)
# - signal's better-sqlite3 hardcodes a #include for signal-tokenizer.h; it's not toggleable
# - simply deleting source references to the tokenizer causes a runtime error:
# ```
# Unhandled Promise Rejection: Error: Error: /nix/store/hf4crvgi4rmm3cg0l1pc9pbvzq0y6kh0-signal-desktop-from-src-6.36.0/lib/Signal/resources/app.asar.unpacked/node_modules/@signalapp/better-sqlite3/build/Release/better_sqlite3.node: undefined symbol: _ZN2v812api_internal18GlobalizeReferenceEPNS_8internal7IsolateEPm
# at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:1869)
# at Module._extensions..node (node:internal/modules/cjs/loader:1354:18)
# at Object.func [as .node] (node:electron/js2c/asar_bundle:2:2096)
# at Module.load (node:internal/modules/cjs/loader:1124:32)
# at Module._load (node:internal/modules/cjs/loader:965:12)
# at f._load (node:electron/js2c/asar_bundle:2:13377)
# at Module.require (node:internal/modules/cjs/loader:1148:19)
# at require (node:internal/modules/cjs/helpers:110:18)
# at bindings (/nix/store/hf4crvgi4rmm3cg0l1pc9pbvzq0y6kh0-signal-desktop-from-src-6.36.0/lib/Signal/resources/app.asar/node_modules/bindings/bindings.js:112:48)
# at new Database (/nix/store/hf4crvgi4rmm3cg0l1pc9pbvzq0y6kh0-signal-desktop-from-src-6.36.0/lib/Signal/resources/app.asar/node_modules/@signalapp/better-sqlite3/lib/database.js:48:64)
# at Worker.<anonymous> (/nix/store/hf4crvgi4rmm3cg0l1pc9pbvzq0y6kh0-signal-desktop-from-src-6.36.0/lib/Signal/resources/app.asar/ts/sql/main.js:62:26)
# at Worker.emit (node:events:513:28)
# at MessagePort.<anonymous> (node:internal/worker:234:53)
# at [nodejs.internal.kHybridDispatch] (node:internal/event_target:735:20)
# at exports.emitMessage (node:internal/per_context/messageport:23:28)
# ```
# - possibly that's a broken reference to v8::Isolate? but that's used by ordinary better-sqlite
# - `v8::api_internal::GlobalizeReference(v8::internal::Isolate*, unsigned long*)` - as per c++filt
# - seems a problem whenever multiple nodejs versions are mixed?
# - <https://github.com/refi64/zypak/issues/20>
# - error message is for better-sqlite, but maybe it's actually because of the rtc stuff (which used a different nodejs)?
# - happens for electron 25, 26 and 27
# - pre-packaged signal-desktop has better-sqlite which doesn't link against anything special like v8, and includes the symbol:
# - `_ZN2v812api_internal18GlobalizeReferenceEPNS_8internal7IsolateEm`
# - notice: IsolateEm instead of IsolatedEPm
# - `v8::api_internal::GlobalizeReference(v8::internal::Isolate*, unsigned long)`
# - i.e. that `unsized long` isn't a pointer!
# - GlobalizeReference doesn't occur in better-sqlite source
# - v8 is a part of nodejs, as is GlobalizeReference.
# - could this be related to that "unable to figure out ABI" thing?
# - somehow related to node-gyp:
# .node-gyp/18.18.2/include/node/v8-persistent-handle.h
# 36:V8_EXPORT internal::Address* GlobalizeReference(internal::Isolate* isolate,
# 37- internal::Address* handle);
# nixpkgs' nodejs is indeed 18.18.2. upstream nodejs is 21.1.0.
# this header matches what nodejs 18.18.2 provides!
# - maybe related to electron.headers? probably not though. nix path-info on electron doesn't show any trace of node
# - in fact, nix path-info on signal-desktop-from-src refers to nodejs, which contains in `bin/nodejs` the use of this symbol:
# - `_ZN2v812api_internal18GlobalizeReferenceEPNS_8internal7IsolateEPm`
# - so.... THERE'S NO REASON FOR ME TO SEE THIS ERROR!!
# - in the build dir, this file DOES contain GlobalizeReference, of the right signature: `./source/release/linux-unpacked/signal-desktop`
# - same file as in the pre-built signal-desktop
# - this is the one which segfaults on launch though.
# - because it needs suid bit. invoke with `--no-sandbox` instead!
# - but then we get the same identical undefined symbol error as above!
# - do i have it inverted: nodejs runs signal-desktop, not that electron runs signal-desktop?
# - note in the build dir, a PREBUILT: source/release/linux-unpacked/resources/app.asar.unpacked/node_modules/@signalapp/libsignal-client/prebuilds/linux-x64/node.napi.node
# - is this the Native API for node?? wtf is signal doing?
# - indeed they ship binaries on npm: <https://www.npmjs.com/package/@signalapp/libsignal-client/v/0.33.0?activeTab=code>
# - i think i need to just blindly copy the Alpine build routine, and then it'll work. they're clearly doing all their involved stuff for SOME reason
#
#
# the dependencies which alpine builds live over here:
@ -130,8 +202,10 @@
, python3
, signal-desktop
, sqlite
, sqlcipher
, srcOnly
, stdenv
, substituteAll
, yarn
}:
let
@ -144,6 +218,13 @@ let
# 26 simply segfaults.
# electron = electron_26;
electron = electron_25;
nodeSources = srcOnly nodejs;
bettersqlitePatch = substituteAll {
src = ./bettersqlite-use-system-sqlcipher.patch;
inherit sqlcipher;
signal_fts5_extension = signal-fts5-extension;
};
signal-fts5-extension = callPackage ./fts5-extension { };
in
stdenv.mkDerivation rec {
pname = "signal-desktop-from-src";
@ -164,6 +245,9 @@ stdenv.mkDerivation rec {
];
buildInputs = [
electron
# so that bettersqlite may link against sqlcipher (see patch)
# but i don't know if it actually needs to. just copied this from alpine.
sqlcipher
];
# to update:
@ -231,12 +315,27 @@ stdenv.mkDerivation rec {
ln -sfv "${nodejs}/include" "$HOME/.node-gyp/${nodejs.version}"
export npm_config_nodedir=${nodejs}
# build the sqlite bindings ELF
pushd node_modules/@signalapp/better-sqlite3
mkdir tokenizer
cp ${signal-fts5-extension}/lib/libsignal_tokenizer.a tokenizer/
patch -p1 < ${bettersqlitePatch}
# mkdir -p "$HOME/.node-gyp/${nodejs.version}"
# echo 9 > "$HOME/.node-gyp/${nodejs.version}/installVersion"
# ln -sfv "${nodejs}/include" "$HOME/.node-gyp/${nodejs.version}"
# export npm_config_nodedir=${nodejs}
npm run build-release --offline --nodedir="${nodeSources}"
popd
# provide the ringrtc (webrtc) dependency. TODO: build this from source
cp -R ${signal-desktop}/lib/Signal/resources/app.asar.unpacked/node_modules/@signalapp/ringrtc/build \
node_modules/@signalapp/ringrtc/
# provide the sqlite bindings ELF. TODO: build this from source
cp -R ${signal-desktop}/lib/Signal/resources/app.asar.unpacked/node_modules/@signalapp/better-sqlite3/build \
node_modules/@signalapp/better-sqlite3/
# cp -R ${signal-desktop}/lib/Signal/resources/app.asar.unpacked/node_modules/@signalapp/better-sqlite3/build \
# node_modules/@signalapp/better-sqlite3/
# yarn generate:
yarn build-module-protobuf --offline --frozen-lockfile --ignore-scripts --ignore-engines
@ -258,7 +357,7 @@ stdenv.mkDerivation rec {
# preInstall = ''
# # Build the sqlite3 package.
# npm_config_nodedir="${srcOnly nodejs}" npm_config_node_gyp="${buildPackages.nodejs}/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" npm rebuild --verbose --sqlite=${sqlite.dev} @signalapp/better-sqlite3
# npm_config_nodedir="${nodeSources}" npm_config_node_gyp="${buildPackages.nodejs}/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" npm rebuild --verbose --sqlite=${sqlite.dev} @signalapp/better-sqlite3
# '';
installPhase = ''
@ -277,10 +376,14 @@ stdenv.mkDerivation rec {
runHook postInstall
'';
preFixup = ''
# the better-sqlite prebuilt by Signal has an implicit dep on libstdc++.so
patchelf --add-needed ${lib.getLib stdenv.cc.cc}/lib/libstdc++.so "$out/lib/Signal/resources/app.asar.unpacked/node_modules/@signalapp/better-sqlite3/build/Release/better_sqlite3.node"
'';
# preFixup = ''
# # the better-sqlite prebuilt by Signal has an implicit dep on libstdc++.so
# patchelf --add-needed ${lib.getLib stdenv.cc.cc}/lib/libstdc++.so "$out/lib/Signal/resources/app.asar.unpacked/node_modules/@signalapp/better-sqlite3/build/Release/better_sqlite3.node"
# '';
passthru = {
inherit bettersqlitePatch signal-fts5-extension;
};
meta = {
description = "Private, simple, and secure messenger";

View File

@ -0,0 +1,34 @@
{ rustPlatform
, fetchFromGitHub
, rust-cbindgen
}:
rustPlatform.buildRustPackage rec {
pname = "signal-fts5-extension";
# via Alpine package:
# > follow @signalapp/better-sqlite3 (on version in package.json) -> deps/download.js -> TOKENIZER_VERSION
# > last bsqlite version: 8.5.2
version = "0.2.1";
src = fetchFromGitHub {
owner = "signalapp";
repo = "Signal-FTS5-Extension";
rev = "v${version}";
hash = "sha256-MzgdRuRsfL3yhlVU0RAAUtAaOukMpqSSa42nRYhpmh0=";
};
cargoHash = "sha256-ZTrqkMBqSsGs80oWIrD6hBKMnjo2Da4d5FumnUNdves=";
nativeBuildInputs = [
rust-cbindgen
];
postBuild = ''
cbindgen --profile release . -o $out/include/signal-tokenizer.h
'';
# stokenizerver = "0.2.1";
# stokenizer = fetchurl {
# url = "https://github.com/signalapp/Signal-FTS5-Extension/archive/refs/tags/v${stokenizerver}/stokenizer-${stokenizerver}.tar.gz";
# hash = "sha256-Kl2gZAtxIw4FZWrga4V6c9TMGCirQ9CEzhRz2laSAE0=";
# };
}