C++: Undefined symbols for architecture x86_64 - c++

I have read most of the other posts with this title, but I could not find a solution.
I have three files (I know the whole program doesn't make any sense, it is just for test purposes):
main.cpp
#include "Animal.h"
Animal ape;
int main(int argc, char *argv[]){
ape.getRace();
return 0;
}
Animal.h
class Animal{
public:
int getRace();
private:
int race;
};
Animal.cpp
#include "Animal.h"
Animal::Animal(){
race = 0;
}
int Animal::getRace(){
race = 2;
return race;
}
When I run the main.cpp file I get this error:
Undefined symbols for architecture x86_64:
"Animal::getRace()", referenced from:
_main in main-oTHqe4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[Finished in 0.1s with exit code 1]
What is wrong here?

You need to compile and link Animal.cpp and main.cpp together, for example:
gcc main.cpp Animal.cpp
It looks like you are not linking against Animal.o (which the above command would do).
P.S. You also need to declare the default constructor that you are defining in Animal.cpp:
class Animal{
public:
Animal(); // <=== ADD THIS
int getRace();
private:
int race;
};

Related

Cannot Configure CLion for Linking C++

I have a simple c++ example that I am trying to compile on a MacOSX machine using the CLion IDE. The goal is to use header files and cmake to compile this code on CLion with an aim to expand to something bigger and so for now, I have simplified my code to have a bar.h header file and a bar.cpp implementation file. I am getting compilation issues during linking. My code looks as follows:
main.cpp
#include "bar.h"
using namespace std;
int main(int argc, char** argv){
cout<<"starting"<<endl;
Bar bar = Bar("Using Bar Function From Main");
bar.foo();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
set(CMAKE_CXX_STANDARD 11)
project(librarytest)
add_executable(myprog main.cpp)
add_subdirectory(bars)
target_link_libraries(myprog PRIVATE bars)
bars\bar.h
#pragma once
#include <string>
#include <iostream>
class Bar{
private:
std::string s;
public:
Bar(std::string s);
void foo();
};
bars\bar.cpp
#include <string>
#include <iostream>
class Bar{
private:
std::string s;
public:
Bar(std::string s){
std::cout<<"Function Bar"<<std::endl;
this->s = s;
}
void foo(){
std::cout << this->s << std::endl;
}
};
bars\CMakeLists.txt
add_library(bars OBJECT
bar.cpp
)
target_include_directories(bars PUBLIC .)
I get the following error message from my CLion CMake build (I have obfuscated by personal details/directory):
====================[ Build | all | Debug ]=====================================
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build /{obfuscated-for-security}/testingincludes/cmake-build-debug --target all
[3/3] Linking CXX executable myprog
FAILED: myprog
: && /Library/Developer/CommandLineTools/usr/bin/c++ -g -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names bars/CMakeFiles/bars.dir/bar.cpp.o CMakeFiles/myprog.dir/main.cpp.o -o myprog && :
Undefined symbols for architecture x86_64:
"Bar::foo()", referenced from:
_main in main.cpp.o
"Bar::Bar(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
I have searched other Stack Overflow articles on similar errors but none can explain the issue as it pertains to linking on the OSX. I have followed some of the guidance like re-installing the compiler.
Can anyone suggest how to get this working on the MacOSX using CLion? Any pointers or suggestions would be welcomed.
The problem is not the build (AFAIK), it's the code.
Your bar.cpp file should look like this
#include "bar.h"
#include <string>
#include <iostream>
Bar::Bar(std::string s){
std::cout<<"Function Bar"<<std::endl;
this->s = s;
}
void Bar::foo(){
std::cout << this->s << std::endl;
}
Your version duplicates the Bar class definition in both the header and cpp file. My version includes the Bar class definition and just adds the definitions of the constructor and member function.

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

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)
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.

C++ class method not found when compiled

I created a simple class 'Hello' in C++ using header(.h) and definition(.cpp) files. This is the header file content:
#ifndef HELLO_H
#define HELLO_H
#include <string>
namespace test
{
class Hello
{
private:
std::string name;
public:
Hello();
void say_hello();
};
}
#endif
And the definition file content is just as you expected:
#include "Hello.h"
#include <iostream.h>
using namespace test;
Hello::Hello()
{
this->name = "Yoppy Yunhasnawa";
}
void Hello::say_hello()
{
string message = "Hello, " + this->name + ".. Have nice day!";
cout << message << "\n";
}
I included this class to a main.cpp file and use it like this:
#include "Hello.h"
using namespace test;
int main(int argc, char *argv[])
{
Hello* hello = new Hello;
hello->say_hello();
}
When I compiled the main.cpp file with g++ like this,
g++ main.cpp
I got following annoying error:
Undefined symbols for architecture x86_64:
"test::Hello::say_hello()", referenced from:
_main in ccsaoOZa.o
"test::Hello::Hello()", referenced from:
_main in ccsaoOZa.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
However, that error does not appear when I don't call both constructor and say_hello method:
int main(int argc, char *argv[])
{
Hello* hello;// = new Hello;
//hello->say_hello();
}
I use macport GCC 4.7 and I am very sure that my method is there but why this symbol(s) not found error keep appearing? Please show me my mistake. Thank you.
When you invoke g++ main.cpp, compiler performs both compiling AND linking. But the code cannot be linked without Hello.cpp file. So, you have two options: either compile and link separately:
g++ -c main.cpp
g++ -c hello.cpp
gcc main.o hello.o
or compile and link everything at the same time:
g++ main.cpp hello.cpp

Mac OS x gives ld: symbol(s) not found for architecture x86_64

I am trying to compile a c++ program which works fine in Xcode but gives error in terminal.
main.cpp
int main(int argc, const char * argv[])
{
Example* example =new Example();
example->show();
}
example.h
class Example {
public:
void show();
};
example.cpp
void Example::show() {
std::cout<<"Hello World"<<std::endl;
}
Error i get
"Example::show()", referenced from:
_main in cckpIa3V.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
I am compiling using g++
g++ -o test main.cpp
You aren't linking in example.o. You don't show your command line/Makefile, so this is (roughly) what you need to type:
$ g++ -o example main.cpp example.cpp
That will compile and link the source files to an executable called example.

Why my C++ class definition fails?

main.cpp
#include <iostream>
#include "Burrito.h"
using namespace std;
int main(){
Burrito b;
return 0;
}
Burrito.h
#ifndef BURRITO_H
#define BURRITO_H
class Burrito{
public:
Burrito();
};
#endif
Burrito.cpp
#include "Burrito.h"
#include <iostream>
Burrito::Burrito(){
}
Compile & Link :
lzsb$ g++ main.cpp -o main
Undefined symbols for architecture x86_64:
"Burrito::Burrito()", referenced from:
_main in ccVpCr0z.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
lzsb$
Platform:
Mac OS 10.6.8
G++ : i686-apple-darwin10 --with-gxx-include-dir=/usr/include/c++/4.2.1
You need to compile the Burrito.cpp file as well. The compiler creates object files from each .cpp file and links them afterwards. This is where your call fails, because the linker can't find the referenced Burrito class in any of your object files. To fix your compiler call just add Burrito.cpp
g++ main.cpp Burrito.cpp -o main
Your compile line should be:
g++ Burrito.cpp main.cpp -o main