0

so I'm getting this error undefined reference to 'Player::Player(World*, Camera*)' and occasionally undefined reference to vtable, depending on some slight changes. I've looked around and seen posts such as Undefined reference to vtable about similar issues, and the answer seems to be to ensure that all virtual functions in the base class are defined or are pure virtual.

As far as I can tell this is the case, I've tried a bunch of different configurations but always get one of the two errors. Code is below:

#ifndef PHYSICSOBJECT_H
#define PHYSICSOBJECT_H

#include <glm/glm.hpp>

#include <array>

class PhysicsObject {
  public:
    glm::vec3 d_acc = {0,0,0};
    glm::vec3 d_vel = {0,0,0};
    glm::vec3 d_pos = {0,50,0};

    //An axis aligned bounding box
    std::array<glm::vec3, 8> d_AABB;

    PhysicsObject();
    virtual ~PhysicsObject();
    virtual void physicsUpdate();
    //virtual void setVel(const glm::vec3& vel) = 0;
    //virtual void setPos(const glm::vec3& pos) = 0;

};

#endif
#include "PhysicsObject.hpp"

PhysicsObject::PhysicsObject(){
}
PhysicsObject::~PhysicsObject(){

}

void PhysicsObject::physicsUpdate(){

}
#include "PhysicsObject.hpp"

class World;
class Camera;

class Player : public PhysicsObject {
  private:
    World* d_world;
    Camera* d_camera;
    std::mutex d_player_mtx;

  public:
    //Player() = default;
    Player(World* world, Camera* camera);
    ~Player() = default;
    void syncCamera();
    void syncAABB();
    void incX(float x);
    void incY(float y);
    void incZ(float z);
    bool willCollide();

    void physicsUpdate() override;
    void setAcc(const glm::vec3& acc)/*override*/;
    void setPos(const glm::vec3& pos) ;
    //void setVel(const glm::vec3& vel) override;
    void incVel(const glm::vec3& vel)/*override*/;
};

edit: attempt at a minimal reproducible example compiled soooo leading me to think theres something funky in my cmake

cmakelist for this folder

cmake_minimum_required(VERSION 2.8)

project(input)

file(GLOB_RECURSE playercpps CONFIGURE_DEPENDS "*.cpp")
file(GLOB_RECURSE playerhpps CONFIGURE_DEPENDS "*.hpp")

add_library(playerlib STATIC ${playercpps})

install(TARGETS playerlib DESTINATION lib)

install(FILES ${playerhpps} DESTINATION include)

top level cmakelist

cmake_minimum_required(VERSION 2.8)

project(game)

find_package(Freetype REQUIRED)
include_directories(${FREETYPE_INCLUDE_DIRS})

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_compile_options(-Wall -Wextra -pedantic --std=c++17 -lstdc++fs -Wno-unused-parameter -g)

add_subdirectory(Managers)
add_subdirectory(Core)
add_subdirectory(Rendering)
add_subdirectory(Input)

add_executable(game main.cpp)

target_link_libraries(game init playerlib managerlib renderinglib)

find_library(GLUT glut)
find_library(OPENGL GL)
find_library(GLEW GLEW)
find_library(MATH m)
find_library(PTHREAD pthread)


target_link_libraries(game ${PTHREAD} ${GLUT} ${OPENGL} ${GLEW} ${MATH} ${FREETYPE_LIBRARIES})

add_definitions(${GCC_FLAGS})

install(TARGETS game DESTINATION bin)

also heres some of the nm output for the lib player ends up in

00000000000006ba T Player::syncCamera()
000000000000079c T Player::willCollide()
0000000000000868 T Player::physicsUpdate()
00000000000006fa T Player::incX(float)
0000000000000730 T Player::incY(float)
0000000000000766 T Player::incZ(float)
0000000000000a96 T Player::incVel(glm::vec<3, float, (glm::qualifier)0> const&)
0000000000000a3e T Player::setAcc(glm::vec<3, float, (glm::qualifier)0> const&)
0000000000000a62 T Player::setPos(glm::vec<3, float, (glm::qualifier)0> const&)
00000000000000ae T Player::syncAABB()
0000000000000000 T Player::Player(World*, Camera*)
0000000000000000 T Player::Player(World*, Camera*)
0000000000000000 W Player::~Player()
0000000000000000 W Player::~Player()
0000000000000000 W Player::~Player()
0000000000000000 n Player::~Player()
JaMiT
  • 14,422
  • 4
  • 15
  • 31
Jordan
  • 21
  • 5
  • How do you build your project? Are you sure that you include *all* source files when building? – Some programmer dude Feb 15 '21 at 05:17
  • 4
    Indeed, there is no implementation for `Player::Player(World*, Camera*)` in the code shown. – Igor Tandetnik Feb 15 '21 at 05:20
  • ah yeah i just didnt include the cpp since its big, the ctor is definitely defined though. I'm building with cmake which im definitely not an expert at but it builds when i remove the virtual functions so it must be linking, one thing i noticed when inspecting the physicsobject.o file with nm is that the constructor and vtable both show as 0000000000, not quite clear what that output means though – Jordan Feb 15 '21 at 05:25
  • 1
    Please try to create a [mcve] to show us, and also include the `CMakeLists.txt` file you use. – Some programmer dude Feb 15 '21 at 05:29
  • *" i just didnt include the cpp since its big"* -- a good start. Next, make the .cpp file not big. Start by simplifying your headers. Trim `PhysicsObject` down to `class PhysicsObject { public: PhysicsObject(); virtual ~PhysicsObject(); virtual void physicsUpdate(); };` and make whatever code changes that necessitates. Still get the error? If so, keep moving down the chain. I would expect the definition of `Player` in your [mre] to look more like `class Player : public PhysicsObject { public: Player(World* world, Camera* camera); ~Player() = default; void physicsUpdate() override; };` – JaMiT Feb 15 '21 at 05:50
  • ok so messing around a bit more seems like the error only seems to occur if i declare a player in a different subdirectory/cmakelist directory? – Jordan Feb 15 '21 at 06:07
  • "the error only seems to occur if i declare a player in a different subdirectory/cmakelist directory?" - It is irrelevant which directory contains a source file. Just make sure that this source file is added to `add_library` call. – Tsyvarev Feb 15 '21 at 08:39
  • Are there multiple versions of the header file? Also where's the header guard/pragma once for `Player.h`(pp)? – fabian Feb 15 '21 at 19:30
  • Is the build process trying to link each subdirectory independently? (It might be better to describe that as "different library" than "different subdirectory".) That could put you in the realm of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – JaMiT Feb 20 '21 at 16:13

0 Answers0