mardi 11 février 2020

Using object files (undefined symbols for architecture)

I am writing a code for a long project that uses at least 15 headers. I'm a lover of inline definitions inside headers, but for such a long project I've run into some problems using this method, so I decided to write a header file .h with a .cpp file for the definitions. Since I'm kind of new to this method, I'm not sure how to write the makefile. I tried my luck but it keeps giving me the famous "Undefined symbols for architecture x86_64" error. What I think is that inside the makefile I should just compile using object files all those headers that use a partner .cpp file, and nothing for inline definitions (.h).. Is this thinking right? Is the following makefile alright or wrong?

Makefile

CC = gcc
G = g++
SDLFLAGS = -lSDL_image -lSDL_ttf -lSDL2
INCS= `sdl2-config --cflags --libs`

AssetManager.o: AssetManager.cpp
    ${CC} -std=c++17 -c AssetManager.cpp
Collision.o: Collision.cpp
    ${CC} -std=c++17 -c Collision.cpp
Game.o: Game.cpp
    ${CC} -std=c++17 -c Game.cpp
Map.o: Map.cpp
    ${CC} -std=c++17 -c Map.cpp
TextureManager.o: TextureManager.cpp
    ${CC} -std=c++17 -c TextureManager.cpp
ECS.o: ECS/ECS.cpp
    ${CC} -std=c++17 -c ECS/ECS.cpp

main: main.cpp *.o ECS/Animation.h ECS/ColliderComponent.h ECS/Components.h ECS/KeyboardController.h ECS/ProjectileComponent.h ECS/SpriteComponent.h ECS/TileComponent.h ECS/TransformComponent.h ECS/UILabel.h colors.h
    ${G} -std=c++17 main.cpp -o main *.o ${INCS} ${SDLFLAGS}

clean:
    rm *.o
cleanmain:
    rm main
edit:
    vim main.cpp

As I earlier anticipated all the commands using .o are for the headers that come with a .cpp file, all the inline headers .h are included in the line main: main.cpp *.o ECS/Animation.h ECS/ColliderComponent.h etc..


An example of an error it gives me is the following:

Undefined symbols for architecture x86_64:
  "Vector2D::Zero()", referenced from:
      TransformComponent::init() in AssetManager.o
      TransformComponent::TransformComponent() in AssetManager.o
      TransformComponent::init() in Game.o
      TransformComponent::TransformComponent() in Game.o
      TransformComponent::TransformComponent() in Map.o
      TransformComponent::init() in Map.o
  "Vector2D::Vector2D(float, float)", referenced from:
      Game::init(char const*, int, int, bool) in Game.o
  "Vector2D::Vector2D()", referenced from:
      TransformComponent::TransformComponent(float, float, int, int, int) in AssetManager.o
      TransformComponent::TransformComponent() in AssetManager.o
      TransformComponent::TransformComponent(float, float, int, int, int) in Game.o
      TransformComponent::TransformComponent() in Game.o
      TransformComponent::TransformComponent() in Map.o
      TileComponent::TileComponent(int, int, int, int, int, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in Map.o
  "operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Vector2D const&)", referenced from:
      Game::update() in Game.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

where TransformComponent is actually just a .h header... Where am I going wrong?

Aucun commentaire:

Enregistrer un commentaire