Reputation: 15308
I'm following a (modified) version of this OpenGL tutorial.
With this trivial source file:
#include <GL/glew.h>
int main() {
glewInit();
}
And this makefile:
cflags=-ggdb -Wall -std=c++17
all: 01
01: 01.o makefile
g++ $(cflags) $(shell pkg-config --libs glew glfw3 glm) -o $@ $<
01.o: 01.cpp makefile
g++ $(cflags) $(shell pkg-config --cflags glew glfw3 glm) -o $@ $< -c
# The following have pkg-config entries:
# x11 xext glu glfw3 glew glm
It can compile but not link.
$ make
g++ -ggdb -Wall -std=c++17 -I/usr/include/libdrm -o 01.o 01.cpp -c
g++ -ggdb -Wall -std=c++17 -lGLEW -lGLU -lGL -lglfw -o 01 01.o
/usr/bin/ld: 01.o: in function `main':
/home/greg/OpenGL_GEOM_2D/01/01.cpp:6: undefined reference to `glewInit'
Checking what pkg-config
is doing in the background:
$ pkg-config --libs glew
-lGLEW -lGLU -lGL
The library it's using is here:
$ dpkg-query -L libglew-dev
/usr/lib/x86_64-linux-gnu/libGLEW.so
That file definitely does have the symbols that are failing to link:
$ readelf -Ws /usr/lib/x86_64-linux-gnu/libGLEW.so | grep glewInit
1146: 000000000005f2f0 38819 FUNC GLOBAL DEFAULT 10 glewInit
So what's going on? Why is the linker failing to find that symbol?
Upvotes: 0
Views: 985
Reputation: 162317
For the old GNU linker the order of inputs specified on the command line does matter. It makes a difference if the libraries are specified before or after the input object files.
Try this for your Makefile
01: 01.o makefile
g++ -o $@ $< $(shell pkg-config --libs glew glfw3 glm)
BTW, you should learn about implicit rules, your whole Makefile can be replaced with:
.PHONY: 01
all: 01
01: LDFLAGS += $(shell pkg-config --libs glew glfw3 glm)
01: 01.o
01.o: CFLAGS += $(shell pkg-config --cflags glew glfw3 glm)
01.o: 01.cpp Makefile
Thanks to the implcit rules you don't have to write the actual commands at all, just set the desired variables.
Upvotes: 1