I'm attempting to learn OpenGL. I'm using Clion as an IDE, which uses a CMakeLists.txt file to organize/compile the project.
The compiler cannot find glClear for some reason:
Undefined symbols for architecture x86_64:
"_glClear", referenced from:
_main in main.cpp.o
"_glClearColor", referenced from:
_main in main.cpp.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[2]: *** [GraphicsPractice] Error 1
make[1]: *** [CMakeFiles/GraphicsPractice.dir/all] Error 2
make: *** [all] Error 2
I'm able to successfully link GLEW and GLFW, however, my code breaks when I call glClear(GL_COLOR_BUFFER_BIT). I'm not sure why. If anyone could help point me in the right direction, that would be great.
CMakeList.txt
cmake_minimum_required(VERSION 3.6)
project(GraphicsPractice)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES src/main.cpp)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory(deps/glfw)
find_package(OpenGl REQUIRED)
find_package(GLEW REQUIRED)
include_directories("deps/glfw/include/")
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} glfw glew)
main.cpp
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", 0, nullptr);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
while (!glfwWindowShouldClose(window)) {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
You need to link the OpenGL Libraries. Namely:
target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES} glfw glew etc...)
Related
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Linking GLEW with CMake
(6 answers)
Closed last month.
When I try to compile it, I get a strange error:
[domon#archlinux TileVox-engine]$ g++ -c engine_main.cpp
[domon#archlinux TileVox-engine]$ g++ engine_main.o -o game -L -lGL -lglfw -lGLEW -lglut -lGLU
/usr/bin/ld: engine_main.o: undefined reference to symbol 'glViewport'
/usr/bin/ld: /usr/lib/libGL.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Code:
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
using namespace std;
int window_width = 1280;
int window_height = 720;
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(window_width, window_height, "TileVox-engine: Main scene", nullptr, nullptr);
if (window == nullptr){
cout << "TileVox-engine Error: failed to create OpenGL profile";
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK){
cout << "OpenGL Error: starting failed";
}
glViewport(0,0, window_width, window_height);
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
But there are no errors here, and I compiled and added the libraries correctly, what could be the problem?
I managed to get GLFW3 to work and properly display a window, however when i add glewInit() to my project it tells me undefined reference to glewInit'. I am using g++ as my compiler with -lglfw3 and lGl as flags. Below is a simple project to demonstrate my issue. I am on linux. Any help is much appreicated.
#include <GL/glew.h>
#include <GL/gl.h>
#include <GLFW/glfw3.h>
#include <iostream>
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main()
{
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfw window creation
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// here is the error, my glew is not intializing :(
if(glewInit() != GLEW_OK) {
return 0;
}
// render loop
while (!glfwWindowShouldClose(window))
{
// render
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
glfwSwapBuffers(window);
glfwPollEvents();
}
// glfw: terminate, clearing all previously allocated GLFW resources.
glfwTerminate();
return 0;
}
There is a standard way on Linux to get a correct set of libraries to link with your program - please look at man pkg-config. In your case you need to link everything, which is needed by both GLFW3 and GLEW - so you should call the pkg-config two times:
hekto#ubuntu:~$ pkg-config --libs glfw3
-lglfw
hekto#ubuntu:~$ pkg-config --libs glew
-lGLEW -lGLU -lGL
Therefore, you need to use -lglfw instead of -lglfw3 and add two more libraries - -lGLEW and -lGLU. These calls to the pkg-config tool can be directly added to your Makefile as well.
I've tried many ways to install OpenGL, using homebrew to install glfw and glew:
$ brew install glew glfw3
Or compile through source code:
$ cd glfw && cmake . && make && sudo make install
$ cd glew && make && sudo make install
Xcode is used to create the project. Opengl.framework, glut.framework, libglfw3. A and libglew. A are all added to the project. The header file path is / usr / local / include, and the library path is / usr / local / lib. Main.cpp source code:
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
void Render(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
{
glColor3f(1.0,0.0,0.0);
glVertex2f(0, .5);
glColor3f(0.0,1.0,0.0);
glVertex2f(-.5,-.5);
glColor3f(0.0, 0.0, 1.0);
glVertex2f(.5, -.5);
}
glEnd();
}
int main(void) {
GLFWwindow* win;
if(!glfwInit()){
return -1;
}
win = glfwCreateWindow(640, 480, "OpenGL Base Project", NULL, NULL);
if(!win)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
if(!glewInit())
{
return -1;
}
glfwMakeContextCurrent(win);
while(!glfwWindowShouldClose(win)){
Render();
glfwSwapBuffers(win);
glfwPollEvents();
}
glfwTerminate();
exit(EXIT_SUCCESS);
return 0;
}
Error in compilation:
Undefined symbols for architecture x86_64:
... (many can't find errors)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Can anyone help me?
I have tried several times in the past to write programs using OpenGL in C and C++ on several platforms, every time only to be stopped by the ridiculous dependency and linking issues that inevitably come up.
I am attempting to use GLFW with C++ on a linux system, building using CMake, with absolutely no success.
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project( GL_TEST_PROJECT )
find_package(OpenGL REQUIRED)
if(NOT OPENGL_FOUND)
message("ERROR: OpenGL not found")
endif(NOT OPENGL_FOUND)
set(GL_LIBRARY GL GLU X11)
add_executable(testgl testgl.cpp)
target_link_libraries(testgl glfw3 Xxf86vm pthread dl Xi Xcursor Xrandr X11 ${GL_LIBRARY} m)
testgl.cpp:
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(void)
{
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
while (!glfwWindowShouldClose(window))
{
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float) height;
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef((float) glfwGetTime() * 50.f, 0.f, 0.f, 1.f);
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-0.6f, -0.4f, 0.f);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(0.6f, -0.4f, 0.f);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(0.f, 0.6f, 0.f);
glEnd();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
make output:
Linking CXX executable testgl
//usr/local/lib/libglfw3.a(x11_init.c.o): In function `initExtensions':
x11_init.c:(.text+0x1b8b): undefined reference to `XineramaQueryExtension'
x11_init.c:(.text+0x1ba3): undefined reference to `XineramaIsActive'
//usr/local/lib/libglfw3.a(x11_monitor.c.o): In function `_glfwPlatformGetMonitors':
x11_monitor.c:(.text+0x672): undefined reference to `XineramaQueryScreens'
collect2: error: ld returned 1 exit status
make[2]: *** [testgl] Error 1
make[1]: *** [CMakeFiles/testgl.dir/all] Error 2
make: *** [all] Error 2
I have tried several different changes to the CMakeLists.txt file, including removing and adding different dependencies, but it seems that there is nowhere for me to go from here. What do I need to do to get this program to compile?
Using the
set(CMAKE_CXX_FLAGS ...)
Does not work for me, but adding them all into
set(GLFW_DEPS X11 Xrandr Xinerama Xxf86vm Xcursor GL dl pthread)
Does get things working.
So, my target_link_libraries looks like this
target_link_libraries( ${PROJECT_NAME} glfw3 ${GLFW_DEPS} ${GLEW_STATIC_LIBRARY} )
It is possible that I'm not using CMAKE_CXX_FLAGS correctly, but you should try just adding the libraries your self. Do be careful about it, their order is important and depending on which version of GLFW you're using they could be different.
That error your getting is strictly because your missing the Xinerama library.
There are two ways to not have to add those libraries manually:
Option 1 is to use GLFW_LIBRARIES which you would have to include glfw source into your project as stated here build with Cmake and GLFW source
Option 2 would be to use the help of find_package as described here: Build with installed GLFW binaries
It appears as though you have glfw installed on your machine so I would recommend option 2, in part because I have yet to get option 1 to work and I'm currently having to manually enter the libraries. This is because I don't want to have glfw installed on machine vs having it all contained in the project.
Add this to "target_link_libraries()":
glfw ${GLFW_LIBRARIES} ${X11_LIBRARIES}
And then add this somewhere above "include_directories" in your CMakeLists.txt file:
#########################################################
# FIND X11
#########################################################
find_package(X11 REQUIRED)
include_directories(${X11_INCLUDE_DIRS})
link_directories(${X11_LIBRARY_DIRS})
add_definitions(${X11_DEFINITIONS})
if(NOT X11_FOUND)
message(ERROR " X11 not found!")
endif(NOT X11_FOUND)
Edit #2: And try adding the following to your CMakeLists.txt
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread")
I'm trying to learn some OpenGL and immediately found out versions of OpenGL >3.2 were the more relevant ones to learn.
So I've set up my Mac OS X 10.10.3 with Xcode and command line tools to get some examples going.
But jebus this thing is being a pain in the butt.
The error I'm getting is.
Undefined symbols for architecture x86_64:
"LoadShaders(char const*, char const*)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
So I have the most recent version of GLFW GLEW cmake to get things going.
I add my header and library paths to the project.
Library Search Paths
/opt/X11/lib /usr/lib/ /Users/mac/Dev/workspace/C++/Test/glfw/build/src/Debug /Users/mac/Dev/workspace/C++/Test/glew/lib
I add the last two directories just to double up on the directory
Header Search Path look similar with include instead of lib
my linkers are vast (from trying random things)
-framework OpenGl -lGLUT -lglew -lglfw -lGL -lGLU -lXmu -lXi -lXext -lX11 -lXt
and I've linked the Binaries with the Libraries as well. Where am I going wrong??
my GPU is the Intel HD 4000 and appears to support up to OpenGL4.1.
Do I need to add compiler flags? Is this just not plausible?
Here's the tutorial code that I'm trying to run.
#include <stdio.h>
#include <stdlib.h>
//GLEW
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLUT/glut.h>
//GLFW
#include <GLFW/glfw3.h>
#include <AGL/glm.h>
GLFWwindow* window;
//no real explanation of what this is.....
#include <common/shader.hpp>
//MAIN FUNCTION
int main(int argc, char *argv[])
{
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;
}
// specify GL information
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // We want 4.1>= OpenGL_version >=3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL
// Open a window and create its OpenGL context
window = glfwCreateWindow( 600, 375, "Tutorial 02", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental=true; // Needed in core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
// Create Vertex Array Object.
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
do{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT );
// Use our Shader
glUseProgram(programID);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// glVertexAttribPointer(
// Atrribute,
// size,
// type,
// normalized,
// stride,
// array buffer offset
// );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
// Draw the triangle
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteVertexArrays(1, &VertexArrayID);
glDeleteProgram(programID);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
I mostly followed this guideline here
Oscar Chavez, Setup instructions
The function LoadShaders() is not part of OpenGL, and it is not part of any of the libraries you are using (I see GLEW and GLFW). In short, LoadShaders() is missing.
My guess is that LoadShaders() is a function that the author of the tutorial wrote, but the formatting for the tutorial is a bit frustrating (to say the least!) so I'm not sure.
//no real explanation of what this is.....
#include <common/shader.hpp>
Probably something the author of that tutorial wrote himself and simply dumped into the project sources, without telling anything more. The most annoying part about this lines is the use of wedge brackets (<…>) instead of quotes ("…") because this misleadingly suggests that the header is part of the system libraries and not something local to the project. Somwehere there likely is a common/shader.cpp and therein will probably be a function LoadShaders. It is this very function, that is something completely custom, not something part of OpenGL or any of the helper libraries, which your linker is telling you to be amiss.