Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking fails with gcc 4.8.2 / ld 2.24, succeeds with gcc 4.4.7 / ld 2.20

Tags:

c

linux

gcc

linker

ld

In a chroot based on CentOS 6.4 I'm working in, linking against ncurses with ld 2.20 succeeds, but linking with ld 2.24 fails. I don't directly invoke the linker, gcc is handling it -- gcc 4.4.7 is using ld 2.20, and gcc 4.8.2 is using ld 2.24.

Here is a minimal example that fails to link with gcc 4.8.2 / ld 2.24 in my particular environment.

#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    WINDOW* window = NULL;

    if (!(window = initscr())) {
        printf("Error initializing ncurses.");
        exit(1);
    }

    halfdelay(50);
    getch();
    endwin();
}

Success (ld 2.20):

$ gcc main.c -lncurses -Wl,--verbose | grep "ncurses.*succeeded" attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libncurses.so succeeded $

Failure (ld 2.24):

$ /opt/gcc/4.8.2/bin/gcc48 main.c -lncurses -Wl,--verbose | grep "ncurses.*succeeded" attempt to open /usr/lib/../lib64/libncurses.so succeeded /opt/binutils/2.24/bin/ld24: /tmp/ccCxUFxl.o: undefined reference to symbol 'halfdelay' /lib64/libtinfo.so.5: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status $

Note that both commands appear to link against the same libncurses.so.

For what it's worth, in a different chroot based on CentOS 5.4, there is a different libncurses version, and it links fine with ld 2.24, but unfortunately, building in that chroot is not an option. The nm utility shows that the (static) libncurses.a here does have the required symbols (nm lists no symbols for libncurses.so -- so I'm just assuming they are similar).

In the CentOS 6.4 chroot, however, nm shows that all of the ncurses symbols I'm getting "undefined reference" messages for are indeed undefined or not present in libncurses.a in the Centos 6.4 chroot, which is confusing, because linking with gcc 4.4.7 works. Something is not right.

Also, I tried producing an object with gcc 4.4.7, and then linking with gcc 4.8.2, but that did not help.

I'm confused as to why the one compiler / linker would succeed while the other would fail. Is this an ABI issue? Does anyone know what is happening here? Are there any flags I can pass to gcc to make the new linker work?

like image 227
tgnottingham Avatar asked Oct 29 '25 09:10

tgnottingham


1 Answers

Your libncurses library is itself linked to libtinfo, which causes your older toolchain to also look for symbols in libtinfo.

But newer toolchains normally runs the linker with the --as-needed, and the --no-copy-dt-needed-entries, the latter which probably causes the difference you're seeing.

Basically you'll need to link to libtinfo as well, which is where the halfdelay function resides.

gcc main.c -lncurses -ltinfo
like image 158
nos Avatar answered Oct 30 '25 23:10

nos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!