os kern error : "ld: symbol(s) not found for architecture x86_64"

526 views Asked by At

I have looked all over Stack Overflow and other websites about this famous error, and all of them are very specific, and in my case I cannot find a solution. I am making an ncurses application and when i try to compile it, it causes the following error:

Undefined symbols for architecture x86_64:
    "NCRS::End()", referenced from:
        _main in crspro-85eaaf.o
    "NCRS::Start()", referenced from:
        _main in crspro-85eaaf.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I compile the code with the following line:

$ clang++ crspro.cpp -lncurses -o crspro

Here is the code:

crspro.cpp

#include "ncrs.h"

int main(int argc, char* argv[]) {

    NCRS::Start();
    getch();
    NCRS::End();

    return 0;
}

ncrs.h

#ifndef NCRS_H
#define NCRS_H

#include <ncurses.h>
#include <string>

typedef std::string string;

class NCRS {
private:
    static bool __curses_on;
    static bool __buffer;
    static bool __echo;
    static bool __keypad;
public:
    static void Start(bool bbuffer=false, bool becho=false, bool bkeypad=false);
    static void End();
};

#endif

ncrs.cpp

#include "ncrs.h"

static void NCRS::Start(bool bbuffer=false, bool becho=false, bool bkeypad=false) {
    initscr();
    if (bbuffer) raw();
    if (becho) echo(); else noecho();
    if (bkeypad) keypad(stdscr, TRUE); else keypad(stdscr, FALSE);

    __buffer = bbuffer;
    __echo = becho;
    __keypad = bkeypad;
    __curses_on = true;
}

static void NCRS::End() { nocbreak(); echo(); keypad(stdscr, FALSE); endwin(); }

I don't have any issues in the code itself as far as I can tell. I have tried even including ncrs.cpp (The horror!!) but I still get the same problems. Can anyone help with this issue? I've had this problem before with other projects and I've had to abandon them because I couldn't find a solution.

Thanks to anyone who can help!

_

_

EDIT

compile with:

clang++ crspro.cpp ncrs.cpp -lncurses -o crspro

returns error:

Undefined symbols for architecture x86_64:
  "NCRS::__curses_on", referenced from:
      NCRS::Start(bool, bool, bool) in ncrs-e52041.o
  "NCRS::__echo", referenced from:
      NCRS::Start(bool, bool, bool) in ncrs-e52041.o
  "NCRS::__buffer", referenced from:
      NCRS::Start(bool, bool, bool) in ncrs-e52041.o
  "NCRS::__keypad", referenced from:
      NCRS::Start(bool, bool, bool) in ncrs-e52041.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
1

There are 1 answers

1
Michael Anderson On BEST ANSWER

Your compilation isn't including anything from ncrs.cpp, which is where both NCRS::Start() and NCRS::End() are defined. You probably want

clang++ crspro.cpp ncrs.cpp -lncurses -o crspro

Or if you want to build the object files separately and then link them:

clang++ -c crspro.cpp -c
clang++ -c ncrs.cpp -c
clang++ crspro.o ncrs.o -lncurses -o crspro

Your next error about "NCRS::__curses_on" is because you're using static variables without defining them you need to add

bool NCRS::__curses_on=false;
bool NCRS::__buffer=false;
bool NCRS::__echo=false;
bool NCRS::__keypad=false;

to one of your .cpp files. (presumably ncrs.cpp is the logical place.)

It's probably worth thinking about whether they should be static (and whether the functions should be static too) - they may need to be, but static class variables are essentially global variables, which will often come back to bite you later. They make it harder to understand the flow of the code, and can make multi-threading and testing painful.