From ce3c3873c5736eacc6c815c7c6c019caaf6887ab Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 18 Jun 2026 11:27:57 -0500 Subject: [PATCH] =?UTF-8?q?fix(ci):=20link=20soul.c=20only=20=E2=80=94=20d?= =?UTF-8?q?rop=20multi-module=20cc=20that=20triggers=20capability=20#error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit elb generates a dist/soul.c with all El modules inlined. Linking dist/soul.c alone is sufficient and is exactly what the local mac build does. Including other dist/*.c files causes two failures: 1. dist/chat.c has a capability-violation #error that fires when the file is compiled as a utility module (outside the cgi entrypoint). 2. --allow-multiple-definition masked other issues silently. Drop OTHER_C, drop --allow-multiple-definition, drop the now-unused elp-c-decls.h generation step. The cc command now matches the proven local build exactly. --- .gitea/workflows/ci.yaml | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 8bc8bc3..e3d97e4 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -91,44 +91,29 @@ jobs: echo "El SDK ready" /opt/el/dist/platform/elc --version || true - - name: Generate ELP master declarations header - run: | - { - printf '/* Auto-generated C forward declarations for ELP cross-module calls */\n' - printf '#pragma once\n' - printf '#include "el_runtime.h"\n' - printf '\n' - grep -h -E '^(el_val_t|void|int|char\*|const char\*)[[:space:]]+[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*\(' dist/*.c 2>/dev/null \ - | grep ';$' | sort -u - } > dist/elp-c-decls.h - echo "Generated elp-c-decls.h with $(grep -c ';' dist/elp-c-decls.h 2>/dev/null || echo 0) declarations" - - name: Build neuron soul binary run: | ELB=/opt/el/dist/bin/elb ELC=/opt/el/dist/platform/elc RUNTIME=/opt/el/runtime - # Compile all El modules to C. - # This step will fail at link on Linux: the El compiler inlines imported - # modules into each module's .c file, producing duplicate strong symbol - # definitions. GNU ld rejects these; macOS ld accepts them silently. - # We capture the link failure and re-link manually below. + # Compile all El modules to C via elb. + # elb fails at link on Linux (GNU ld rejects duplicate strong symbols that + # macOS ld accepts silently) — that's expected and captured with || true. + # The important output is dist/soul.c: the El compiler inlines all imported + # modules into the entry-point file, so soul.c is a self-contained + # translation unit. We never link the other dist/*.c files — they contain + # the same symbols inlined again, plus capability-violation #error guards + # that fire when compiled outside the cgi entrypoint. $ELB --elc=$ELC --runtime=$RUNTIME/el_runtime.c || true - # Re-link with soul.c listed first so its real main() (from the cgi block) - # wins over the stub main()s generated in every other module. - # --allow-multiple-definition tells GNU ld to pick the first definition - # for each duplicate symbol — safe here because all duplicates are identical - # (same El source compiled independently into multiple .c files). + # Link only soul.c + the runtime. No --allow-multiple-definition needed. mkdir -p dist - OTHER_C=$(ls dist/*.c | grep -v '/soul\.c$' | sort | tr '\n' ' ') cc -O2 -DHAVE_CURL \ -I$RUNTIME \ - dist/soul.c $OTHER_C \ + dist/soul.c \ $RUNTIME/el_runtime.c \ -lssl -lcrypto -lcurl -lpthread -lm \ - -Wl,--allow-multiple-definition \ -o dist/neuron ls -lh dist/neuron -- 2.52.0