You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下MinGW编译GLFW+GLEW项目报未定义引用错误

Windows下MinGW编译GLFW+GLEW项目undefined reference问题解决

问题背景

我正在使用GLFW和GLEW搭建OpenGL开发环境,以下是项目源代码:

#define GLFW_INCLUDE_GLU
#ifdef _WIN32
    #define GLFW_DLL // -> windows
    #include <GL/glew.h>
#elif __linux__
    #include <GL/glew.h>
#endif

#include <GLFW/glfw3.h>
#include <iostream>
#include <stdexcept>

GLFWwindow* window = NULL;
GLFWmonitor* monitor = NULL;

int window_width = 800;
int window_height = 600;

static void window_hints() {
    const GLFWvidmode* mode = glfwGetVideoMode(monitor);

    glfwWindowHint(GLFW_RED_BITS, mode->redBits);
    glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
    glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
    glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);

    glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
}

static void set_window_callbacks() {
    glfwSetWindowCloseCallback(window, [] (GLFWwindow *window) {
        std::cout << "closing window!";
    });
    glfwSetKeyCallback(window, [] (GLFWwindow *window, int key,int scancode, int action, int mods) {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
            glfwSetWindowShouldClose(window, GLFW_TRUE);
        }
    });
    glfwSetWindowSizeCallback(window, [] (GLFWwindow *window, int width, int height) {
        glViewport(0, 0, width, height);
        window_width = width;
        window_height = height;
        glLoadIdentity();
        GLdouble aspect = (GLdouble)window_width / window_height;
        glOrtho(-1, 1, -1 / aspect, 1 / aspect, 0.01, 10000);
        glTranslatef(0, 0, -10);
    });
}

void GLAPIENTRY
MessageCallback( GLenum source,
                 GLenum type,
                 GLuint id,
                 GLenum severity,
                 GLsizei length,
                 const GLchar* message,
                 const void* userParam )
{
  fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
           ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
            type, severity, message );
}

int main(int argc, char *argv[])
{

    glfwSetErrorCallback([] (int code, const char * err_msg) {
        std::cerr << "GLFW Error " << code << ": \n\t" << err_msg << std::endl;
    });

    if(!glfwInit())
        throw std::runtime_error("glfwInit failed");

    monitor = glfwGetPrimaryMonitor();
    window_hints();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);

    window = glfwCreateWindow(window_width, window_height, "test window", NULL, NULL);

    if(!window)
        throw std::runtime_error("glfwOpenWindow failed.");

    set_window_callbacks();

    // GLFW settings
    glfwMakeContextCurrent(window);
    glewInit(); 

    glfwSwapInterval(1);

    std::cout << glGetString(GL_VERSION) << std::endl;
    
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
    glDebugMessageCallback(MessageCallback, 0);

    glMatrixMode(GL_PROJECTION);

    glViewport(0, 0, window_width, window_height);
    glLoadIdentity();
    GLdouble aspect = (GLdouble)window_width / window_height;
    glOrtho(-1, 1, -1 / aspect, 1 / aspect, 0.01, 10000);
    glTranslatef(0, 0, -10);    


    while(!glfwWindowShouldClose(window))
    {
        // process pending events
        glfwPollEvents();
        glClearColor(0, 0, 0, 1); // black
        glClear(GL_COLOR_BUFFER_BIT);

        //glRotatef(1, 0, 0, 0.1);

        glBegin(GL_TRIANGLES);

        glColor3f(1.0, 0.0, 0.0);
        glVertex2f(-0.5, -0.5);

        glColor3f(0.0, 1.0, 0.0);
        glVertex2f( 0.5, -0.5);

        glColor3f(0.0, 0.0, 1.0);
        glVertex2f( 0.0,  0.5);

        glEnd();

        glfwSwapBuffers(window);
    }

    // clean up and exit
    glfwTerminate();
    std::cerr << std::endl;
    return 0;
}

Linux系统下使用如下Makefile可正常运行:

main: main.cpp makefile
    g++ main.cpp -g -o main -lglfw -lGL -lX11 -lGLEW -std=c++2a

Windows下编译故障描述

尝试适配Windows平台时使用如下Makefile:

main.exe: main.cpp makefile
    g++ main.cpp -g -o main.exe -I"D:\cpp_libraries\glfw-3.3.5.bin.WIN64\include" -I"D:\cpp_libraries\glew-2.1.0\include" -L"D:\cpp_libraries\glfw-3.3.5.bin.WIN64\lib-mingw-w64" -L"D:\cpp_libraries\glew-2.1.0\lib\Release\x64" -lglfw3dll -lglew32 -lopengl32

使用的glew-2.1.0和glfw-3.3.5.bin.WIN64均为官网下载的Windows预编译二进制包,已将存放glew32.dll和glfw3.dll的目录添加到系统Path环境变量。
编译时g++对所有glew、glfw函数调用均返回undefined reference错误,GL相关函数可正常链接。已尝试以下操作均未解决:

  • 将dll文件放入项目目录
  • 将链接参数从-lglfw3dll改为-lglfw
  • 从源码编译GLFW,未找到网上提到的glfw3.lib文件

解决方案

1. 明确库格式差异

网上提到的glfw3.lib是MSVC编译器使用的导入库格式,MinGW使用的导入库后缀为.a/.dll.a,不需要查找.lib文件,源码编译GLFW生成的.a文件即可正常使用。

2. 修正头文件宏定义

GLEW默认按静态链接处理符号,动态链接时需要额外定义宏,修改头文件前的宏定义部分如下:

#define GLFW_INCLUDE_GLU
#ifdef _WIN32
    #define GLFW_DLL // 动态链接GLFW保留,静态链接删除
    #define GLEW_DLL // 新增:动态链接GLEW添加,静态链接替换为GLEW_STATIC
    #include <GL/glew.h>
#elif __linux__
    #include <GL/glew.h>
#endif

3. 补充系统依赖库

GLFW在Windows平台运行依赖gdi32、user32等系统库,需要在链接参数中补充:

main.exe: main.cpp makefile
    g++ main.cpp -g -o main.exe -I"D:\cpp_libraries\glfw-3.3.5.bin.WIN64\include" -I"D:\cpp_libraries\glew-2.1.0\include" -L"D:\cpp_libraries\glfw-3.3.5.bin.WIN64\lib-mingw-w64" -L"D:\cpp_libraries\glew-2.1.0\lib\Release\x64" -lglfw3dll -lglew32 -lopengl32 -lgdi32 -luser32 -lkernel32

如果使用静态版本的GLFW,将-lglfw3dll替换为-lglfw3即可。

4. 确认GLEW库兼容性

官方预编译的GLEW包默认提供MSVC版本的.lib文件,无法被MinGW识别。可下载MinGW版本的GLEW预编译包,或自行使用MinGW编译GLEW源码生成对应的.a格式导入库。

内容的提问来源于stack exchange,提问作者Boris Vassilev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:27:05