GLEW Linking Problem (C++)

Hi!
I’ve got a linker problem (or that’s what I think it is) and don’t know whats wrong with my configuration in CodeBlocks and Visual Studio 2010.
Under Build Options the following libs are listed:
glew32.lib
glew32mx.lib
glew32mxs.lib
glew32s.lib
libfreeglut.a
libfreeglut_static.a

such as

-lOpengl32

As Linker-Option…

The Code (Tutorial from OpenGLbooks.com, with german comments ^^):


#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define WINDOW_TITLE_PREFIX "Chapter 2"

int CurrentWidth = 800,
    CurrentHeight = 600,
    WindowHandle = 0;
unsigned FrameCount = 0;
GLuint      VertexShaderId,
            FragmentShaderId,
            ProgramId,
            VaoId,
            VboId,
            ColorBufferId;
const GLchar* VertexShader =
{
    "#version 400
"\

    "layout(location=0) in vec4 in_Position;
"\
    "layout(location=1) in vec4 in_Color;
"\
    "out vec4 ex_Color;
"\

    "void main(void)
"\
    "{
"\
    "   gl_Position = in_Position;
"\
    "   ex_Color = in_Color;
"\
    "}
"
};

const GLchar* FragmentShader =
{
    "#version 400
"\
    "in vec4 ex_Color;
"\
    "out vec4 out_Color;
"\

    "void main(void)
"\
    "{
"\
    "   out_Color = ex_Color;
"\
    "}
"
};



void Initialize(int, char*[]);
void InitWindow(int, char*[]);
void ResizeFunction(int, int);
void RenderFunction(void);
void TimerFunction(int);
void IdleFunction(void);
void Cleanup(void);
void CreateVBO(void);
void DestroyVBO(void);
void CreateShaders(void);
void DestroyShaders(void);

int main(int argc, char* argv[])
{
/*Ruft Initialize mit den von Windows übergebenen Parametern auf*/
    Initialize(argc, argv);

    glutMainLoop();

    exit(EXIT_SUCCESS);
}

void Initialize(int argc, char* argv[])
{   /*Erstellt GLEW-Variable zur Überprüfung der Initialisierung*/
    GLenum GlewInitResult;
    /*Ruft InitWindow-Funktion mit den Windows-Parametern auf*/
    InitWindow(argc, argv);
    GlewInitResult = glewInit();

    if (GLEW_OK != GlewInitResult)
    {
        std::cout<<"ERROR:"<<glewGetErrorString(GlewInitResult)<<std::endl;
        exit(EXIT_FAILURE);
    }

    std::cout<<"INFO: OpenGL Version:"<<glGetString(GL_VERSION)<<std::endl;
    CreateShaders();
    CreateVBO();
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}

void InitWindow(int argc, char* argv[])
{/*Initialisiert GLUT*/
    glutInit(&argc, argv);
/*Initialisiert GLUT auf OpenGL 4.0*/
    glutInitContextVersion(4, 0);
/*Initialisiert GLUT mit dem Flag Vorwärts-Kompatibel*/
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
/*Setzt das GLUT-Profil auf GLUT_CORE_PROFILE*/
    glutInitContextProfile(GLUT_CORE_PROFILE);
/*Optionen sorgen dafür, dass sich GlutMainLoop selbst wiederholt bis das Fenster schließt*/
    glutSetOption(
        GLUT_ACTION_ON_WINDOW_CLOSE,
        GLUT_ACTION_GLUTMAINLOOP_RETURNS
    );
/*Initialisiert das Fenster mit der gewünschten Größe*/
    glutInitWindowSize(CurrentWidth, CurrentHeight);
/*Aktiviert Z-Buffer, Double-Buffer und die RED-GREEN-BLUE-ALPHA Farbpalette*/
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
/*Übergibt Ergebnis der Fenster-Erstellung (Fenster-Titel) an WindowHandle*/
    WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
/*Falls Fenster-Erstellung fehl schlägt, wird das Programm beendet*/
    if(WindowHandle < 1) {
        std::cout<<"ERROR: Could not create a new rendering window."<<std::endl;
        exit(EXIT_FAILURE);
    }

    glutReshapeFunc(ResizeFunction);
    glutDisplayFunc(RenderFunction);
    glutIdleFunc(IdleFunction);
    glutTimerFunc(0, TimerFunction, 0);
    glutCloseFunc(Cleanup);
}

void ResizeFunction(int Width, int Height)
{
    CurrentWidth = Width;
    CurrentHeight = Height;
    glViewport(0, 0, CurrentWidth, CurrentHeight);
}

void RenderFunction(void)
{   ++FrameCount;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    glutSwapBuffers();
    glutPostRedisplay();
}

void IdleFunction(void)
{
    glutPostRedisplay();
}
/*TIMER-FUNKTION ZUM MESSEN DER FPS*/
void TimerFunction(int Value)
{
    if (0 != Value) {
        char* TempString = (char*)
            malloc(512 + strlen(WINDOW_TITLE_PREFIX));
/*KONSOLEN-AUSGABE DER FRAMES*/
        std::cout<<TempString<<WINDOW_TITLE_PREFIX<<": "<<FrameCount * 10<<" Frames Per Second @ "<<CurrentWidth<<" x "<<CurrentHeight<<std::endl;
/*FENSTER-HEADER-AUSGABE DER FPS
Speichert Text im Pointer TempString*/
        sprintf(TempString,"%s: %d Frames Per Second @ %d x %d",WINDOW_TITLE_PREFIX,FrameCount * 10,CurrentWidth,CurrentHeight);
/*Schreibt TempString ins Fenster*/
        glutSetWindowTitle(TempString);
        free(TempString);
    }
/*Frame-Zähler wieder auf 0 setzen*/
    FrameCount = 0;
/*Funktion ruft sich selbst mit 100ms Verzögerung auf und übergibt Wert 1 an TimerFunction*/
    glutTimerFunc(100, TimerFunction, 1);
}

void Cleanup(void)
{
    DestroyShaders();
    DestroyVBO();
}

void CreateVBO(void)
{
    GLfloat Vertices[] = {
        -0.8f, -0.8f, 0.0f, 1.0f,
         0.0f,  0.8f, 0.0f, 1.0f,
         0.8f, -0.8f, 0.0f, 1.0f
    };

    GLfloat Colors[] = {
        1.0f, 0.0f, 0.0f, 1.0f,
        0.0f, 1.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f, 1.0f
    };
    GLenum ErrorCheckValue = glGetError();

    glGenVertexArrays(1, &VaoId);
    glBindVertexArray(VaoId);
    glGenBuffers(1, &VboId);
    glBindBuffer(GL_ARRAY_BUFFER, VboId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    glGenBuffers(1, &ColorBufferId);
    glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(1);

    ErrorCheckValue = glGetError();
    if (ErrorCheckValue != GL_NO_ERROR)
    {
        fprintf(
            stderr,
            "ERROR: Could not create a VBO: %s 
",
            gluErrorString(ErrorCheckValue)
        );

        exit(-1);
    }
 }

void DestroyVBO(void)
{
    GLenum ErrorCheckValue = glGetError();

    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glDeleteBuffers(1, &ColorBufferId);
    glDeleteBuffers(1, &VboId);

    glBindVertexArray(0);
    glDeleteVertexArrays(1, &VaoId);

    ErrorCheckValue = glGetError();
    if (ErrorCheckValue != GL_NO_ERROR)
    {
        fprintf(
            stderr,
            "ERROR: Could not destroy the VBO: %s 
",
            gluErrorString(ErrorCheckValue)
        );

        exit(-1);
    }
}

void CreateShaders(void)
{
    GLenum ErrorCheckValue = glGetError();

    VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
    glCompileShader(VertexShaderId);

    FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
    glCompileShader(FragmentShaderId);
    ProgramId = glCreateProgram();
        glAttachShader(ProgramId, VertexShaderId);
        glAttachShader(ProgramId, FragmentShaderId);
    glLinkProgram(ProgramId);
    glUseProgram(ProgramId);

    ErrorCheckValue = glGetError();
    if (ErrorCheckValue != GL_NO_ERROR)
    {
        fprintf(
            stderr,
            "ERROR: Could not create the shaders: %s 
",
            gluErrorString(ErrorCheckValue)
        );

        exit(-1);
    }
}

void DestroyShaders(void)
{
    GLenum ErrorCheckValue = glGetError();

    glUseProgram(0);

    glDetachShader(ProgramId, VertexShaderId);
    glDetachShader(ProgramId, FragmentShaderId);

    glDeleteShader(FragmentShaderId);
    glDeleteShader(VertexShaderId);

    glDeleteProgram(ProgramId);

    ErrorCheckValue = glGetError();
    if (ErrorCheckValue != GL_NO_ERROR)
    {
        fprintf(
            stderr,
            "ERROR: Could not destroy the shaders: %s 
",
            gluErrorString(ErrorCheckValue)
        );

        exit(-1);
    }
}


And here are the error messages…


...\GL\freeglut_std.h|60|warning: "NOMINMAX" redefined|
..\lib\gcc\mingw32\4.4.1\include\c++\mingw32\bits\os_defines.h|46|warning: this is the location of the previous definition|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewUseProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDetachShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDeleteShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDeleteProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `gluErrorString@4'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewCreateShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewShaderSource'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewCompileShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewCreateProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewAttachShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewLinkProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewUseProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `gluErrorString@4'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDisableVertexAttribArray'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBindBuffer'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDeleteBuffers'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBindVertexArray'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDeleteVertexArrays'|
obj\Release\main.o:main.cpp|| undefined reference to `gluErrorString@4'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewGenVertexArrays'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBindVertexArray'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewGenBuffers'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBindBuffer'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBufferData'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewVertexAttribPointer'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewEnableVertexAttribArray'|
obj\Release\main.o:main.cpp|| undefined reference to `gluErrorString@4'|
||=== Build finished: 27 errors, 2 warnings ===|

Should be allright after all I see.
Used the freeglut-VC++ builds for VC++, the MingW Builds for Codeblocks. The Error-Messages are the same, am I missing a lib?
Hope someone of you could help me out!

You need to link against OpenGL32.lib, glew32.lib and GLU32.lib.

Tried to link against with -lGLEW and -lOpengl32, OpenGL works, but -lGLEW gets an error. The same project compiles without the shader-funtions (Tutorial 1). How do I link properly against under Windows?
EDIT:

Found out that I’ve to use #define GLEW_STATIC before the include of GLEW. This fixed 17 errors.
Now there are ten left:

D:\Eigene Dateien\Uni\Programmieren\Includes\freeglut-MinGW-2.6.0-3.mp\freeglut\include\GL\freeglut_std.h|60|warning: "NOMINMAX" redefined|
d:\programme\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\mingw32\bits\os_defines.h|46|warning: this is the location of the previous definition|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32.lib(glew32.dll)|| first defined here|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32.lib(glew32.dll)|| first defined here|
||Warning: .drectve `/DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32s.lib(.\static\release\glew.obj):(.text[__glewInit_GL_VERSION_1_2]+0x4)||undefined reference to `_imp__wglGetProcAddress@4'|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32s.lib(.\static\release\glew.obj):(.text[__glewInit_GL_VERSION_1_3]+0x4)||undefined reference to `_imp__wglGetProcAddress@4'|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32s.lib(.\static\release\glew.obj):(.text[__glewInit_GL_VERSION_1_4]+0x4)||undefined reference to `_imp__wglGetProcAddress@4'|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32s.lib(.\static\release\glew.obj):(.text[__glewInit_GL_VERSION_1_5]+0x4)||undefined reference to `_imp__wglGetProcAddress@4'|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32s.lib(.\static\release\glew.obj):(.text[__glewInit_GL_VERSION_2_0]+0x4)||undefined reference to `_imp__wglGetProcAddress@4'|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32s.lib(.\static\release\glew.obj):(.text[_wglewGetExtension]+0x1b)||undefined reference to `_imp__wglGetCurrentDC@0'|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32s.lib(.\static\release\glew.obj):(.text[_wglewContextInit]+0x4)||undefined reference to `_imp__wglGetProcAddress@4'|
D:\Eigene Dateien\Uni\Programmieren\Includes\glew-1.7.0\lib\glew32s.lib(.\static\release\glew.obj):(.text[_wglewContextInit]+0x3e)||undefined reference to `_imp__wglGetCurrentDC@0'|
||=== Build finished: 10 errors, 3 warnings ===|

Yeah, because the lib isn’t libglew, it’s glew32.lib. Therefore you need to link against glew32.lib! From the user’s standpoint it doesn’t matter if you link statically or dynamically, you always link against glew32.lib. All you need to know if your lib is for exporting DLL functions or is really a static library which only bundles object code.

So against what should I link?
At the moment it’s

-lglu32
-lopengl32
-glew32

And where can I read how I exactly link against a special lib?
Is it like -lnameofthelib ?
Sorry, maybe a little newbie-question ^^
Ah and btw, what does the

..\glew32.lib(glew32.dll)|| first defined here|

exactly mean? :slight_smile:

EDIT:
Dropped glew32.lib out of the VC-Project and with the glew32s.lib it compiles. So I think, the wrong header at the wrong time.
So I just need to know why it doesn’t work under CodeBlocks, maybe because of MingW and GLEW? >.<

For followers (every thread deserves an update once/decade, right?) I think the problem/fix is to link opengl32 “after” glew, so -lglew32 -lopengl32 FWIW (mingw anyway)