Home > Software design >  Where do I put the -lncurses to properly link the ncurses library
Where do I put the -lncurses to properly link the ncurses library

Time:06-13

I can't find a way to properly link the ncurses library. The same code compiled just right on mac, but won't compile on linux. I am getting an error saying undefined reference to waddnwstr. In the example I only use the mvwaddwstr function that expands to waddwstr and then to waddnwstr.

This is the error message I am getting:

/usr/bin/ld: Game.o: in function `Game::printIconInColor(int, int, wchar_t const*, int)':
/home/build/./src/include/Game.cpp:1058: undefined reference to `waddnwstr'

This is the piece of code that generates the error:

void Game::printIconInColor( int y, int x, const wchar_t* icon, int color ){
  if( color ) wattron( m_window, COLOR_PAIR( color ) );
  mvwaddwstr( m_window, y, x, icon );
  if( color ) wattroff( m_window, COLOR_PAIR( color ) );
}

I have read a lot of similar questions on stack overflow, but none of them work, or I am getting it wrong...

Here is the makefile:

CXX = g  
CXXFLAGS = -g -Wall -pedantic -Iinclude -std=c  17 -O2 -D_XOPEN_SOURCE_EXTENDED
EXECUTABLE = game
OBJECTS = main.o Character.o MC.o NPC.o Potion.o Game.o
INC = ./src/include/
SRC = $(shell find $(INC) -type f -name '*.cpp')
LDFLAGS = -lncurses -lstdc  fs 


all:    compile run

compile: $(OBJECTS) 
    $(CXX) $(CXXFLAGS) -o $(EXECUTABLE) $(OBJECTS) $(LDFLAGS)

doc: $(SRC)
    doxygen

run:
    ./$(EXECUTABLE)

clean:
    rm $(EXECUTABLE) $(OBJECTS)


main.o: ./src/main.cpp
    $(CXX) $(CXXFLAGS) -c ./src/main.cpp

Character.o: $(INC)Character.cpp
    $(CXX) $(CXXFLAGS) -c $(INC)Character.cpp 

NPC.o: $(INC)NPC.cpp
    $(CXX) $(CXXFLAGS) -c $(INC)NPC.cpp

MC.o: $(INC)MC.cpp
    $(CXX) $(CXXFLAGS) -c $(INC)MC.cpp

Potion.o: $(INC)Potion.cpp
    $(CXX) $(CXXFLAGS) -c $(INC)Potion.cpp

Game.o: $(INC)Game.cpp
    $(CXX) $(CXXFLAGS) -c $(INC)Game.cpp

Example that works on mac:


#include <ncurses.h>

int main(){
  setlocale(LC_ALL, "");
  initscr();

  WINDOW * win = newwin( 10, 10, 10, 10 );

  box( win, 0, 0 );
  mvwaddwstr( win, 1, 1, L"\u238B" );
  wgetch( win );
  endwin();

  return 0;
}

CodePudding user response:

You need to link the ncursesw library if you want wide character support:

LDFLAGS = -lncurses -lncursesw -lstdc  fs 

CodePudding user response:

Apple's bundled copy of ncurses (5.7) is configured for wide-character ncurses. For that platform (and perhaps a few others), the makefile could just use -lncurses.

But waddwnstr uses wchar_t parameters, which makes it a wide-character function. For the usual case, that is in the wide-character library, so you would use -lncursesw.

If you were using an add-on library (i.e., MacPorts or brew), that uses a symbolic link to allow either name to be used, to simplify porting.

Keeping things like this straight is generally done with configure scripts (to produce a correct makefile), so that your makefile would contain

LDFLAGS = -lncurses -lstdc  fs

or

LDFLAGS = -lncursesw -lstdc  fs

If both libraries were specified, the linker should complain about the duplicated symbols between the two libraries -- for most platforms other than MacOS.

When both libraries are available, the header files also are available, requiring some compiler (-I) options and/or source-modification to use the correct header (not just ncurses.h). Again, a configure script is the usual approach.

  • Related