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.