Recommand · October 14, 2021 0

gcc link error depending on the input file argument position

  • Environment
    $ lsb_release -a
    Description: Ubuntu 20.04.2 LTS
    $gcc –version
    gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

  • Problem

    • link error happens depending on the position of input file.
    • OK
      $gcc -lsndfile -o snd-003 snd-003.c
        /usr/bin/ld: /tmp/ccMmdgxh.o: in function `main':  
        snd-003.c:(.text+0x5c): undefined reference to `sf_open'  
        /usr/bin/ld: snd-003.c:(.text+0x88): undefined reference to `sf_readf_short'  
        /usr/bin/ld: snd-003.c:(.text+0xc4): undefined reference to `sf_close'  
        collect2: error: ld returned 1 exit status       
    
    • NG
      If you change the argument position of input file, then link error does not happen.
      $gcc snd-003.c -lsndfile -o snd-003
  • Other info

    • snd-003.c is uploaded below (just FYI).
      https://file.io/PA4K22CzXwsi
    • this problem happens on other gcc version
      • gcc 8.4.0
      • gcc 7.5.0
    • this error happens on other libraries too (e.x. libssl).
    • there is no this problem on other machines.
      • deiban 10.9 (gcc 8.3.0)
      • debian 8.3 (gcc 4.9.2)
    • similar problem reported long time ago, but it’s not solved.
      strange g++ linking behavior depending on arguments order
  • Question
    Does anyone have some clue on what’s wrong with this ? gcc ? environment ?
    I want to know the root cause of this behavior.
    Any comments are really appreciated.

I guess this is the expected behavior (https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html):

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again. See the -( option for a way to force the linker to search archives multiple times.