This commit is contained in:
osmaczko 2026-02-27 18:41:34 +01:00
parent 85c1027645
commit 92dd2c8093
No known key found for this signature in database
GPG Key ID: 6A385380FD275B44
7 changed files with 74 additions and 76 deletions

View File

@ -28,22 +28,6 @@ ifneq (,$(findstring MINGW,$(detected_OS)))
detected_OS := Windows
endif
# liblibchat and librln are both Rust staticlibs that embed Rust std,
# resulting in duplicate symbol errors at link time.
# On Linux, --allow-multiple-definition suppresses the error.
# On Darwin, Apple ld does not support that flag; instead we partial-link
# liblibchat.a with ld -r, keeping only its public API symbols exported so
# that all Rust std internals (including _rust_eh_personality) are hidden
# and cannot conflict with the copy embedded in librln.a.
ifeq ($(detected_OS),Linux)
LDFLAGS := --passL:-Wl,--allow-multiple-definition
endif
ifeq ($(detected_OS),Darwin)
LIBCHAT_A := build/liblibchat_clean.a
else
LIBCHAT_A := vendor/libchat/target/release/liblibchat.a
endif
##########
## Main ##
@ -90,50 +74,30 @@ NIM_PARAMS := $(NIM_PARAMS) -d:git_version=\"$(GIT_VERSION)\"
##################
## Dependencies ##
##################
.PHONY: build-waku-librln
LIBRLN_VERSION := v0.7.0
RUST_BUNDLE_LIB := rust-bundle/target/release/lib_rust_bundle.a
ifeq ($(detected_OS),Windows)
LIBRLN_FILE := rln.lib
else
LIBRLN_FILE := librln_$(LIBRLN_VERSION).a
endif
build-waku-librln:
@echo "Start building waku librln"
# libchat and rln each embed Rust std when built as staticlibs; linking both
# causes duplicate-symbol errors. rust-bundle/ links them as rlibs so std
# is emitted once. [1]
# [1] https://doc.rust-lang.org/reference/linkage.html
.PHONY: build-rust-bundle
build-rust-bundle:
@echo "Building Rust bundle (libchat + rln)"
$(MAKE) -C vendor/nwaku librln
$(eval NIM_PARAMS += --passL:./vendor/nwaku/${LIBRLN_FILE} --passL:-lm)
@echo "Completed building librln"
cargo build --release --manifest-path rust-bundle/Cargo.toml
@echo "Bundle library: $(RUST_BUNDLE_LIB)"
build-waku-nat:
@echo "Start building waku nat-libs"
$(MAKE) -C vendor/nwaku nat-libs
@echo "Completed building nat-libs"
.PHONY: build-libchat
build-libchat:
@echo "Start building libchat"
cd vendor/libchat && cargo build --release
ifeq ($(detected_OS),Darwin)
@mkdir -p build
@nm --no-llvm-bc -gjU vendor/libchat/target/release/liblibchat.a 2>/dev/null | \
grep -E '^_(chat_|double_ratchet_|encrypt_result_|ffi_c_string_|installation_key_pair_|ratchet_state_|create_context|installation_name|destroy_context|destroy_string|create_intro_bundle|create_new_private_convo|send_content|handle_payload|destroy_intro_result|destroy_send_content_result|destroy_handle_payload_result|destroy_convo_result)' \
> build/libchat_exports.txt
@ld -r -exported_symbols_list build/libchat_exports.txt \
vendor/libchat/target/release/liblibchat.a \
-o build/liblibchat_clean.o
@libtool -static -o $(LIBCHAT_A) build/liblibchat_clean.o
endif
@echo "Completed building libchat"
.PHONY: tests
tests: | build-waku-librln build-waku-nat build-libchat logos_chat.nims
tests: | build-rust-bundle build-waku-nat logos_chat.nims
echo -e $(BUILD_MSG) "build/$@" && \
$(ENV_SCRIPT) nim tests $(NIM_PARAMS) \
--passL:$(LIBCHAT_A) \
$(LDFLAGS) \
--passL:$(RUST_BUNDLE_LIB) --passL:-lm \
logos_chat.nims
@ -142,11 +106,10 @@ tests: | build-waku-librln build-waku-nat build-libchat logos_chat.nims
##########
# Ensure there is a nimble task with a name that matches the target
tui bot_echo pingpong: | build-waku-librln build-waku-nat build-libchat logos_chat.nims
tui bot_echo pingpong: | build-rust-bundle build-waku-nat logos_chat.nims
echo -e $(BUILD_MSG) "build/$@" && \
$(ENV_SCRIPT) nim $@ $(NIM_PARAMS) \
--passL:$(LIBCHAT_A) \
$(LDFLAGS) \
--passL:$(RUST_BUNDLE_LIB) --passL:-lm \
--path:src logos_chat.nims
###########
@ -165,11 +128,10 @@ endif
LIBLOGOSCHAT := build/liblogoschat.$(LIBLOGOSCHAT_EXT)
.PHONY: liblogoschat
liblogoschat: | build-waku-librln build-waku-nat build-libchat logos_chat.nims
liblogoschat: | build-rust-bundle build-waku-nat logos_chat.nims
echo -e $(BUILD_MSG) "$(LIBLOGOSCHAT)" && \
$(ENV_SCRIPT) nim liblogoschat $(NIM_PARAMS) \
--passL:$(LIBCHAT_A) \
$(LDFLAGS) \
--passL:$(RUST_BUNDLE_LIB) --passL:-lm \
--path:src logos_chat.nims && \
echo -e "\n\x1B[92mLibrary built successfully:\x1B[39m" && \
echo " $(shell pwd)/$(LIBLOGOSCHAT)"

