diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 419fff6..8bc8bc3 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -109,21 +109,26 @@ jobs: ELC=/opt/el/dist/platform/elc RUNTIME=/opt/el/runtime - # Compile all El modules to C (may fail at link on Linux: the El compiler - # inlines imported modules into each module's .c file, producing duplicate - # symbol definitions that GNU ld rejects as errors. macOS ld accepts them - # silently. We ignore the link failure and re-link manually below.) + # 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. $ELB --elc=$ELC --runtime=$RUNTIME/el_runtime.c || true - # soul.c is a fully self-contained merged file — every function from every - # imported module is inlined into it. Link only soul.c against el_runtime.c; - # this avoids all duplicate-symbol conflicts from the individual module files. + # 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). mkdir -p dist + OTHER_C=$(ls dist/*.c | grep -v '/soul\.c$' | sort | tr '\n' ' ') cc -O2 -DHAVE_CURL \ -I$RUNTIME \ - dist/soul.c \ + dist/soul.c $OTHER_C \ $RUNTIME/el_runtime.c \ -lssl -lcrypto -lcurl -lpthread -lm \ + -Wl,--allow-multiple-definition \ -o dist/neuron ls -lh dist/neuron