Tuesday, May 25, 2010

Eclise + MinGW + FreeGlut (2)

Eclipse CDT + MinGW + FreeGlut (2)

This tutorial starts with building freeglut to create a simple working application with Eclipse and MinGW in both 32-bit and 64-bit versions.  This tutorial refers to a few other tutorials so that readers can jump to the part they want to know conveniently.  Follow the instructions below is relatively a simple task.

  1. The first task is to obtain Eclipse CDT.  This tutorial is based on Eclipse CDT Galieo (SR2 Build ID:2010 02 18-1602).  You can download it from this link, but the most recent version on the Eclipse server may be your preferred choice.

  2. Obtain your preferred MinGW version.  I prepared 32-bit MinGW 4.5.0 and 64-bit MinGW 4.6.0 (2010-April-16 Experimental) packages for you to download.  Note that the include paths within the packages are different.  This is the default settings of the two packages.  Eclipse, however, knows the 32-bit folder paths well, but does not aware of the include paths for the 64-bit version.  Probably, this is because the 64-bit version is still experimental.

  3. Download freeglut.  This tutorial uses freeglut 2.6.0.  If you want to use a pre-compiled binary package, try the following links.
    1. freeglut 32-bit, compiled with 32-bit MinGW 4.5.0 (O2 optimization).  libfreeglut32.a and freeglut32.dll are for dynamic linking, while libfreeglut32_static.a is for static linking.  Header files are included.  I built this package myself.  Feel free to contact me if you have any problem (use the comment in my blog)

    2. freeglut 64-bit, compiled with 64-bit MinGW 4.6.0 (2010-April-16 Experimental) (O2 optimization).  libfreeglut64.a and freeglut64.dll are for dynamic linking, while libfreeglut64_static.a is for static linking.  Header files are included.  I built this package myself.  Feel free to contact me if you have any problem (use the comment in my blog)

    3. From other source

  4. Build freeglut (If you get the binary package from Step 3, ignore this step).  Instructions are available in my post and in another web site.

  5. Putting things together.  If you use MinGW and freeglut 32-bit, this step is quite simple, as Eclipse knows MinGW 32-bit settings well, provided that you save MinGW at C:\MinGW. If you choose a 64-bit path, follow a common instruction for building and running 64-bit applications with Eclipse + MinGW 64-bit in my post.
    1. Put freeglut library in a proper place.
    2. Set compiler and linker flags.  This can be done by going to 'Project->Properties'.  Then, in C/C++ Build, go to 'Settings'.  The flags for static and dynamic links are different.  I assume that you are going to build a C++ application.
      1. For static link:
        In 'GCC C++ Compiler', go to 'Preprocessor' and add a defined symbol FREEGLUT_STATIC.  Also, make sure that your compiler see your freeglut and OpenGL headers.

        In 'MinGW C++ Linker', go to 'Libraries' and add the following libraries (-l): winmm, gid32, opengl32, and freeglut64_static.  Note that the name for freeglut64_static must be consistent with your actual library file name.  Also, it is important to omit the prefix 'lib' and suffix '.a'.  It is crucial, however, that the library file name must come with the prefix and suffix.  Next, add library search path (-L).  This is where you have placed your freeglut library.  For example, in my case, I add a path "C:\MinGW_x64\x86_64-w64-mingw32\lib\freeglut" (with double quotes).

      2. For dynamic link:
        There is no need to add any thing to the preprocessor section, but make sure that your compiler see your freeglut and OpenGL headers.

        Now, go to 'MinGW C++ Linker' and its library section.  Then, do exactly the same thing as discussed for the static link, except that you have to change freeglut64_static to the one for your dynamic link.

    3. Build application.  Try starting with a simple one.  A good example is given from other www.transmissionzero.co.uk.

    4. Run your application.  This seems to be trivial at first, but it can be a bit tricky because you also have to set your MinGW library path.  In addition, if you dynamically link to freeglut, you need to set up its library path.  Whether or not you are building an 64-bit application, please see Section 'Change Run-Time Setting' in my previous post.  It shows you how to set run-time library paths in Eclipse and Windows command to set a library path in case that you are going to run your application outside Eclipse.  If you feel not understand how to do it, you might want to check some figures in my even older post (Figures 6 and 7).

