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