From 192b277229bc482f82e18dcc7c77065bcc4b60d9 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Sat, 18 Jul 2026 14:10:48 -0500 Subject: [PATCH] ci: link the Linux soul with -rdynamic so its http handler resolves MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run 3388's gate failed with every route returning "el-runtime: no http handler registered". The runtime resolves handle_request (and the tool handlers) by name via dlsym(RTLD_DEFAULT, ...). On glibc/Linux a symbol is only visible to dlsym if it is in the dynamic symbol table, so the stripped CI binary booted but served nothing. macOS exports these freely, which is why the local build passed and masked it. Add -rdynamic to the cc link (mirrors the Windows build's --export-all-symbols). strip -s keeps .dynsym, so the handler still resolves after stripping. This fixes both the gate AND the actual deployed soul — without it the Linux/GKE soul is a server that answers nothing. --- .gitea/workflows/ci.yaml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 5e13896..96a804d 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -94,16 +94,23 @@ jobs: # entirely: elb on Linux would OOM the runner (elc uses 24GB+ virtual memory # on a 16GB host) and we always restore from the repo's soul.c anyway. mkdir -p dist - cc -O2 -DHAVE_CURL \ + # -rdynamic: the el runtime resolves the HTTP request handler (and the + # tool handlers) by NAME via dlsym(RTLD_DEFAULT, "handle_request"). + # macOS exports these symbols freely, but glibc/Linux only makes symbols + # visible to dlsym if they are in the dynamic symbol table — so without + # -rdynamic the stripped Linux binary boots but returns "el-runtime: no + # http handler registered" for EVERY route (i.e. a soul that serves + # nothing). Same reason the Windows build links -Wl,--export-all-symbols. + cc -O2 -DHAVE_CURL -rdynamic \ -I$RUNTIME \ dist/soul.c \ $RUNTIME/el_runtime.c \ -lssl -lcrypto -lcurl -lpthread -lm \ -o dist/neuron - # Strip debug symbols and non-essential symbol table entries. - # -s removes the symbol table + relocation info (max size reduction). - # Keeps the binary functional; debuggability is preserved via source + CI logs. + # -s strips .symtab + debug for size. .dynsym (which -rdynamic populated + # with the dlsym-resolved handlers) is preserved, so the handler still + # resolves after stripping. strip -s dist/neuron ls -lh dist/neuron