I'm starting a C++ OpenGL project, and I'm beginning with two .cpp files, Scene
and boilerplate
(with no .h files!). boilerplate
contains OpenGL procedures that simply setup the environment.
I thought I'd move them to this separate file to give myself more room in Scene
, but now that I've done so and attempted to #include
this file in Scene
, I'm getting 'duplicate symbol' errors when linking, e.g.
Scanning dependencies of target Coursework
[ 33%] Building CXX object CMakeFiles/Coursework.dir/Scene.cpp.o
[ 66%] Linking CXX executable Coursework
duplicate symbol __Z12checkGLErrorv in:
CMakeFiles/Coursework.dir/Scene.cpp.o
CMakeFiles/Coursework.dir/boilerplate.cpp.o
duplicate symbol __Z5setupv in:
CMakeFiles/Coursework.dir/Scene.cpp.o
CMakeFiles/Coursework.dir/boilerplate.cpp.o
duplicate symbol _height in:
CMakeFiles/Coursework.dir/Scene.cpp.o
CMakeFiles/Coursework.dir/boilerplate.cpp.o
...
Every 'duplicate symbol' comes from the definitions in boilerplate.cpp
.
Why am I getting these errors? I thought #include
ing is effectively the same as copy-and-pasting that file's code into the current file, yet when I actually do this it builds just fine.
I'm using CMake to build, in case this is relevant (it is a linking error so it could be to do with this?).
Here are the files for reference,
Scene.cpp:
#include <iostream>
#include <glut/glut.h>
#include "boilerplate.cpp"
void draw() {
glClearColor(0.2f, 0.2f, 0.2f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// make beautiful models
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
setup();
glutDisplayFunc(draw);
checkGLError();
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
boilerplate.cpp:
#include <glut/glut.h>
#include <cstdio>
int width, height;
void checkGLError() {
int e = 0;
GLenum error = glGetError();
while (GL_NO_ERROR != error) {
e++;
printf("GL Error %i: %s\n", e, gluErrorString(error));
error = glGetError();
}
}
void setup() {
width = 800;
height = 800;
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(width, height);
glutCreateWindow("Coursework");
}
void reshape(int _width, int _height) {
height = _height;
width = _width;
GLdouble aspect = static_cast<GLdouble>(width) / static_cast<GLdouble>(height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, aspect, 1, 1000);
glMatrixMode(GL_MODELVIEW);
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.9)
project(Coursework)
set(CMAKE_CXX_STANDARD 11)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
# Put directories in project's 'include path'
include_directories(${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS})
# Declare the var 'SOURCE_FILES', and give it all relevant source filenames
set(SOURCE_FILES Scene.cpp boilerplate.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES} ${GLUT_LIBRARY})