I am trying to compile C++ code with Geany.
Compile command: g++ -Wall -c "%f"
Build command: g++ -Wall -o "%e" "%f"
main.cpp:
#include <iostream>
#include "Person.hpp"
int main()
{
Person p1(16);
std::cout << p1.getAge();
return 0;
}
Person.hpp
class Person
{
public:
Person(int a);
void setAge(int);
int getAge() const;
private:
int age;
};
inline int Person::getAge() const
{
return age;
}
Person.cpp
#include "Person.hpp"
Person::Person(int a)
{
age = a;
}
void Person::setAge(int a)
{
age = a;
}
Error:
g++ -Wall -o "main" "main.cpp" (in directory:
/home/me/projects/Test) /tmp/ccxYmWkE.o: In function main':
main.cpp:(.text+0x15): undefined reference toPerson::Person(int)'
collect2: error: ld returned 1 exit status Compilation failed.
Before Geany, I only used Code::Blocks and everything worked fine. How can I fix it?
It's obvious you didn't add Person.cpp to the compilation command. then it can not pass the linkage level.
Add -o Person Person.cpp to the build option after g++ -Wall -c "%e" "%f".
After all the compile command should be something like below:
g++ -Wall -o "main" "main.cpp" -o Person Person.cpp
Related
I am getting this error:
g++ -c location.cpp
g++ -c place.cpp
g++ -c popularplace.cpp
g++ -c person.cpp
g++ -o main main.cpp *.o
Undefined symbols for architecture x86_64:
"sim::PopularPlace::arraycounter", referenced from:
sim::PopularPlace::PopularPlace() in popularplace.o
sim::PopularPlace::PopularPlace(double, double) in popularplace.o
"sim::PopularPlace::places", referenced from:
sim::Person::action() in person.o
sim::PopularPlace::PopularPlace() in popularplace.o
sim::PopularPlace::PopularPlace(double, double) in popularplace.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
When building this makefile:
main: main.cpp simulation.h location.o place.o popularplace.o person.o
g++ -o main main.cpp *.o
location.o: location.cpp location.hpp simulation.h
g++ -c location.cpp
place.o: place.hpp place.cpp
g++ -c place.cpp
popularplace.o: place.hpp place.cpp simulation.h popularplace.hpp popularplace.cpp
g++ -c popularplace.cpp
person.o: person.cpp person.hpp location.hpp simulation.h place.hpp place.cpp location.cpp popularplace.o
g++ -c person.cpp
clean:
rm *.o
I can't find the error. Here is the popularplace.cpp file:
#include "popularplace.hpp"
#include "simulation.h"
namespace sim{
PopularPlace::PopularPlace()
:open(true){
places[PopularPlace::arraycounter] = this;
PopularPlace::arraycounter++;
}
PopularPlace::PopularPlace(double x, double y)
:Place(x, y), open(true){
places[PopularPlace::arraycounter] = this;
PopularPlace::arraycounter++;
}
bool PopularPlace::isOpen() const{
return open;
}
void PopularPlace::close(int numOfCasesToReopen){
open = false;
}
bool PopularPlace::reopen(int activeCases){
if(activeCases <= numOfCasesToReopen){
open = true;
return true;
} else{
return false;
}
}
}
and here's the popularplace.hpp file:
#ifndef POPULAR_PLACE_HPP
#define POPULAR_PLACE_HPP
#include "simulation.h"
#include "place.hpp"
namespace sim{
class PopularPlace : public Place{
private:
bool open;
int numOfCasesToReopen;
static int arraycounter;
public:
static PopularPlace* places[POPULAR_PLACES];
PopularPlace();
PopularPlace(double x, double y);
bool isOpen() const;
void close(int numOfCasesToReopen);
bool reopen(int activeCases);
};
}
#endif
If you need me to provide additional information/code, I'd be happy to do so. Thanks.
Static variables need a definition; they are declared in the header but they should also be defined in the cpp file. This is also where you'd initialize them. For example:
int PopularPlace::arraycounter{0};
PopularPlace* PopularPlace::places[POPULAR_PLACES] = {};
However, you might consider using an std::vector<std::shared_ptr<PopularPlace>> instead of a manually-managed array.
The code examples explain the problem fairly straightforward:
Hash.h
#include <iostream>
#include <cstdint>
using namespace std;
class Hash {
public:
Hash(int64_t sz);
int64_t size;
};
Hash.cpp
#include "Hash.h"
using namespace std;
Hash::Hash(int64_t sz) : size(sz)
{
cout << "Hash int" << endl;
}
main.cpp
#include "Hash.h"
using namespace std;
int main(int argc, char *argv[])
{
Hash HashTable(12);
return 0;
}
And here is the version file, foo.map:
VER_0.1
{
global:
extern "C++" {
"Hash::Hash(int64_t)";
};
local:
*;
};
For the compilation:
$g++ -g -c -Wall -Werror -fpic Hash.cpp -std=c++0x
$g++ -shared -o Hash.so Hash.o -std=c++0x -Wl,--version-script=foo.map
$g++ -g -o prog Hash.so main.cpp -std=c++0x
The error message:
/tmp/ccd60Ulm.o: In function `main':
/remote/ltg_engine1_us03/liangwa/test/004/main.cpp:7: undefined reference to `Hash::Hash(long)'
collect2: error: ld returned 1 exit status
Then if I change all int64_t to int or long, it compiles fine. So anything special with int64_t? I am using g++ 7.3.0
i have this simple code in the following files:
Stat.h
#ifndef STAT_H
#define STAT_H
class Stat {
public:
void compute_value();
};
#endif
Stat.cpp
class Stat {
public:
void compute_value() {
}
};
main.cpp
#include "Stat.h"
int main(void)
{
Stat stat;
stat.compute_value();
}
When i try to compile i got the following error:
clang++ -std=c++14 -Wall -Wextra -pedantic -Weverything -O3 Stat.cpp main.cpp -o main
/tmp/main-0466d7.o: In function `main':
main.cpp:(.text+0xf6a): undefined reference to `Stat::compute_value()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
You are redefining the class in your Stat.cpp source file because definition is also a declaration. Instead of having the entire class redefinition you only need to define the member function(s) in your Stat.cpp source file and include the Stat.h header:
#include "Stat.h"
void Stat::compute_value() {}
i been having a problem that i tried for many days to fix but i cant find a solution for it.
I keep getting this Error:
undefined reference to 'Simulator::Simulator(int, int)'
undefined reference to 'Simulator::run();'
undefined reference to 'Simulator::~Simulator()'
undefined reference to 'Simulator::~Simulator()'
I searched for an answer but nothing seems to be working for me.
Here are my classes:
main.cpp:
#include <iostream>
#include <cstdlib>
#include "Simulator.h"
int main(int argc, char** argv) {
//Some code
Simulator sim(rows, cols);
sim.run();
}
Simulator.h:
#include <iostream>
#include "PersonQueue.h"
#include "DogQueue.h"
class Simulator {
void drawBoard();
DogQueue _dq;
PersonQueue _pq;
public:
int dog_num, person_num;//Number of entitys
int _rows, _cols;//Should be static but wont work.
void fill_queue();//check
void init_clrs();
Simulator(int rows, int cols);//check
void run();//check
~Simulator();
};
Simulator.cpp:
#ifndef SIM_C
#define SIM_C
#include <iostream>
#include <curses.h>
#include "Simulator.h"
int Simulator:: _rows;
int Simulator:: _cols;
Simulator::Simulator(int row, int col) {
_rows = row;
_cols = col;
dog_num = 2; //number of dog entitys
person_num = 2;//number of person entitys
}
void Simulator::init_clrs() {
//some code...
}
void Simulator::drawBoard() {
//some code...
}
void Simulator::fill_queue() {
//some code...
}
void Simulator::run() {
initscr();
start_color();
Simulator::init_clrs();
Simulator::fill_queue();
Simulator::drawBoard();
while (std::cin.get() != (char)27) {
Person* person_obj = _pq.dequeue();
Dog* dog_obj = _dq.dequeue();
person_obj->Person::advance();
dog_obj->Dog::advance();
if (dog_obj->steps == MAX_STEP && person_obj->steps) {
_dq.enqueue(dog_obj);
_pq.enqueue(person_obj);
}
refresh();
}
}
Simulator::~Simulator() {//To_be_changed
delete this;
}
#endif
From what i read i believe the problem may be with the makefile but it seems ok and works until i get the undefined error.
makefile just in case:
tester: main.o simulator.o personqueue.o dogqueue.o character.o person.o dog.o
g++ -Wall main.cpp -lncurses -o tester
main.o: main.cpp
g++ -c -Wall main.cpp -o main.o
simulator.o: Simulator.cpp Simulator.h
g++ -c -Wall Simulator.cpp Simulator.h -o simulator.o
character.o: Character.cpp Character.h
g++ -c -Wall Character.cpp Character.h -o character.o
person.o: Person.cpp Person.h
g++ -c -Wall Person.cpp Person.h -o person.o
dog.o: Dog.cpp Dog.h
g++ -c -Wall Dog.cpp Dog.h -o dog.o
personqueue.o: PersonQueue.cpp PersonQueue.h
g++ -c -Wall PersonQueue.cpp PersonQueue.h -o personqueue.o
dogqueue.o: DogQueue.cpp DogQueue.h
g++ -c -Wall DogQueue.cpp DogQueue.h -o dogqueue.o
clean:
rm -rf *.o tester
Thank you for any input on this issue.
EDIT:
I dont believe the problem is with DogQueue or Person queue as all they include is Dog.h Person.h
but anyways just to be sure:
#include "DogQueue.h"
#include <cstdlib>
//Some code...
#include "PersonQueue.h"
#include <cstdlib>
//some code...
i think you have issues in your make file,
tester: main.o simulator.o personqueue.o dogqueue.o character.o person.o dog.o
g++ -Wall main.cpp -lncurses -o tester
try something like this, though I have not tested the code,
tester: main.o simulator.o personqueue.o dogqueue.o character.o person.o dog.o
g++ -o tester main.o simulator.o personqueue.o dogqueue.o character.o person.o dog.o -lncurses
class.h
#include <iostream>
#include <stdint.h>
using namespace std;
template <typename T>
class CIntegerType {
public:
void Show ( void );
private:
T m_Data;
};
class.cpp
#include "class.h"
template <typename T>
void CIntegerType<T> :: Show ( void ) {
cout << m_Data << endl;
}
main.cpp
#include "class.h"
int main ( void ) {
CIntegerType<uint32_t> UINT32;
UINT32 . Show ();
return 0;
}
This commands return:
g++ -Wall -pedantic -c main.cpp
g++ -Wall -pedantic -c class.cpp
g++ -Wall -pedantic -o class.o main.o
main.o: In function `main':
main.cpp:(.text+0x11): undefined reference to 'CIntegerType< unsigned int>::Show()'
collect2: ld returned 1 exit status
Try putting your template implementation in the header file.
See: Why can templates only be implemented in the header file?
Try g++ -Wall -pedantic -o main.o class.o instead. You are facing the same problem as in this question: g++ linking order dependency when linking c code to c++ code
The linker searches for functions in the order they appear. Since you have a template function, its use in main must be fed to the linker prior to the actual code to instantiate it in class.