Does the order in which libraries appear on the gcc command line matter?

前端 未结 1 1257
失恋的感觉
失恋的感觉 2021-01-25 16:54

I always thought that libraries had to be listed after any object files that depended on them, but given this simple program:

#include 
#         


        
相关标签:
1条回答
  • 2021-01-25 17:32

    I confirm the unexpected link-order behaviour that you observe with gcc 5.1 and also that I have the traditional behaviour with gcc 4.9.2. I would infer that this novelty comes in with gcc 5.x, and that your toolchain is gcc 5.x. Possibly it is a distro-specific anomaly of the toolchain build. My toolchain is as per ubuntu 14.04.

    The novel behaviour only affects dynamic libraries. I can see what is causing it if I link in verbose mode (-v) with gcc 4.9.2 and also with gcc 5.1, placing -lm before it is needed, and examine the differences in the verbose output.

    From gcc 4.9.2 I have (with artifical line-wrapping):

    /usr/lib/gcc/x86_64-linux-gnu/4.9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so 
    -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccsHNLNB.res 
    -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc 
    -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id 
    --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker 
    /lib64/ld-linux-x86-64.so.2 -z relro -o mathtest 
    /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o 
    /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o 
    /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.9 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib -L/lib/x86_64-linux-gnu 
    -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib 
    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. -lm mathtest.o -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.9/crtend.o 
    /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o
    

    And from gcc 5.1 I have:

    /usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so 
    -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/cc5hI8vd.res 
    -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc 
    -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id 
    --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker 
    /lib64/ld-linux-x86-64.so.2 -z relro -o mathtest 
    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o 
    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o 
    /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/5 
    -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu 
    -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib -L/lib/x86_64-linux-gnu 
    -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib 
    -L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. -lm mathtest.o -lgcc --as-needed 
    -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed 
    /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o 
    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
    

    The relevant difference is that the gcc 4.9.2 linkage passes the option --as-needed in 4 places whereas the gcc 5.1 linkage passes it in only 3. gcc 4.9.2 passes --as-needed for the first time at the the 5th quoted "line":

    --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker
    

    gcc 5.1 does not pass it there. Thereafter, both linkages pass this option at the same 3 places, starting as the 13th "line":

    -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. -lm mathtest.o -lgcc --as-needed
    

    This means that for gcc 4.9.2, the library option -lm on "line" 13 falls within the scope of the first --as-needed. For gcc 5.1 it does not. The effect of this option is to inform the linker that the dynamic library libm (or any dynamic library that is encountered in the option's scope) shall be linked only if it is encountered at a point in the linkage at which it can satisfy some unresolved symbols. In the absence of this option, at a given point in the linkage, a dynamic library is by default deemed to be needed for the linkage regardless of whether there are yet any unresolved symbols that it can satisfy. See the documentation of --as-needed

    Thus the gcc 4.9.2 linkage will not link libm, although it appears on the commandline, because at the point where it appears - before mathtest.o - --as-needed is in force and there are as yet no unresolved references that libm satisfies. The gcc 5.1 linkage will link libm because it appears on the commandline at a point where --as-needed is not in force.

    0 讨论(0)
提交回复
热议问题