G++ can't find references to raw() or cbreak()

2020-04-15 15:18发布

问题:

I'm having trouble getting some absolute basic work with curses.h done, even though I've worked with it before. I'm sure it's a classic case of missing something small, but I'm at my wit's end.

G++ absolutely won't recognize the functions raw() or cbreak(), even though curses.h is included in my .cpp and header file, and linked to when compiling with (minimal version):

g++ debugC.cpp -lcurses

With the relevant code being:

#include <curses.h>
#include "debugC.h"
#include "machine.h"

using namespace std;

debugC::debugC(machine *BFM){
    localMachine = BFM;
}

//entry into debugger
void debugC::start(){
    void * v = NULL;
    initscr();
    raw();
    noecho();
}

The errors returned by g++:

/usr/bin/ld: /tmp/cci6mA0L.o: undefined reference to symbol 'raw'
/usr/lib/libtinfo.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

I've stripped this down to minimal functioning code for clarity. It compiles without the call to raw().

curses.h is clearly included, and I've linked against it when compiling. How could it not understand references to some curses functions, and not others?

I've scoured SO and Google for help but I can't seem to find a solution, I'd really appreciate any possible insight. Thanks.

回答1:

Some systems configure ncurses as two libraries: ncurses (or ncursesw) which is the high-level library, and tinfo (or tinfow) which is the low-level library. raw is a low-level feature.

Most systems provide the package/configuration scripts (e.g., ncursesw6-config or the data files for pkg-config), and the --libs option lists both libraries when it is built in this way:

$ ncursesw6-config --libs
-lncursesw6 -ltinfow6

$ pkg-config --libs ncursesw6
-lncursesw6 -ltinfow6

For example, assuming a correctly installed pkg-config, you could do something like:

g++ debugC.cpp $(pkg-config --libs ncurses)

In some configurations (using the rpath feature for instance), the dependent library names are stored in the shared library, so that all one needs to do is refer to the top-level library to get both. Debian (and derived systems such as Ubuntu) don't use rpath, while also configuring ncurses as two libraries.

Two methods of configuration are provided (but depends on the packager...), by the way:

  • ncurses*-config script predates pkg-config, and works (though some are confused by the naming convention for cross-compiler tools), while
  • pkg-config has problems with standardization (not noticed by single-platform developers).