Statically link ncurses to program

18,572

Solution 1

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.

Solution 2

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.

Solution 3

I just spent a few hours on an ARM processor, trying to get it to work, as the accepted answer didn't work for me.

Here are my findings:

Apparently

gcc -static hello_curses.c -o curses -lncurses

works on an x64 processor, but not on an ARM processor.

When I tried with the above line, I still got all the "undefined reference errors" (and a lot more) of the OP.

You need to also link against libtinfo.a, and note that sequence matters.
This is the correct command line that works:

gcc -static hello_curses.c -o curses -lncurses -ltinfo

If you mix up the sequence, then it won't work...

gcc -static hello_curses.c -o curses -ltinfo -lncurses 

undefined reference to `unctrl'

Of course this also works if you use the :lib syntax

This compiles

gcc -static hello_curses.c -o curses -l:libncursesw.a -l:libtinfo.a

This does not compile

gcc -static hello_curses.c -o curses -l:libtinfo.a -l:libncursesw.a 

Oh how I like gcc...
This program should never have been allowed to graduate from kindergarden

(.text+0x2a8): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioninit_pair': (.text+0x2ac): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioninit_pair': (.text+0x50a): undefined reference to tparm' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioninit_pair': (.text+0x518): undefined reference to _nc_putp' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioninit_color': (.text+0x552): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioninit_color': (.text+0x556): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioninit_color': (.text+0x5e4): undefined reference to tparm' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioninit_color': (.text+0x5f2): undefined reference to _nc_putp' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioncan_change_color': (.text+0x740): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioncan_change_color': (.text+0x744): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functionhas_colors': (.text+0x768): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functionhas_colors': (.text+0x76c): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In functioncolor_content': (.text+0x7c2): undefined reference to cur_term' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o):(.text+0x7c6): more undefined references tocur_term' follow /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In function _nc_do_color': (.text+0x8de): undefined reference to tparm' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In function _nc_do_color': (.text+0x8e6): undefined reference to tputs' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In function _nc_do_color': (.text+0x958): undefined reference to tputs' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In function set_foreground_color': (.text+0x62): undefined reference totputs' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_color.o): In function set_background_color': (.text+0xa2): undefined reference totputs' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_hline.o): In function whline': (.text+0xec): undefined reference toacs_map' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_hline.o): In function whline': (.text+0xf0): undefined reference toacs_map' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_add_wch.o): In function wadd_wch': (.text+0x4fe): undefined reference to TABSIZE' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_add_wch.o): In function wadd_wch': (.text+0x502): undefined reference to TABSIZE' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_add_wch.o): In function wecho_wchar': (.text+0x6d8): undefined reference to TABSIZE' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_add_wch.o): In function wecho_wchar': (.text+0x6dc): undefined reference to TABSIZE' /usr/lib/gcc/arm-linux-gnueabihf/4.8/../../../arm-linux-gnueabihf/libncursesw.a(lib_wunctrl.o): In function wunctrl': (.text+0x30): undefined reference tounctrl' collect2: error: ld returned 1 exit status

Share:
18,572
mdogg
Author by

mdogg

Updated on June 04, 2022

Comments

  • mdogg
    mdogg about 2 years

    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?

  • mdogg
    mdogg almost 14 years
    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
  • Troubadour
    Troubadour almost 14 years
    @mdogg: I now think the issue is where the -l option appears. @Gilles' answer is in agreement.
  • mdogg
    mdogg almost 14 years
    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?
  • Troubadour
    Troubadour almost 14 years
    @mdogg: FWIW, it runs fine for me so I would say it's not the static linking per se.
  • mdogg
    mdogg almost 14 years
    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.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' almost 14 years
    @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 may help.
  • mdogg
    mdogg almost 14 years
    yep, that was the problem. I added the termcap info into /usr/share and it worked. Thanks a alot!
  • Wyatt Ward
    Wyatt Ward over 6 years
    you can also just add the path to your .a archive without -l preceding it at all and it'll link that static library into your program. e.g. gcc hello_curses.c -o curses /path/to/libncurses.a