Search code examples
c++ncurseslinker-errors

Compilation linking with libncurses fail with "undefined reference"


I've just installed ncurses from sources, and the Makefile log make it looks like everything is OK. Both libncurses.a and libncurses++.a are present and using -lncurses or -lncurses++ won't raise "cannot found -lX" errors.

$ ls -al /usr/lib/x86_64-linux-gnu/*curses*
lrwxrwxrwx 1 root root     12 Feb 19  2016 /usr/lib/x86_64-linux-gnu/libcurses.a -> libncurses.a
lrwxrwxrwx 1 root root     13 Feb 19  2016 /usr/lib/x86_64-linux-gnu/libcurses.so -> libncurses.so
-rw-r--r-- 1 root root 298812 Feb 19  2016 /usr/lib/x86_64-linux-gnu/libncurses.a
-rw-r--r-- 1 root root 171456 Feb 19  2016 /usr/lib/x86_64-linux-gnu/libncurses++.a
-rw-r--r-- 1 root root     31 Feb 19  2016 /usr/lib/x86_64-linux-gnu/libncurses.so

Strangely, when trying to compile a dummy sample like

#include <cursesapp.h>
#include <cursesm.h>
#include <cursesf.h>

int main() {
    NCursesPanel *mystd = new NCursesPanel();

    return 0;
}

with g++ src/main.cpp -o main -lncurses++ will throw a really long list of linking errors inside libcurses++. Linking with an extra -lncurses won't help either. A small excerpt:

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libncurses++.a(cursesw.o): In function `NCursesWindow::initialize() [clone .part.11]':
(.text+0xd0): undefined reference to `noecho'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libncurses++.a(cursesw.o): In function `NCursesWindow::scanw(char const*, ...)':
(.text+0x214): undefined reference to `vwscanw'

I found it weird that the error messages point to /usr/lib/gcc/5 and thought that maybe there are two libncurses on my machine, but I couldn't find it.

Is there really a problem of multiple ncurses on my machine? How can I investigate further and solve the linking problem?


Solution

  • TL;DR

    The official C++ interface may actually require that you link with all ncurses extra libraries, namely Menu, Panel, and Forms. The following solved the problem:

    g++ file.cpp -lncurses++ -lmenu -lpanel -lform -lutil -lncurses

    Follow the Demo

    Looking at the c++ code online I realized that it comes with a demo.cc and inspecting the make process it is clear that the demo is compiled. Because the installation went smoothly, I knew that the build process was capable of compiling so I should be too.

    The complete command issued in the make was:

    g++ -o demo ../objects/demo.o -L../lib -lncurses++ -L../lib -lform -lmenu -lpanel -lncurses -lutil -DHAVE_CONFIG_H -I../c++ -I. -I../include -D_GNU_SOURCE -D_DEFAULT_SOURCE -DNDEBUG -O2

    So after replacing the object with the actual source file, I started removing flags and arguments until it broke the compilation. Turns out libcurses++ depends on those.