Reputation: 23
So I wrote a small set of logging functions in the file cerus.h
. The contents of that file can be seen below. It is being included in main.cpp
, model.cpp
, engine.cpp
and camera.cpp
. As can be seen, I have include guards so I'm not sure why I'm getting this error:
Output of $ make
jed@ArchPC:~/glPlayground$ make
g++ -std=c++11 -c model.cpp -o bin/model.o
g++ -std=c++11 -c tiny_obj_loader.cc -o bin/tinyobj.o
g++ -std=c++11 -c camera.cpp -o bin/camera.o
g++ -g -std=c++11 -o main bin/main.o bin/engine.o bin/tinyobj.o bin/model.o bin/camera.o -lGL -lGLU -lglut -lSOIL -lGLEW -lglfw
bin/engine.o: In function `LOG(char const*)':
engine.cpp:(.text+0x0): multiple definition of `LOG(char const*)'
bin/main.o:main.cpp:(.text+0x0): first defined here
bin/engine.o: In function `LOGERR(char const*)':
engine.cpp:(.text+0x3d): multiple definition of `LOGERR(char const*)'
bin/main.o:main.cpp:(.text+0x3d): first defined here
bin/model.o: In function `LOG(char const*)':
model.cpp:(.text+0x0): multiple definition of `LOG(char const*)'
bin/main.o:main.cpp:(.text+0x0): first defined here
bin/model.o: In function `LOGERR(char const*)':
model.cpp:(.text+0x3d): multiple definition of `LOGERR(char const*)'
bin/main.o:main.cpp:(.text+0x3d): first defined here
bin/camera.o: In function `LOG(char const*)':
camera.cpp:(.text+0x0): multiple definition of `LOG(char const*)'
bin/main.o:main.cpp:(.text+0x0): first defined here
bin/camera.o: In function `LOGERR(char const*)':
camera.cpp:(.text+0x3d): multiple definition of `LOGERR(char const*)'
bin/main.o:main.cpp:(.text+0x3d): first defined here
collect2: error: ld returned 1 exit status
Makefile:4: recipe for target 'main' failed
make: *** [main] Error 1
cerus.h
#ifndef CERUS_H
#define CERUS_H
#include <iostream>
//Need to add Windows and Mac Includes here
// Linux Include Statements
void LOG(const char* str){
std::cout << "[INFO]" << str << "\n";
}
void LOGERR(const char* str){
std::cout << "[ERROR]" << str << "\n";
}
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GLFW/glfw3.h>
#endif
Makefile
all: main
main: bin/main.o bin/engine.o bin/model.o bin/tinyobj.o bin/camera.o cerus.h
g++ -g -std=c++11 -o main bin/main.o bin/engine.o bin/tinyobj.o bin/model.o bin/camera.o -lGL -lGLU -lglut -lSOIL -lGLEW -lglfw
bin/main.o: main.cpp cerus.h
g++ -std=c++11 -c main.cpp -o bin/main.o
bin/engine.o: engine.cpp engine.h cerus.h
g++ -std=c++11 -c engine.cpp -o bin/engine.o
bin/tinyobj.o: tiny_obj_loader.cc tiny_obj_loader.h cerus.h
g++ -std=c++11 -c tiny_obj_loader.cc -o bin/tinyobj.o
bin/model.o: model.cpp model.h cerus.h
g++ -std=c++11 -c model.cpp -o bin/model.o
bin/camera.o: camera.cpp camera.h cerus.h
g++ -std=c++11 -c camera.cpp -o bin/camera.o
clean:
rm -f bin/*.o main
If someone could explain to me why my guard isn't catching this, I would greatly appreciate the help.
EDIT: Fixed this issue by adding a file called cerus.cpp
and defining my logging functions there instead of in cerus.h
Upvotes: 0
Views: 218
Reputation: 7788
Guards did nothing wrong, they just protect your declarations/inlines/templates. It's the definitions that are real issue. If you have inline functions in your cpp, put them in header, same for templates. Do not include cpp files. Can't see much of your code but that is most of the cases.
Upvotes: 0
Reputation: 75062
This type of guard is to avoid things from being declared or defined in same translation unit.
It won't have any effect for multiple definition in different translation units (i.e. multiple source files).
In this case, you should move the definitions of functions LOG
and LOGERR
to another .cpp file, and put declarations of the functions in the header file.
Upvotes: 2