views:

41

answers:

2

I'm having some problems statically linking ncurses to one of my programs

Here's a really simple sample program:

#include<ncurses.h>


int main(){

    initscr();
    printw("Hello world\n");
    refresh();
    getch();
    endwin();
    return 0;
}

When I compile it with

gcc -static -lncurses hello_curses.c -o curses

I get these errors:

/tmp/ccwHJ6o1.o: In function `main':
curses_hello.c:(.text+0x5): undefined reference to `initscr'
curses_hello.c:(.text+0x14): undefined reference to `printw'
curses_hello.c:(.text+0x1b): undefined reference to `stdscr'
curses_hello.c:(.text+0x20): undefined reference to `wrefresh'
curses_hello.c:(.text+0x27): undefined reference to `stdscr'
curses_hello.c:(.text+0x2c): undefined reference to `wgetch'
curses_hello.c:(.text+0x31): undefined reference to `endwin'
collect2: ld returned 1 exit status

I'm a little confused why this isn't working. What am I missing here?

+1  A: 

Edit:

I think the real problem is that you need to specify your -l option at the end of the command. I just tried it the way you had it and reproduced your error. If I put -l:libncurses.a at the end of the line then it works. All without the -static option BTW.


I think what is happening is that you have a dynamic library for ncurses but you have used the -static option which means to not use any dynamic libraries. I suspect you do not actually have a static version of the ncurses library i.e. one ending with a .a suffix.

If you want to link with the static version (.a) of ncurses rather than the dynamic version (.so) then temporarily remove the symlink for libncurses.so so that the linker picks up the .a file instead. Alternatively copy the .a file somewhere else and add that to an earlier search path.

Alternatively if your linker supports it (eg. ld) then you could specify -l:libncurses.a instead of -lncurses.

Troubadour
Thanks for the response troubadour. I initially thought that the problem was that the static library wasn't installed, but it is in /usr/lib.I'll try adding it to an earlier search path
mdogg
@mdogg: I now think the issue is where the `-l` option appears. [@Gilles' answer](http://stackoverflow.com/questions/3514852/statically-link-ncurses-to-program/3515002#3515002) is in agreement.
Troubadour
+4  A: 

You need to pass -l options at the end of the command line:

gcc -static hello_curses.c -o curses -lncurses

When the compiler encounters -lfoo, it links in all the symbols from foo that have been requested by a previous file. If you put -lfoo at the beginning, no symbol has been requested yet, so no symbol gets linked.

Gilles
+1: for the explanation!
Troubadour
thanks! that allows it to compile. However when I try to run it in my enviroment I get "Error opening terminal: vt102." Is this a problem with libncurses not being linked properly?
mdogg
@mdogg: FWIW, it runs fine for me so I would say it's not the static linking per se.
Troubadour
It works when I'm in my normal enviroment, but when I run it under a really stripped down enviroment I get this error. I think it has something to do with the lack of shared libraries, but I'm not really sure.
mdogg
@mdogg: the ncurses library needs additional data files that describe the various terminal types. You need to either install the terminfo or termcap description for `vt102` (and any other terminal type you will need) or pass the terminal description in the environment (`$TERMCAP` or `$TERMINFO`). The [ncurses FAQ](http://invisible-island.net/ncurses/ncurses.faq.html#big_terminfo) may help.
Gilles
yep, that was the problem. I added the termcap info into /usr/share and it worked. Thanks a alot!
mdogg