I'm trying to compile an ncurses file using g++. It gives this output which would suggest that it isn't linking correctly. Interestingly it compiles fine under clang++. I have ncurses installed from source and I know that it's working because it compiles under clang. Ignore the warnings at the start of the file, I'm going to work on those next. Also I know that main.cpp is godawful, I'm working on fixing that too.
CC main.cpp ./main
main.cpp: In function ‘int main(int, char**)’:
main.cpp:34:34: warning: format not a string literal and no format arguments [-Wformat-security]
34 | wprintw(window_one, text.c_str());
| ^
main.cpp:38:34: warning: format not a string literal and no format arguments [-Wformat-security]
38 | wprintw(window_two, text.c_str());
| ^
/usr/bin/ld: /tmp/cct3HGZR.o: in function `main':
/home/ubuntu/side-projects/slides/main.cpp:13: undefined reference to `initscr'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:14: undefined reference to `cbreak'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:16: undefined reference to `stdscr'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:16: undefined reference to `keypad'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:18: undefined reference to `start_color'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:19: undefined reference to `init_pair'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:21: undefined reference to `stdscr'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:21: undefined reference to `wbkgd'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:23: undefined reference to `LINES'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:24: undefined reference to `COLS'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:27: undefined reference to `printw'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:28: undefined reference to `refresh'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:33: undefined reference to `wmove'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:34: undefined reference to `wprintw'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:35: undefined reference to `wrefresh'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:37: undefined reference to `COLS'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:37: undefined reference to `COLS'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:37: undefined reference to `LINES'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:38: undefined reference to `wprintw'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:39: undefined reference to `wrefresh'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:41: undefined reference to `stdscr'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:41: undefined reference to `wgetch'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:45: undefined reference to `endwin'
/usr/bin/ld: /tmp/cct3HGZR.o: in function `create_newwin(int, int, int, int)':
/home/ubuntu/side-projects/slides/main.cpp:52: undefined reference to `newwin'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:53: undefined reference to `box'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:55: undefined reference to `wrefresh'
/usr/bin/ld: /tmp/cct3HGZR.o: in function `destroy_win(_win_st*)':
/home/ubuntu/side-projects/slides/main.cpp:60: undefined reference to `wborder'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:61: undefined reference to `wrefresh'
/usr/bin/ld: /home/ubuntu/side-projects/slides/main.cpp:62: undefined reference to `delwin'
collect2: error: ld returned 1 exit status
make: *** [Makefile:9: all] Error 1
Here's my makefile:
CC = g++
CFLAGS = -g -lncurses -Wall
SRC = main.cpp
OUT = ./main
.PHONY: all
all: ${SRC}
@echo "CC " ${SRC} ${OUT}
@${CC} ${CFLAGS} ${SRC} -o ${OUT}
@echo "Done"
.PHONY: clean
clean:
@echo "Cleaning Directory"
@rm -rf ${OUT}
@echo "Done"
And here's the C++ that I'm trying to compile:
#include <ncurses.h>
#include <string>
WINDOW *create_newwin(int height, int width, int starty, int startx);
void destroy_win(WINDOW *local_win);
int main(int argc, char *argv[]) {
WINDOW *window_one;
WINDOW *window_two;
int startx, starty, width, height;
int ch;
initscr();
cbreak();
keypad(stdscr, TRUE);
start_color();
init_pair(1, COLOR_BLUE, COLOR_RED);
bkgd(COLOR_PAIR(1));
height = LINES;
width = COLS / 2;
starty = 0;
startx = 0;
printw("Press F1 to exit");
refresh();
window_one = create_newwin(height, width, starty, startx);
std::string text = "test";
wmove(window_one, height / 2, text.size() / 2);
wprintw(window_one, text.c_str());
wrefresh(window_one);
window_two = create_newwin(LINES, COLS / 2, 0, COLS / 2);
wprintw(window_two, text.c_str());
wrefresh(window_two);
while((ch = getch()) != KEY_F(1)) {
switch(ch) {}
}
endwin();
return 0;
}
WINDOW *create_newwin(int height, int width, int starty, int startx) {
WINDOW *local_win;
local_win = newwin(height, width, starty, startx);
box(local_win, 0, 0);
wrefresh(local_win);
return local_win;
}
void destroy_win(WINDOW *local_win) {
wborder(local_win, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ');
wrefresh(local_win);
delwin(local_win);
}
Libraries should normally come last on the g++ command line, otherwise they may not be searched. This is because the linker only searches libraries if there are undefined names in the files it has already looked at - in your case, it hasn't looked at any at the point it comes across the library.
You probably want a separate makefile variable called LIBS or similar which you tack on the end of the g++ command line.