Can't get GLFW to link

2019-03-20 03:26发布

问题:

I am trying to compile the below test program:

#include <GL/glfw.h>

int main(int argc, char** argv) {
    if(!glfwInit()) {
        return -1;
    }

    if(!glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_WINDOW)) {
        return -1;
    }

    while(glfwGetWindowParam(GLFW_OPENED)) {
        glfwSwapBuffers();
    }

    return 0;
}

but I always get undefined reference errors in regards to the GLFW functions.

Below is my makefile:

CXX = clang++
CXXFLAGS = -Wall -std=c++0x
LDFLAGS = -lglfw

OBJ_DIR = bin
LIB_DIR = -L/usr/lib
INC_DIR = -I/usr/include

SOURCE = main.cpp
OBJECTS = ${SOURCE:%.cpp=$(OBJ_DIR)/%.o}
EXECUTABLE = hello

all: init $(OBJECTS) $(EXECUTABLE)

$(EXECUTABLE):
    $(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIB_DIR) -o $@ $(OBJECTS)

$(OBJ_DIR)/%.o: %.cpp
    $(CXX) $(INC_DIR) -c $< -o $@

init:
    @mkdir -p "$(OBJ_DIR)"

clean:
    @rm -rf $(OBJ_DIR) $(EXECUTABLE)

I definitely have glfw.h and libglfw.a/.so as when I run locate glfw I get:

:~$ locate glfw
/usr/include/GL/glfw.h
/usr/lib/libglfw.a
/usr/lib/libglfw.so
/usr/lib/libglfw.so.2
/usr/lib/libglfw.so.2.6

The output of nm /usr/lib/libglfw.a | grep glfwInit:

:~$ nm /usr/lib/libglfw.a | grep glfwInit
                 U _glfwInitialized
                 U _glfwInitialized
                 U _glfwInitialized
                 U _glfwInitialized
0000000000000000 B _glfwInitialized
0000000000000000 T glfwInit
                 U _glfwInitialized
                 U _glfwInitialized
                 U _glfwInitialized
                 U _glfwInitialized
                 U _glfwInitialized
                 U _glfwInitJoysticks
                 U _glfwInitTimer
00000000000000c0 T _glfwInitJoysticks
0000000000000000 T _glfwInitTimer

and the verbose message from clang:

clang++ -I/usr/include -c main.cpp -o bin/main.o
clang++ -Wall -std=c++0x -Wl --verbose -lglfw -lGL -lGLU -L/usr/lib -o hello bin/main.o
Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
clang: warning: argument unused during compilation: '-std=c++0x'
 "/usr/bin/ld" -z relro --hash-style=gnu --as-needed --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/usr/lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. -L/lib/x86_64-linux-gnu -L/lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib -lglfw -lGL -lGLU bin/main.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o
bin/main.o: In function `main':
main.cpp:(.text+0x17): undefined reference to `glfwInit'
main.cpp:(.text+0x76): undefined reference to `glfwOpenWindow'
main.cpp:(.text+0x97): undefined reference to `glfwGetWindowParam'
main.cpp:(.text+0xa7): undefined reference to `glfwSwapBuffers'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [hello] Error 1

It seems to not be finding the library?

回答1:

The problem is that the glfw libraries are being specified to the linker before the object file that depends on them. ld searches libraries to resolve dependencies only for the dependencies that it knows about at the point in list of files it's processing. So when ld is searching libglfw.a it doesn't know about the glfwInit dependency in main.o yet. ld (by default) doesn't go back an search the library again.

Try:

$(EXECUTABLE):
    $(CXX) $(CXXFLAGS) $(LIB_DIR) -o $@ $(OBJECTS)  $(LDFLAGS)

Also the libraries should probably be specified in a LDLIBS (or LIBS) variable - LDFLAGS is conventionally use for linker options:

CXX = clang++
CXXFLAGS = -Wall -std=c++0x
LDLIBS = -lglfw -lGL -lGLU

OBJ_DIR = bin
LIB_DIR = -L/usr/lib
INC_DIR = -I/usr/include

SOURCE = main.cpp
OBJECTS = ${SOURCE:%.cpp=$(OBJ_DIR)/%.o}
EXECUTABLE = hello

all: init $(OBJECTS) $(EXECUTABLE)

$(EXECUTABLE):
    $(CXX) $(LDFLAGS) $(LIB_DIR) -o $@ $(OBJECTS) $(LDLIBS)

$(OBJ_DIR)/%.o: %.cpp
    $(CXX) $(INC_DIR) -c $< -o $@

init:
    @mkdir -p "$(OBJ_DIR)"

clean:
    @rm -rf $(OBJ_DIR) $(EXECUTABLE)


标签: c++ clang glfw