Static Compile GLFW and GLEW
Warning: Use of undefined constant woothemes - assumed 'woothemes' (this will throw an Error in a future version of PHP) in /home/public/wp-content/themes/irresistible/single.php on line 19
// August 31st, 2011 // Posted in C, OpenGL // Tagged as glew, glfw
Introduction
I need to compile GLFW and GLEW and statically link them into my OpenGL application but apparently it’s not as easy as I thought it was.
I’m using Linux Mint 9 KDE which is based on Kubuntu 10.04 and I have GCC 4.4.3 installed. GLFW and GLEW are available in Ubuntu repository as GLFW 2.6.2 and GLEW 1.5 but I want to use the latest version instead. As of this writing those are GLFW 2.7.2 and GLEW 1.7.0.
The Code
For demonstration purpose I’ve created a project directory called “test” which has a subdirectory called “external“. In “external” is where I put GLFW and GLEW sources. The code below is the main source code called “test.c“.
#include <stdio.h> #include <stdlib.h> #include "external/glew/include/GL/glew.h" #include "external/glfw/include/GL/glfw.h" int main( int argc, char const* argv[] ) { if( !glfwInit() ){ fprintf( stderr, "Epic Fail!\n" ); } glfwOpenWindowHint( GLFW_FSAA_SAMPLES, 4 ); glfwOpenWindowHint( GLFW_OPENGL_VERSION_MAJOR, 3 ); glfwOpenWindowHint( GLFW_OPENGL_VERSION_MINOR, 1 ); glfwOpenWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE ); // open a window and creates OpenGL context if( !glfwOpenWindow( 1024, 768, 8,8,8,0, 24,8, GLFW_WINDOW )){ fprintf( stderr, "Failed to open GLFW window\n" ); glfwTerminate(); return -1; } // initialize GLEW if( glewInit() != GLEW_OK ){ fprintf( stderr, "Failed to initialize GLEW\n" ); return -1; } glfwSetWindowTitle( "Testing" ); // dark background glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); return 0; }
The code above will compile just fine but the executable won’t work using the latest source (it will work using GLFW & GLEW from Ubuntu repository). After banging my head against the wall and digging around the internet, I found out that the line
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MINOR, 1 );
won’t work because GLFW 2.7.1 and 2.7.2 requires OpenGL 3.2. Apparently OpenGL Core Profiles only available in OpenGL 3.2. Thanks for elmindreda for pointing this out. To get around it simply change the line to
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MINOR, 2 );
Compiling The Libraries
Let’s compile GLFW first. Using your favorite shell go into GLFW source directory. In my case it’s in “external/glfw“, compile and install it.
unix$ cd external/glfw unix$ make x11
it will compile the required static lib file which is located in external/glfw/lib/x11/libglfw.a
Compiling GLEW is a bit tricky. Simply doing “make” should produce libglew.a and libglew.so for static lib and shared lib but for unknown reason it won’t work. I need to make small changes to the Makefile by adding a flag -DGLEW_STATIC to couple lines of code. Edit the file and find a line that says:
$(CC) -DGLEW_NO_GLU $(CFLAGS) $(CFLAGS.SO) -o $@ -c $<
in my case it was line 122. add the static flag into it:
$(CC) -DGLEW_STATIC -DGLEW_NO_GLU $(CFLAGS) $(CFLAGS.SO) -o $@ -c $<
few lines after that also find a line that says:
$(CC) -DGLEW_NO_GLU $(CFLAGS) $(PICFLAG) $(CFLAGS.SO) -o $@ -c $<
for me it was line 125. Change it to:
$(CC) -DGLEW_STATIC -DGLEW_NO_GLU $(CFLAGS) $(PICFLAG) $(CFLAGS.SO) -o $@ -c $<
Put Everything Together
As the final step, compile everything using GCC with these flags:
/usr/bin/gcc test.c external/glew/src/glew.o external/glfw/lib/x11/libglfw.a -lXrandr -lX11 -pthread -lm -lGLU -lGL -o test
Basically what it says is to include both glew.o (which we've just compiled using -DGLEW_STATIC directive) and static lib libglfw.a as statically linked libraries to our test.c and produce the result as a binary file called "test".
If everything went well executing the binary file should gives you a pop of OpenGL Context window.
The reason GLFW may appear to require OpenGL 3.2 in this case is that you have requested an OpenGL context profile. Profiles are only defined for OpenGL 3.2 and above, so requesting it with 3.1 makes little sense. If you were to remove the request for a specific profile, requests for OpenGL 3.1 or below would likely work as expected.
In this case, GLFW is a thin layer on top of this API and follows the policies set by it:
http://www.opengl.org/registry/specs/ARB/glx_create_context.txt
thanks for the clarification elmindreda! :)