View File

@ -25,11 +25,11 @@
overlays = [ rust-overlay.overlays.default ];
};
libchatDrv = pkgs.callPackage ./nix/libchat.nix {};
librlnDrv = pkgs.callPackage ./nix/librln.nix {};
rustBundleDrv = pkgs.callPackage ./nix/bundle.nix { src = self; };
in {
packages.default = pkgs.callPackage ./nix/default.nix {
src = self;
inherit libchatDrv librlnDrv;
inherit rustBundleDrv;
};
devShells.default = pkgs.callPackage ./nix/shell.nix {
inherit libchatDrv;

34
nix/bundle.nix Normal file
View File

@ -0,0 +1,34 @@
{ lib, stdenv, rust-bin, makeRustPlatform, perl, pkg-config, cmake, src }:
let
rustToolchain = rust-bin.fromRustupToolchainFile (src + "/vendor/libchat/rust_toolchain.toml");
rPlatform = makeRustPlatform {
cargo = rustToolchain;
rustc = rustToolchain;
};
in rPlatform.buildRustPackage {
pname = "rust-bundle";
version = "0.1.0";
inherit src;
cargoRoot = "rust-bundle";
cargoLock = {
lockFile = src + "/rust-bundle/Cargo.lock";
# Add outputHashes here for any git/non-registry deps that appear in
# rust-bundle/Cargo.lock (run `nix build` once; it will report missing hashes).
outputHashes = {};
};
nativeBuildInputs = [ perl pkg-config cmake ];
doCheck = false;
buildAndTestSubdir = "rust-bundle";
installPhase = ''
runHook preInstall
mkdir -p $out/lib
cp rust-bundle/target/*/release/lib_rust_bundle.a $out/lib/ 2>/dev/null || true
cp rust-bundle/target/release/lib_rust_bundle.a $out/lib/ 2>/dev/null || true
runHook postInstall
'';
}

View File

@ -1,8 +1,7 @@
{ lib, stdenv, nim, which, pkg-config, writeScriptBin,
openssl, miniupnpc, libnatpmp,
src, # logos-chat source (self from flake, with submodules=1)
libchatDrv, # result of libchat.nix
librlnDrv }: # result of librln.nix
rustBundleDrv }: # result of bundle.nix
# NOTE: this build requires git submodules to be present in src.
# When fetching from GitHub use '?submodules=1#', e.g.:
@ -20,14 +19,12 @@ in stdenv.mkDerivation {
inherit src;
NIMFLAGS = lib.concatStringsSep " " [
"--passL:${libchatDrv}/lib/liblibchat.a"
"--passL:${librlnDrv}/lib/librln_v0.7.0.a"
"--passL:${rustBundleDrv}/lib/lib_rust_bundle.a"
"--passL:-lm"
"-d:miniupnpcUseSystemLibs"
"-d:libnatpmpUseSystemLibs"
"--passL:-lminiupnpc"
"--passL:-lnatpmp"
(lib.optionalString (!stdenv.isDarwin) "--passL:-Wl,--allow-multiple-definition")
"-d:git_version=${revision}"
];

View File

@ -1,4 +1,4 @@
{ lib, stdenv, rust-bin, makeRustPlatform, perl, pkg-config, cmake }:
{ rust-bin, makeRustPlatform, perl, pkg-config, cmake }:
let
rustToolchain = rust-bin.fromRustupToolchainFile ../vendor/libchat/rust_toolchain.toml;
@ -31,20 +31,6 @@ in rPlatform.buildRustPackage {
cp target/release/liblibchat.so $out/lib/ 2>/dev/null || true
cp target/release/liblibchat.dylib $out/lib/ 2>/dev/null || true
cp target/release/liblibchat.a $out/lib/ 2>/dev/null || true
${lib.optionalString stdenv.isDarwin ''
# Partial-link liblibchat.a, keeping only its public API symbols exported.
# This hides all Rust std symbols (including _rust_eh_personality) so they
# do not conflict with the copy embedded in librln.a at final link time.
if [ -f "$out/lib/liblibchat.a" ]; then
nm --no-llvm-bc -gjU $out/lib/liblibchat.a 2>/dev/null | \
grep -E '^_(chat_|double_ratchet_|encrypt_result_|ffi_c_string_|installation_key_pair_|ratchet_state_|create_context|installation_name|destroy_context|destroy_string|create_intro_bundle|create_new_private_convo|send_content|handle_payload|destroy_intro_result|destroy_send_content_result|destroy_handle_payload_result|destroy_convo_result)' \
> $TMPDIR/libchat_exports.txt
ld -r -exported_symbols_list $TMPDIR/libchat_exports.txt \
$out/lib/liblibchat.a \
-o $TMPDIR/liblibchat_clean.o
libtool -static -o $out/lib/liblibchat.a $TMPDIR/liblibchat_clean.o
fi
''}
runHook postInstall
'';
}

15
rust-bundle/Cargo.toml Normal file
View File

@ -0,0 +1,15 @@
[package]
name = "rust-bundle"
version = "0.1.0"
edition = "2021"
[lib]
name = "rust_bundle"
crate-type = ["staticlib"]
[profile.release]
panic = "abort"
[dependencies]
libchat = { path = "../vendor/libchat/conversations" }
rln = { path = "../vendor/nwaku/vendor/zerokit/rln", features = ["arkzkey"] }

4
rust-bundle/src/lib.rs Normal file
View File

@ -0,0 +1,4 @@
// Force both rlibs into this staticlib.
// Their #[no_mangle] pub extern "C" symbols are exported from lib_rust_bundle.a.
extern crate libchat;
extern crate rln;