Pinyo Taeprasartsit
(May 2010)

This document can be viewed at my blog and my Google docs.  I welcome questions, comments, and suggestions.  Please leave a message in my blog if you have any.  Thank you.



8 comments:

Nimer said...

Hi, I'm trying to use freeglut64 with netbeans (I prefer it over Eclipse) and while compiling I get the following error (using the example from this tutorial):

"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory `/d/GNU_OPENGL_test'
"/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/MinGWx64-Windows/gnu_opengl_test.exe
make[2]: Entering directory `/d/GNU_OPENGL_test'
mkdir -p build/Debug/MinGWx64-Windows
rm -f build/Debug/MinGWx64-Windows/main.o.d
x86_64-w64-mingw32-g++.exe -m64 -static -c -g -DFREEGLUT_STATIC -MMD -MP -MF build/Debug/MinGWx64-Windows/main.o.d -o build/Debug/MinGWx64-Windows/main.o main.cpp
mkdir -p dist/Debug/MinGWx64-Windows
x86_64-w64-mingw32-g++.exe -m64 -static -lwinmm -lgdi32 -lopengl32 -lfreeglut64_static -o dist/Debug/MinGWx64-Windows/gnu_opengl_test build/Debug/MinGWx64-Windows/main.o -L.
build/Debug/MinGWx64-Windows/main.o: In function `glutInit_ATEXIT_HACK':
D:\GNU_OPENGL_test/freeglut_std.h:610: undefined reference to `__glutInitWithExit'
build/Debug/MinGWx64-Windows/main.o: In function `glutCreateWindow_ATEXIT_HACK':
D:\GNU_OPENGL_test/freeglut_std.h:612: undefined reference to `__glutCreateWindowWithExit'
build/Debug/MinGWx64-Windows/main.o: In function `glutCreateMenu_ATEXIT_HACK':
D:\GNU_OPENGL_test/freeglut_std.h:614: undefined reference to `__glutCreateMenuWithExit'
build/Debug/MinGWx64-Windows/main.o: In function `main':
D:\GNU_OPENGL_test/main.cpp:11: undefined reference to `glutKeyboardFunc'
D:\GNU_OPENGL_test/main.cpp:12: undefined reference to `glutDisplayFunc'
D:\GNU_OPENGL_test/main.cpp:13: undefined reference to `glutMainLoop'
build/Debug/MinGWx64-Windows/main.o: In function `display()':
D:\GNU_OPENGL_test/main.cpp:32: undefined reference to `__imp_glClear'
D:\GNU_OPENGL_test/main.cpp:34: undefined reference to `__imp_glColor3f'
D:\GNU_OPENGL_test/main.cpp:36: undefined reference to `__imp_glBegin'
D:\GNU_OPENGL_test/main.cpp:37: undefined reference to `__imp_glVertex2f'
D:\GNU_OPENGL_test/main.cpp:38: undefined reference to `__imp_glVertex2f'
D:\GNU_OPENGL_test/main.cpp:39: undefined reference to `__imp_glVertex2f'
D:\GNU_OPENGL_test/main.cpp:40: undefined reference to `__imp_glVertex2f'
D:\GNU_OPENGL_test/main.cpp:41: undefined reference to `__imp_glEnd'
D:\GNU_OPENGL_test/main.cpp:43: undefined reference to `__imp_glFlushmake[2]: Leaving directory `/d/GNU_OPENGL_test'
make[1]: Leaving directory `/d/GNU_OPENGL_test'
'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/MinGWx64-Windows/gnu_opengl_test.exe] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 4s)

If you could tell me what I did wrong, I would be really grateful!

pinyotae said...

Hi Nimer,

It seems that you used a cross-compiler for your work. Your compiler is 32-bit, but generates 64-bit applications (I noticed from prefix x86_64-w64-mingw32).

If you use this compiler, its calling convention will be different from a native 64-bit compiler (a 64-bit compiler that generates 64-bit applications). In fact, the library calling convention of a 64-bit app should have only one prefix underscore, but yours requested two underscores, as your compiler is 32-bit.

If you want to stick to this compiler, please try my old package .

Also, please let me know if it works or not. There is a little discussion about this issue in the comments of another of my posts . Credit to James (Anonymous poster near the bottom of the discussion) who pointed this out.

I don't know if this issue is by design or by error.

Hope this helps,
Pinyo
(Mar 11, 2011)

Nimer said...

Older version of your library makes a lot more errors ;/. The newer one gives my the following errors I consider worth of notice:

In function `glutInit_ATEXIT_HACK':
D:\GNU_OPENGL_test/freeglut_std.h:610: undefined reference to `__glutInitWithExit'
build/Debug/MinGWx64-Windows/main.o: In function `glutCreateWindow_ATEXIT_HACK':
D:\GNU_OPENGL_test/freeglut_std.h:612: undefined reference to `__glutCreateWindowWithExit'
build/Debug/MinGWx64-Windows/main.o: In function `glutCreateMenu_ATEXIT_HACK':
D:\GNU_OPENGL_test/freeglut_std.h:614: undefined reference to `__glutCreateMenuWithExit'

If you have any idea what could be a cause of those, please give ma notice.

Thanks in advance!

pinyotae said...

Hi Nimer,

Sorry for confusion. The links to freeglut are old. I thought that I updated the link in the blog to the new, correct one.

Please try the freeglut package in this link . I tested it with both native and cross compilers and it worked with both. Perhaps, the calling convention problem in an experimental version is now a history.

Nimer said...

I still get this error... I'm using newest senzo build of mingw64 for compiling this... I'm gonna try with automated version, and then give you a call if it worked out.

Thanks in advance!

Nimer said...

Dynamic linking library tends to work, but I cant manage to make static library to work.

This is my makefile for static linking:
CPP=x86_64-w64-mingw32-g++
CCFLAGS=-m64 -O0 -static -g -Wall -Wextra -pedantic -L. -I.

all: main

main: main.o
$(CPP) $(CCFLAGS) main.o -o main.exe -lwinmm -lgdi32 -lopengl32 -lfreeglut64_static

main.o: main.cpp
$(CPP) $(CCFLAGS) -DFREEGLUT_STATIC -c main.cpp

clean:
rm *.o main.exe

pinyotae said...

Hello again, Nimer:

I tested compilation-linking with these:
1. x86_64-w64-mingw32-gcc -c -o TestFreeGlut.o TestFreeGlut.c -DFREEGLUT_STATIC -I-I"G:\Workspace\FreeGlut\TestCompile"

2. x86_64-w64-mingw32-gcc -o TestFreeGlut.exe TestFreeGlut.o -L"G:\Workspace\FreeGlut\TestCompile" -lfreeglut64_static -lopengl32 -lwinmm -lgdi32

I don't have any problem (both sezero and official builds). I tested it with Windows 7 Home Premium 64-bit.

Could you try it with a command line, instead of Netbeans? As usual, please let me know if it works or not. I will update my blogs when things are settled.

Hope this helps,
Pinyo

Nimer said...

It works - sounds like I was calling libraries in wrong turn... When I changed -lwinmm -lgdi32 -lopengl32 -lfreeglut64_static to -lfreeglut64_static -lopengl32 -lwinmm -lgdi32 it worked ;).

Thanks mate for your time - I did not know that lfreeglut64 needs to be called before other libs.

BTW. I tried it with both Netbeans and MSYS.