At one point in time in my life the order of libraries that one passed to the gcc mattered. You pass gcc the list of libraries from the most to least dependant. For example consider the following source code:
testlib.c
include <math.h>
double proxy_sqrt(double x)
{
return sqrt(x);
}
testlib.h
double proxy_sqrt(double);
use-testlib.c
#include "testlib.h"
int main(int argc, char* argv[])
{
proxy_sqrt(36);
return 0;
}
Then to compile and link:
gcc -c -o testlib.o testlib.c
ar rvs testlib.a testlib.o
gcc -o use-testlib use-testlib.c testlib.a -lm
Note that the last step the most to least dependent ordering is used.
But this (invalid?) order works on SLES12
gcc -o use-testlib use-testlib.c -lm testlib.a
but fails on Ubuntu 14.04....
gcc -o use-testlib use-testlib.c -lm testlib.a
testlib.a(testlib.o): In function `proxy_sqrt':
testlib.c:(.text+0x1b): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Anyone know why?
Verbose output from the 2 compilers is shown at the links below:
sles12
ubuntu14.04
Look at the differences in the linker (collect2
) commands and the --as-needed
and --no-as-needed
options:
SLES 12
/usr/lib64/gcc/x86_64-suse-linux/4.8/collect2 --build-id --eh-frame-hdr \
-m elf_x86_64 -dynamic-linker … /tmp/ccgoQd94.o -lm testlib.a -lgcc \
--as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s \
--no-as-needed /usr/lib64/gcc/x86_64-suse-linux/4.8/crtend.o \
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../lib64/crtn.o
Ubuntu 14
/usr/lib/gcc/x86_64-linux-gnu/4.8/collect2 --sysroot=/ --build-id --eh-frame-hdr \
-m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker … \
/tmp/cciheQTH.o -lm testlib.a -lgcc --as-needed -lgcc_s \
--no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed \
/usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o \
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o
The use of --as-needed
at the start of the options for Ubuntu 14 changes the behaviour of things compared to SLES 12. Reputedly, it is to make things easier. I remain to be convinced — it just seems to give new ways for code to break when moved.