logos-messaging-nim/nix/default.nix
NagyZoltanPeter a7df0d9c56
chore: adjust artifact builds and uploads to contain logosdeliverynode app (#4059)
* feat(nix): add logosdeliverynode build target

Generalize the wakucanary-only binary path in nix/default.nix into an
app-target map so any app binary shares one build/install/rln-bundle
path, and expose a `logosdeliverynode` flake package (with gitVersion
for --version reporting).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci(github): build logosdeliverynode in release/pre-release/windows workflows

- release-assets.yml: build logosdeliverynode (POSTGRES=1) so it ships in
  the waku-<arch>-<os>.tar.gz release asset.
- pre-release.yml: add logosdeliverynode to the make targets and to the
  nwaku nightly/RC tarball.
- windows-build.yml: build logosdeliverynode.exe and assert it exists.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* ci(jenkins): build & push logosdeliverynode docker image to harbor

Jenkinsfile.release now builds a second image from the dedicated
logosdeliverynode Dockerfile stage and pushes it to
harbor.status.im/wakuorg/logosdelivery:<IMAGE_TAG> alongside the primary
image. Add a logosdeliverynode stage to the root Dockerfile so the image
entrypoint is /usr/bin/logosdeliverynode rather than the generic
/usr/bin/wakunode symlink. Bump the pipeline timeout to 40m to cover the
extra compile.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-28 11:20:05 +01:00

199 lines
6.9 KiB
Nix

{ pkgs
, src
, zerokitRln
, targets ? []
, gitVersion ? "n/a"
, enablePostgres ? true
, enableNimDebugDlOpen ? true
, chroniclesLogLevel ? null
}:
let
deps = import ./deps.nix { inherit pkgs; };
# Binary app targets built as executables; anything else builds the FFI library.
appSources = {
wakucanary = "apps/wakucanary/wakucanary.nim";
logosdeliverynode = "apps/logos_delivery_node/logosdeliverynode.nim";
};
appTarget =
let requested = builtins.filter (t: builtins.hasAttr t appSources) targets;
in if requested == [] then null else builtins.head requested;
buildApp = appTarget != null;
nimDefineArgs = pkgs.lib.concatStringsSep " \\\n " (
[ "--define:disable_libbacktrace"
"--define:git_version=${gitVersion}" ]
++ pkgs.lib.optional enablePostgres "--define:postgres"
++ pkgs.lib.optional enableNimDebugDlOpen "--define:nimDebugDlOpen"
++ pkgs.lib.optional (chroniclesLogLevel != null)
"--define:chronicles_log_level=${toString chroniclesLogLevel}"
);
# nat_traversal is excluded from the static pathArgs; it is handled
# separately in buildPhase (its bundled C libs must be compiled first).
otherDeps = builtins.removeAttrs deps [ "nat_traversal" ];
# Some packages (e.g. regex, unicodedb) put their .nim files under src/
# while others use the repo root. Pass both so the compiler finds either layout.
pathArgs =
builtins.concatStringsSep " "
(builtins.concatMap (p: [ "--path:${p}" "--path:${p}/src" "--path:${p}/sds" ])
(builtins.attrValues otherDeps));
libExt =
if pkgs.stdenv.hostPlatform.isWindows then "dll"
else if pkgs.stdenv.hostPlatform.isDarwin then "dylib"
else "so";
# Shared `nim c` invocation. Callers vary the output, the source file and a
# few mode-specific flags (e.g. --app:lib, --noMain, --header); everything
# else (paths, defines, threading, gc, nimcache, rln linkage) is constant.
# $NAT_TRAV and $NIMCACHE are shell variables defined in buildPhase.
nimCompile = { outFile, sourceFile, extraArgs ? [] }: ''
nim c \
--noNimblePath \
${pathArgs} \
--path:$NAT_TRAV \
--path:$NAT_TRAV/src \
--passL:"-L${zerokitRln}/lib -lrln${pkgs.lib.optionalString pkgs.stdenv.isLinux " -lstdc++"}" \
${nimDefineArgs} \
--threads:on \
--mm:refc \
--nimcache:$NIMCACHE \
--out:${outFile} \
${pkgs.lib.concatStringsSep " \\\n " extraArgs} \
${sourceFile}
'';
in
pkgs.stdenv.mkDerivation {
pname = if buildApp then appTarget else "liblogosdelivery";
version = "dev";
inherit src;
nativeBuildInputs = with pkgs; [
nim-2_2
git
gnumake
which
] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ pkgs.darwin.cctools ];
buildInputs = [ zerokitRln ]
++ pkgs.lib.optionals pkgs.stdenv.isLinux [ pkgs.stdenv.cc.cc.lib ];
buildPhase = ''
export HOME=$TMPDIR
export XDG_CACHE_HOME=$TMPDIR/.cache
export NIMBLE_DIR=$TMPDIR/.nimble
export NIMCACHE=$TMPDIR/nimcache
mkdir -p build $NIMCACHE
# nat_traversal bundles C sub-libraries that must be compiled before linking.
# Copy the fetchgit store path to a writable tmpdir, build, then pass to nim.
NAT_TRAV=$TMPDIR/nat_traversal
cp -r ${deps.nat_traversal} $NAT_TRAV
chmod -R +w $NAT_TRAV
make -C $NAT_TRAV/vendor/miniupnp/miniupnpc \
CFLAGS="-Os -fPIC" build/libminiupnpc.a
make -C $NAT_TRAV/vendor/libnatpmp-upstream \
CFLAGS="-Wall -Os -fPIC -DENABLE_STRNATPMPERR -DNATPMP_MAX_RETRIES=4" libnatpmp.a
${if buildApp then ''
echo "== Building ${appTarget} =="
${nimCompile {
outFile = "build/${appTarget}";
sourceFile = appSources.${appTarget};
extraArgs = [ "--path:." ];
}}
'' else ''
echo "== Building liblogosdelivery (dynamic) =="
${nimCompile {
outFile = "build/liblogosdelivery.${libExt}";
sourceFile = "library/liblogosdelivery.nim";
extraArgs = [
"--app:lib"
"--opt:size"
"--noMain"
"--header"
"--nimMainPrefix:liblogosdelivery"
];
}}
echo "== Building liblogosdelivery (static) =="
${nimCompile {
outFile = "build/liblogosdelivery.a";
sourceFile = "library/liblogosdelivery.nim";
extraArgs = [
"--app:staticlib"
"--opt:size"
"--noMain"
"--nimMainPrefix:liblogosdelivery"
];
}}
''}
'';
installPhase = if buildApp then ''
runHook preInstall
mkdir -p $out/bin $out/lib
cp build/${appTarget} $out/bin/
runHook postInstall
'' else ''
runHook preInstall
mkdir -p $out/lib $out/include
cp build/liblogosdelivery.${libExt} $out/lib/ 2>/dev/null || true
cp build/liblogosdelivery.a $out/lib/ 2>/dev/null || true
cp library/liblogosdelivery.h $out/include/ 2>/dev/null || true
cp library/liblogosdelivery_kernel.h $out/include/ 2>/dev/null || true
runHook postInstall
'';
# Bundle librln alongside the produced artifact so the output is self-contained.
# Use --add-rpath (not --set-rpath) so fixupPhase's stdenv RUNPATH injection
# for libstdc++ is preserved.
postInstall =
if buildApp then
pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
cp ${zerokitRln}/lib/librln.dylib $out/lib/
chmod +w $out/lib/librln.dylib $out/bin/${appTarget}
install_name_tool -id @rpath/librln.dylib $out/lib/librln.dylib
old=$(otool -L $out/bin/${appTarget} | awk 'NR>1{print $1}' | grep librln || true)
if [ -n "$old" ]; then
install_name_tool -change "$old" @rpath/librln.dylib $out/bin/${appTarget}
fi
install_name_tool -add_rpath @loader_path/../lib $out/bin/${appTarget}
''
+ pkgs.lib.optionalString pkgs.stdenv.isLinux ''
cp ${zerokitRln}/lib/librln.so $out/lib/
patchelf --add-rpath '$ORIGIN/../lib' $out/bin/${appTarget}
''
else
pkgs.lib.optionalString pkgs.stdenv.isDarwin ''
cp ${zerokitRln}/lib/librln.dylib $out/lib/
chmod +w $out/lib/librln.dylib $out/lib/liblogosdelivery.dylib
install_name_tool -id @rpath/liblogosdelivery.dylib $out/lib/liblogosdelivery.dylib
install_name_tool -id @rpath/librln.dylib $out/lib/librln.dylib
old=$(otool -L $out/lib/liblogosdelivery.dylib | awk 'NR>1{print $1}' | grep librln)
install_name_tool -change "$old" @rpath/librln.dylib $out/lib/liblogosdelivery.dylib
install_name_tool -add_rpath @loader_path $out/lib/liblogosdelivery.dylib
''
+ pkgs.lib.optionalString pkgs.stdenv.isLinux ''
cp ${zerokitRln}/lib/librln.so $out/lib/
patchelf --add-rpath '$ORIGIN' $out/lib/liblogosdelivery.so
'';
meta = with pkgs.lib; {
description =
if buildApp
then "logos-delivery ${appTarget} binary"
else "logos-delivery shared/static library";
homepage = "https://github.com/logos-messaging/logos-delivery";
license = licenses.mit;
platforms = platforms.unix;
};
}