3
votes

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?

1
@FaroukJouti, that would be wrong, so there's no reason to try it! Libraries come after the files that need them. - Jonathan Wakely
I tried the exact same thing you tried and it worked just fine for me in gcc 4.8.2 - Farouq Jouti

1 Answers

3
votes

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