使用MinGW、freeglut和glew编译简单的静态OpenGL 4.0程序

5
问题在标题中,我将尝试在下面列出我已经尝试过的内容。
首先,在我的理解中,为了在Windows上使用OpenGL 4.0,必须扩展或绕过默认的Windows库,因为它只支持OpenGL 1.1。
因此,我们已经安装了MinGW在 C:/MinGW/。接下来,我通过从 项目网站 下载 tarball 来设置FreeGLUT。根据 说明 运行makefiles并编译,并在 ./configure 命令中添加一个小的附加项--prefix
./configure --prefix=/c/Users/Owner/root/
make all
make install 

现在我已经在/c/Users/Owner/root/lib//c/Users/Owner/root/include/等位置安装了freeglut。接下来是GLEW,据我所知,这是我的问题儿子。
项目网站直接下载1.7.0.zip链接)下载源代码文件。编译稍微有点复杂,我目前的方法是从Stack Overflow问题“使用mingw在Windows上构建glew”中得出的。以下是简略形式:
mkdir lib/
mkdir bin/
gcc -DGLEW_NO_GLU -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.o -c src/glew.c
gcc -shared -Wl,-soname,libglew32.dll -Wl,--out-implib,lib/libglew32.dll.a -o lib/glew32.dll src/glew.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
ar cr lib/libglew32.a src/glew.o
gcc -DGLEW_NO_GLU -DGLEW_MX -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.mx.o -c src/glew.c
gcc -shared -Wl,-soname,libglew32mx.dll -Wl,--out-implib,lib/libglew32mx.dll.a -o lib/glew32mx.dll src/glew.mx.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
ar cr lib/libglew32mx.a src/glew.mx.o

应该从“/path/to/glew-1.7.0/”的“根目录”运行。
现在,假设没有错误,库的设置“完成”,编译我的简单程序只需要这一行代码。
${G++}  -DFREEGLUT_STATIC -DGLEW_STATIC -m32 main.cpp -o main.exe -lfreeglut_static -lopengl32 -lwinmm -lgdi32 -lglew32  -I ${ROOTPATH}/include -L ${ROOTPATH}/lib --static

现在我们来分解一下这个问题,让我解释一下为什么我有各种“额外”的参数,并向您展示我已经遇到和解决的错误和问题。
  1. -DFREEGLUT_STATIC-lfreeglut_static 被用于替代普通的 -lfreeglut,因为我们想要一个静态构建。如果不这样做,将会出现与 freeglut 相关的链接器错误。
  2. 出于同样的原因,添加了 -DGLEW_STATIC
  3. 添加了 -lwinmm 来修复链接器错误:freeglut_init.c:(.text+0x5d9): undefined reference to '_timeBeginPeriod@4'
  4. 添加了 -lgdi32 来修复链接器错误:c:/Users/Owner/root//lib\libfreeglut_static.a(freeglut_init.o):freeglut_init.c:(.text+0x58c): undefined reference to '_GetDeviceCaps@8'

现在我被以下链接器错误难住了:

c:/Users/Owner/root//lib\libglew32.a(glew.o):glew.c:(.text+0x83e8): undefined reference to `_glGetString@4'
c:/Users/Owner/root//lib\libglew32.a(glew.o):glew.c:(.text+0xa1b2): undefined reference to `_glGetString@4'
c:/Users/Owner/root//lib\libglew32.a(glew.o):glew.c:(.text+0xa290): undefined reference to `_glGetString@4'

产生此错误的最小测试用例(main.cpp)如下。
#include <GL/glew.h>
#include <GL/freeglut.h>

int main(int argc, char **argv) {
  glEnableVertexAttribArray(0);
}

有什么想法?


2
尝试在编译程序的行末添加-lopengl32,看看是否有帮助。编辑:根据genpfault的说法,应该是-lfreeglut_static,我读得太快了。 - Jite
1
@Jite,这个方法可行!(在最小测试案例上)O.o 请将其作为答案,以便我可以点赞并接受它。我简直不敢相信我错过了一组GCC参数的组合,因为我已经尝试了大约12种不同的设置!如果您或其他人能够提供有关如何选择库顺序的信息,那就更好了,而不是随机尝试组合。 - nixeagle
很高兴它能运行!我认为其他人可能需要更深入地解释,但据我所知(如果我错了请纠正我),这是关于阴影效应的,例如如果你有两个库定义了同名函数,最后链接的那个库会覆盖之前的那个。 - Jite
2个回答

4
尝试在编译程序时在行末添加 -lopengl32,看看是否有帮助。

1

gcc 链接器选项中参数顺序很重要。

尝试这个:

${G++} -DFREEGLUT_STATIC -DGLEW_STATIC -m32 main.cpp -o main.exe -I ${ROOTPATH}/include -L ${ROOTPATH}/lib -lopengl32 -lwinmm -lgdi32 -lglew32 -static -lfreeglut_static 

另外,我认为没有双破折号--static选项,只有-static

在win32上,您需要成功执行glewInit()才能使您的glEnableVertexAttribArray()函数指针有效。当然,在检查核心版本和/或扩展之后 :)


1
这增加了更多关于“undefined reference to '_wglGetProcAddress@4'”的投诉。可能应该提到我已经尝试过参数顺序。我在问题中提供的是一组参数,可以减少GCC垃圾邮件的数量。 - nixeagle
看起来 --static-static 都可以使用。我使用了 --static 因为它是一个长格式选项。 - nixeagle
1
glewInit()而言,是的我知道。我放了一个最小化测试案例来产生链接错误。如果我放置了25或50行C++代码,每个人都会关注代码。通过将其减少到仅产生链接错误的6行,我似乎得到了更快更正确的响应。顺便说一句,实际代码在Linux上对我来说也运行良好;)。实际上解决我的Windows问题的是将-lopengl32移动到gcc参数列表的末尾。请参见我在回答Jite时下面的评论。 - nixeagle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接