26 Jan 2008

Bug: Glew and Mesa Glut

There is a macro definition clash between Glew's glew.h and Mesa Glut's glut.h on Unix. Any program using Glew fails to compile. The problem does NOT occur with other Glut implementations (freeglut, Kilgard glut).

I am using Slackware Linux 12.0, Mesa 6.5.2 and Glew 1.5.0. However, the problem is present in all recent versions of Glew, including svn, and all recent versions of Mesa Glut, including git.

Other people have had the same problem:
http://www.nabble.com/glew-header-trashes-glut-header-tc7610932.html
http://groups.google.fr/group/linux.debian.bugs.rc/browse_thread...

I first encountered this problem when trying to compile enblend, but even the following trivial test program is sufficient to demonstrate the problem (thanks Philippe Després). It doesn't compile.

#include <GL/glew.h>
#include <GL/glut.h>
int main()
{
return 0;
}
  • First, the application #includes glew.h
  • glew.h #defines GLAPIENTRY -- for Unix this is line 209 of glew.h, and GLAPIENTRY is defined to be empty
  • Then glew.h #includes glu.h at line 1137
  • Then glu.h #includes gl.h which redefines GLAPIENTRY (consistently with glew.h)
  • Then glew.h uses GLAPIENTRY (successfully), and eventually #undefs GLAPIENTRY at line 10767
  • Then the application #includes glut.h
  • Then glut.h #includes glu.h at line 11
  • But glu.h has already been included, so glu.h does nothing (it checks __glu_h__ in the usual way)
  • Then glut.h uses GLAPIENTRY at line 196
    # define GLUTAPIENTRY GLAPIENTRY
    In other words, glut.h expects to get GLAPIENTRY from glu.h, but glew.h undefined it.
  • So GLUTAPIENTRY now contains the string "GLAPIENTRY" instead of being empty. This causes compilation errors throughout the rest of glut.h, starting on line 531
    GLUTAPI void GLUTAPIENTRY glutInit(int *argcp, char **argv);
    which produces these errors
    /usr/include/GL/glut.h:531: error: expected initializer before 'glutInit'
    /usr/include/GL/glut.h:539: error: expected initializer before 'glutInitDisplayMode'
    /usr/include/GL/glut.h:541: error: expected initializer before 'glutInitDisplayString'
    /usr/include/GL/glut.h:543: error: expected initializer before 'glutInitWindowPosition'
    /usr/include/GL/glut.h:544: error: expected initializer before 'glutInitWindowSize'

    etc etc...

The obvious solution is to delete the #undef at line 10767 of glew.h. Here's the trivial patch:
--- glew-1.5.0/include/GL/glew.h        2007-12-28 03:09:49.000000000 +0000
+++ glew-patched/include/GL/glew.h 2008-01-26 11:45:27.000000000 +0000
@@ -10764,7 +10764,6 @@
#ifdef GLEW_APIENTRY_DEFINED
#undef GLEW_APIENTRY_DEFINED
#undef APIENTRY
-#undef GLAPIENTRY
#endif

#ifdef GLEW_CALLBACK_DEFINED

3 comments:

Newmikey said...

We Are Dave,

You just saved my life. Trying to compile Enblend/enfuse on PCLinuxOS for days on end, all kinds of sources. This did the trick!

Many thanks,

NewMikey
(PCLinuxOS Digital Photography Edition)

dude said...

I just wanted to chime in with my thanks too. I've been trying to compile the Enblend/Enfuse package on PCLinuxOS for hours now.

Much appreciated!

We Are Dave said...

Just a quick note to say, this appears to no longer be a problem with Mesa 7.5 and Glew 1.5.1. (BICBW...) Thanks to whoever fixed it, if that's what happened ;-)