#!/bin/bash
# Build the session daemon. Same object set as test_session_channel: this drives
# UdxTransport, which owns the HyperDht/DhtConnector/SwarmManager trio, plus
# protomux for the channel.
#
# ⚠ THIS IS A DEV BUILD (plain g++). Anything SHIPPED must be built with the Zig
# wrappers — a plain build links against a newer glibc and will not load on
# ashatron. See memory/hyperswarm-peer.md.
set -e
cd "$(dirname "$0")"
SRCDIR=../src
UDX_INC=../thirdparty/libudx/include
# compact_encoding.h forwards to libcompact; see ../test/build_tests.sh, which
# compiles those objects into the same cache.
COMPACT_INC="-I../thirdparty/libcompact/include -I../thirdparty/libutf/include"
CXXFLAGS="-std=c++17 -O2 -D_GNU_SOURCE -I. -I$SRCDIR -I$UDX_INC $COMPACT_INC"
LDFLAGS="-luv -lsodium -lpthread"
OBJ=/tmp/hsp-obj
if [ ! -d "$OBJ" ]; then
echo "ERROR: $OBJ missing. Run ../test/build_tests.sh first — it compiles the"
echo "shared transport objects this links against."
exit 1
fi
SHARED="noise_ik noise_handshake noise_stream dht_rpc holepuncher hyperdht \
dht_connector udx_transport swarm_manager protomux"
# ⛔ A HALF-UPDATED OBJECT CACHE LINKS FINE AND IS DEAD ON ARRIVAL.
#
# These objects are compiled by ../test/build_tests.sh, which runs under `set -e`
# -- so an error anywhere in it leaves the cache half-new, and nothing here would
# notice. That is not hypothetical: `fadee53` added two ints to HyperDht, and the
# binary committed in `ca1234b` linked a NEW hyperdht.o against an OLD
# udx_transport.o. _init_dht() then allocated the old sizeof while the
# constructor wrote the new layout, so every start overran the heap and aborted
# in the next malloc -- 5 runs of test_daemon_public_dht.py, 5 crashes, months
# after the last "green" measurement.
#
# A class layout is a contract between two translation units. If any header
# changed after an object was compiled, that object cannot be trusted, and the
# only safe answer is to say so rather than link it.
NEWEST=$(ls -t $SRCDIR/*.h $SRCDIR/*.cpp | head -1)
STALE=""
for o in $SHARED; do
if [ ! -f "$OBJ/$o.o" ] || [ "$NEWEST" -nt "$OBJ/$o.o" ]; then
STALE="$STALE $o.o"
fi
done
if [ -n "$STALE" ]; then
echo "ERROR: object cache is older than $NEWEST:$STALE"
echo " The layout of a shared class may have changed under them."
echo " Run ../test/build_tests.sh (it rebuilds every C++ object) first."
exit 1
fi
g++ $CXXFLAGS -c -o $OBJ/session_daemon.o session_daemon.cpp
g++ $CXXFLAGS -c -o $OBJ/session_main.o main.cpp
g++ -o session-daemon \
$OBJ/session_main.o $OBJ/session_daemon.o \
$(for o in $SHARED; do echo -n "$OBJ/$o.o "; done) \
$(ls $OBJ/udx_*.o | grep -v "/udx_transport.o$") \
$(ls $OBJ/compact_*.o) \
$LDFLAGS
echo " OK: session-daemon"