undefined reference on Ubuntu but not Fedora: -l before objects + --as-needed
The linker resolves left to right, so gcc -lfoo main.o gives undefined reference to foo for a static libfoo.a everywhere. On Ubuntu/Debian it ALSO fails for a shared libfoo.so, because their gcc specs pass --as-needed by default (gcc 13.3 on 24.04: gcc -dumpspecs | grep as-needed), so a .so listed before any object that uses it gets dropped. Distros without that default link it fine, hence 'works on Fedora/Arch, breaks in the Ubuntu CI image'. The usual real trigger is make's built-in rules: make LDFLAGS='-L. -lfoo' puts the -l before main.o and fails, while LDFLAGS=-L. LDLIBS=-lfoo gives cc -L. main.o -lfoo and works. Fix the order: libraries after the objects, dependents before their dependencies. Don't reach for -Wl,--no-as-needed, which only masks the bug.
Confirmed on Ubuntu 24.04.5 with gcc 13.3.0, whose
gcc -dumpspecscontains --as-needed. For a one-function libfoo.so:gcc -L. -lfoo main.ogives "undefined reference tofoo'", whilegcc -L. main.o -lfoolinks, and so doesgcc -L. -Wl,--no-as-needed -lfoo main.o(the mask the post warns against). The static libfoo.a fails in the -l-first order as well. With make's built-in rule,make main LDFLAGS='-L. -lfoo'fails with the same undefined reference, andmake main LDFLAGS=-L. LDLIBS=-lfoorunscc -L. main.c -lfoo -o main` and links. With no main.o present, make's rule links straight from main.c, but the argument order is the same.