Mr.UNOwen Mr.UNOwen - 4 months ago 11
C++ Question

Getting "undefined reference to `glBegin' " to formerly working project, what needs updating in make file?

So I'm trying to re-build a 4 year old project that was working, but now is having issues building. I was able to address some of the compile related issues, but now I'm having linker issues with the openGL calls.

In terms of what's different, now instead of freeglut it's now freeglut3 and instead of libsdl-mixer it's libsdl-mixer1.2.

Is there anything I need to update in the LDFLAGS section???

Here segments of the makefile:

CC=g++

# The _POSIX_* symbols only come into play on systems that are POSIX
# but not SUS.
# SUS3=-D_POSIX_SOURCE -D_POSIX_C_SOURCE=200112L -D_XOPEN_SOURCE=600
HARDEN=-D_FORTIFY_SOURCE
TESTING=-D_FLAT_WORLD
CFLAGS= -pg -g `sdl-config --cflags --libs` -fpermissive
LDFLAGS=-lGLEW -lGL -lGLU -lglut -lpthread -lSDL_mixer

ALL=mech

mech: $(ALL)

# -------------------------------------------------------
run.o: ../run.cc ../commonStrc.h
$(CC) $(CFLAGS) -c $<

debug.o: ../debug.cc ../debug.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

world.o: ../world.cc ../world.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

gameRoot.o: ../gameRoot.cc ../gameRoot.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

gameState.o: ../gameState.cc ../gameState.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

initGame.o: ../initGame.cc ../initGame.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

controls.o: ../controls.cc ../controls.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

levelManager.o: ../levelManager.cc ../levelManager.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

thread.o: ../thread.cc ../thread.h
$(CC) $(CFLAGS) -c $<

# ------------------------------------------------------- soundMngr
gmAudioPlayer.o: ../soundMngr/gmAudioPlayer.cc ../soundMngr/gmAudioPlayer.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

gmAudioLoader.o: ../soundMngr/gmAudioLoader.cc ../soundMngr/gmAudioLoader.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

# ------------------------------------------------------- MD5
md5anim.o: ../md5/md5anim.cc ../md5/MD5Model.h ../commonStrc.h ../md5/md5head.h
$(CC) $(CFLAGS) -c $<

md5mesh.o: ../md5/md5mesh.cc ../md5/MD5Model.h ../commonStrc.h ../md5/md5head.h
$(CC) $(CFLAGS) -c $<

MD5Model.o: ../md5/MD5Model.cc ../md5/MD5Model.h ../commonStrc.h ../md5/md5head.h
$(CC) $(CFLAGS) -c $<

# ------------------------------------------------------- myLib
myCorePoint.o: ../myLib/myCorePoint.cc ../myLib/myCorePoint.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

myVec.o: ../myLib/myVec.cc ../myLib/myVec.h
$(CC) $(CFLAGS) -c $<

myVert.o: ../myLib/myVert.cc ../myLib/myVert.h
$(CC) $(CFLAGS) -c $<

myCam.o: ../myLib/myCam.cc ../myLib/myCam.h
$(CC) $(CFLAGS) -c $<

myTexMngr.o: ../myLib/myTexMngr.cc ../myLib/myTexMngr.h
$(CC) $(CFLAGS) -c $<

myVerBall.o: ../myLib/myVerBall.cc ../myLib/myVerBall.h
$(CC) $(CFLAGS) -c $<

MyCoor3.o: ../myLib/MyCoor3.cc ../myLib/MyCoor3.h
$(CC) $(CFLAGS) -c $<

MyMatr4.o: ../myLib/MyMatr4.cc ../myLib/MyMatr4.h
$(CC) $(CFLAGS) -c $<

.... some more stuff I cut out .....

bbFinder.o: ../org/bbFinder.cc ../org/bbFinder.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

pathFinder.o: ../org/pathFinder.cc ../org/pathFinder.h ../commonStrc.h
$(CC) $(CFLAGS) -c $<

# --------------------------------------------------------

mech: run.o debug.o world.o gameRoot.o gameState.o initGame.o controls.o levelManager.o thread.o gmAudioLoader.o gmAudioPlayer.o md5anim.o md5mesh.o MD5Model.o myVert.o myVec.o myCorePoint.o myCam.o myTexMngr.o myVerBall.o MyCoor3.o MyMatr4.o hud.o pauseScreen.o rotSeg.o mechLeg.o gameBound.o particle.o particleGroup.o BBHier.o BBox.o bSphere.o Missile.o drunk.o homing.o pHoming.o miniMis.o hydra.o buildingBlock.o Projectile.o explosion.o bBin.o bCone.o binIndices.o tiltBlock.o core.o blast.o pseudoModel.o pseudoReader.o pseudoParts.o pseudoMech.o turret.o actor.o hover.o pseudoPlayer.o mechAI.o misCan.o font.o flatFog.o env.o healZone.o amoZone.o itemGen.o materialPreset.o mainMenu.o controlMenu.o menuMngr.o lvlSelect.o shader.o mouseFix.o ctrlBox.o linThread.o winThread.o bbFinder.o pathFinder.o
$(CC) -pg $(LDFLAGS) -o $@ $^

clean:
rm -rf core* *.o *.gch $(ALL)

Answer

I believe the link flags are in the wrong order.

This doesn't look right to me…

LDFLAGS = -lGLEW -lGL -lGLU -lglut -lpthread -lSDL_mixer 

What happens is that the linker searches in order, so if you write X Y Z, then X can use symbols from Y and Z, but Y can only use symbols from Z, and Z can't use symbols from any other library. Any "base" library which everything depends on should go at the end.

Sometimes, putting things in the wrong order will still work, depending on whether the libraries are static or dynamic libraries, which version of the libraries you are using, how the libraries were compiled, et cetera. It's a serious misfeature, in my opinion, that the order is important at all! Some other toolchains, like the Darwin (macOS, iOS) toolchain, do not generally care what order you specify libraries in.

Your LIBS variable should end up looking like this:

LIBS = -lGLEW -lglut -lGLU -lGL -lSDL_mixer -pthread

But you should probably write it in the makefile like this:

LIBS := -lglut $(shell pkg-config --libs gl glu glew SDL_mixer) -pthread

And the build rule should look like this:

LDFLAGS := -pg
mech: ...
    $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

I've made a few changes.

  • Libraries go in LIBS not in LDFLAGS.

  • Libraries in $(LIBS) go at the end of the command line, after $^.

  • Use := to avoid expanding $(shell ...) multiple times.

  • Use pkg-config to get most of the libraries right. I don't think glut has a pkg-config file (it doesn't on my system), so that one is manual. The pkg-config --libs command will put libraries in the correct order for you so you don't have to think as much about it.

  • Use -pthread instead of -lpthreads (should be in your CFLAGS too).

I'm planning on posting an article explaining all of this, as these errors are somewhat common in Makefiles.

Comments