Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

G++ Failing to link ncurses even though it has the -lncurses flag

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#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);
}

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading