Search code examples
opengllinkerqt-creatorqmakeglew

glew linking problems qt creator qmake


I am trying to get a project working with SDL2, assimp, opengl, and glew and cannot get glew to link properly (almost a duplicate but a more comprehensive question and answer, I think).

My qmake .pro file :

CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt

HEADERS += \
    objloader.h \
    display.h \
    eventloop.h \
    shader.h \
    texture.h

SOURCES += main.cpp \
    objloader.cpp \
    display.cpp \
    eventloop.cpp \
    shader.cpp \
    texture.cpp


INCLUDEPATH +=  "C:/code middleware/glew-1.12.0/include/" \
                "C:\code middleware\glm\\" \
                 "C:\code middleware\SDL2-2.0.3\include\\" \
                "C:\Users\smart_000\Desktop\assimp\include\\"

DEPENDPATH += "C:/code middleware/glew-1.10.0/bin/Release\Win32/" \
                "C:\code middleware\SDL2-2.0.3\lib/x86/" \
                "C:/Users/smart_000/Desktop/assimp/bin/" \
                "C:/code middleware/glew-1.12.0/lib/Release/Win32/" \
                "C:/code middleware/glew-1.12.0/bin/Release/Win32/"

LIBS += -L"C:\code middleware\SDL2-2.0.3\lib\x86" -lSDL2main -lSDL2
LIBS += -L"C:/Users/smart_000/Desktop/assimp/lib/" -lassimp.dll -lzlib
LIBS += -lopengl32
LIBS += -lglu32
LIBS += -L"C:/code middleware/glew-1.12.0/lib/Release/Win32/" -lglew32 -lglu32

The linker errors I am getting: linker errors

What I have tried already:

  • Checking file path problems ('/' and '\' kind of stuff and spaces in file names etc.)
  • Linking dynamically and statically (Yes, I defined GLEW_STATIC where I needed to, and I linked to -lglew32s and such)
  • SDL stuff: messing with and defining 'NO_SDL_GLEXT' above it
  • Making test programs and trying to link it with just g++ (I used the -static flag where I should have when I tried the static one and placed the linker flags after the files that needed them). These errors were the same as the qt ones minus the warnings.

  • Putting the glew source code directly in my project and building it (exact same errors) --- The issues were eerily similar and made no sense to me. I had commented out the qmake stuff and re ran qmake; I wasn't aware I could get linker errors like that if I put it in my project like I did.

  • Running qmake after my changes, lol
  • Moving 'LIBS' and 'DEPENDPATH' around and added 'CONFIG += opengl' in desperation
  • Messing with debug and release builds.

What I haven't tried:

  • Moving libraries and things to the system path
  • MAKING SURE THE LIBRARIES WERE BUILT FOR MINGW!

The relevant code(I know it's terrible; I was just hacking around when I encountered these issues) :

"main.cpp" :

#include <GL/glew.h>
#include <iostream>
#include <SDL.h>
#include <objloader.h>
#include "display.h"
#include "eventloop.h"

Display* display = NULL;

void callback()
{
    std::cout << "yay" << std::endl;
    display->Swap();
}

int main(int argc, char* argv[])
{
    UShortVector indices;
    Vec3Vector vertices;
    Vec2Vector uvs;
    Vec3Vector normals;

    bool success = ObjLoader::loadObj("cube.obj", indices, vertices, uvs, normals);
    display = new Display();

    EventLoop eventLoop;
    eventLoop.SetLoopCallback(&callback);
    display->Create("yay");

    eventLoop.Start();

    return 0;
}

"display.h"

#ifndef DISPLAY_H
#define DISPLAY_H
#include <GL/glew.h>
#include <SDL.h>
#include <iostream>

class Display
{
public:
    Display();
    ~Display();

    void Create(const char* title);
    void Swap();

    SDL_Window* window_ = NULL;
    SDL_GLContext glContext_;
};

#endif // DISPLAY_H

"shader.h"

#ifndef SHADER_H
#define SHADER_H
#include <GL/glew.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <memory.h>

class Shader
{
public:
    GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path);
private:
    Shader();
    ~Shader();
};

#endif // SHADER_H

"shader.cpp"

#include "shader.h"

Shader::Shader()
{

}

Shader::~Shader()
{

}

GLuint Shader::LoadShaders(const char * vertexShaderPath, const char * fragmentShaderPath)
{
    FILE* vertexFile = fopen(vertexShaderPath, "r");
    FILE* fragmentFile = fopen(fragmentShaderPath, "r");

    if(!vertexFile || !fragmentFile)
    {
        if(!vertexFile)
        {
            perror("could not open the vertex shader file");
        }
        if(!fragmentFile)
        {
            perror("could not open the fragment shader file");
        }
    }

    GLuint programID = glCreateProgram();
    GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);

    const size_t MAX_LINE_LENGTH = 120;
    char line[MAX_LINE_LENGTH];

    std::vector<GLchar*> vertShaderSource;
    std::vector<GLchar*> fragmentShaderSource;

    while(fgets(line, MAX_LINE_LENGTH, vertexFile) != NULL)
    {
        vertShaderSource.push_back((GLchar*)line);
        memset((void*)line, '\0', sizeof(line));
    }

    while(fgets(line, MAX_LINE_LENGTH, fragmentFile) != NULL)
    {
        fragmentShaderSource.push_back((GLchar*)line);
        memset((void*)line, '\0', sizeof(line));
    }

    glShaderSource(vertShader, vertShaderSource.size(), (const GLchar**)&vertShaderSource, NULL);
    glShaderSource(fragShader, fragmentShaderSource.size(), (const GLchar**)&fragmentShaderSource, NULL);

    // doesn't do anything at the moment, I know. It should still compile though.
    return programID;
}

Solution

  • Right after I posted the question, I found the issue. Embarrassingly, it was an issue I have run into before with assimp (although I just now realized why re-building it with cmake worked).

    The hallmarks:

    • Weird linker errors with a library when you know the library is being found.
    • You primarily work on a windows system :)

    The solution:

    • Check the build kit that you are using with Qt creator Vs. the libs you are using.

      I was using the MINGW one only and my libs were compiled using the MSVC++ compiler

    • The libs you are looking for are .a files: specifically lib{name}.a . In this case, I was looking for libglew32.dll.a <- note the .dll in there for whether it is a dll import library or a static one like libglew32s.a <- note the s for static.

    • Where to go to get the rights libs :

      - Go here for building it: Building glew on windows with mingw.

      - Go here to download the pre-built one that I did (older version of glew): https://launchpad.net/glew-cmake/+milestone/1.10.0

      The Download link that I used: glew-gcc-1.10.0-win32.zip (md5) Glew-Cmake 1.10.0 Binaries (MinGW) <- I tried to post a picture, but apparently, I am not cool enough to do that yet.

    My updated and working qmake .pro file :

    TEMPLATE = app
    CONFIG += console
    CONFIG -= app_bundle
    CONFIG -= qt
    
    HEADERS += \
        objloader.h \
        display.h \
        eventloop.h \
        shader.h \
        texture.h
    
    SOURCES += main.cpp \
        objloader.cpp \
        display.cpp \
        eventloop.cpp \
        shader.cpp \
        texture.cpp
    
    
    INCLUDEPATH +=  "C:/code middleware/glew-gcc-1.10.0-win32/include/" \
                    "C:/code middleware/glm/" \
                    "C:/code middleware/SDL2-2.0.3/include/" \
                    "C:/Users/smart_000/Desktop/assimp/include/"
    
    DEPENDPATH +=   "C:/code middleware/SDL2-2.0.3/lib/x86/" \
                    "C:/Users/smart_000/Desktop/assimp/bin/" \
                    "C:/code middleware/glew-gcc-1.10.0-win32/lib/" \
                    "C:/code middleware/glew-gcc-1.10.0-win32/bin/"
    
    LIBS += -L"C:/code middleware/SDL2-2.0.3/lib/x86" -lSDL2main -lSDL2
    LIBS += -L"C:/Users/smart_000/Desktop/assimp/lib/" -lassimp.dll -lzlib
    LIBS += -L"C:/code middleware/glew-gcc-1.10.0-win32/lib/" -lglew32.dll
    LIBS += -lopengl32
    LIBS += -lglu32
    

    Note: Don't forget the .dll on the end of the libs (-lglew32.dll).

    - Happy Linking!