Home > Net >  Trying to link OpenGL with Makefiles
Trying to link OpenGL with Makefiles

Time:08-25

I am on an Intel Mac. I installed the GLEW, glfw, and glm libraries using HomeBrew. I ran the code below and got an error message, but when I removed one line calling the glClear function,

glClear(GL_COLOR_BUFFER_BIT);

It gave this error.

g   main.o -o main -L/usr/local/lib/ -lGLEW -lglfw
Undefined symbols for architecture x86_64:
  "_glClear", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1

When I remove that one command, the GLFW window opens and it responds to the escape key closing the window. It seems that only OpenGL commands do not work. I can't figure out why. I tried calling other OpenGL functions and every time it gave an error, but glew functions work fine.

C File:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

GLFWwindow* window;

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>

#include <stdio.h>

int main(){

    glm::vec3 position = glm::vec3(0, 0, 0);

    if(!glfwInit()){
        printf("Initialization failed");
    } else {
        printf("GLFW Works\n");
    }

    // Creates a window and an OpenGL context
    window = glfwCreateWindow(800, 600, "GAME", NULL, NULL);
    if(window == NULL){
        fprintf(stderr, "Failed to open GLFW Window.");
        getchar();
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    //glewExperimental = true; // needed for core profile
    GLenum err = glewInit();
    if(err != GLEW_OK){
        fprintf(stderr, "Failed to initialize GLEW. "/*, glewGetErrorString(err)*/);
        getchar();
        glfwTerminate();
        return -1;
    }
    fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));

    glm::mat4 PerspectiveProjection = glm::perspective(glm::radians(45.0f), 4.0f/3.0f, 0.1f, 100.0f);
    glm::mat4 OrthoProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 0.01f, 100.0f);

    do{
        // Swap buffers
        glClear(GL_COLOR_BUFFER_BIT);
        glfwSwapBuffers(window);
        glfwPollEvents();
    } while( glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == false );

    // Cleanup VBO
    

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    return 0;
}

Makefile:

LIB = -L/usr/local/lib/ -lGLEW -lglfw
UNI_HEADER = /usr/local/include/

ALL: main
    ./main

main: main.o
    g   main.o -o main $(LIB)

main.o: main.cpp
    g   -c main.cpp -I $(UNI_HEADER)

test: test.o
    g   test.o -o test $(LIB)

test.o: test.cpp
    g   -c test.cpp -I $(UNI_HEADER)

.PHONY:
clean:
    rm main main.o *.o

CodePudding user response:

Like Neil commented, all I had to do was add -framework OpenGL to my lib variable in my Makefile. So when I run the command to link the object files, it is:

g   test.o -o test -L/usr/local/lib/ -lGLEW -lglfw -framework OpenGL

Makefile:

LIB = -L/usr/local/lib/ -lGLEW -lglfw -framework OpenGL
UNI_HEADER = /usr/local/include/

ALL: main
    ./main

main: main.o
    g   main.o -o main $(LIB)

main.o: main.cpp
    g   -c main.cpp -I $(UNI_HEADER)

test: test.o
    g   test.o -o test $(LIB)

test.o: test.cpp
    g   -c test.cpp -I $(UNI_HEADER)

.PHONY:
clean:
    rm main main.o *.o

CodePudding user response:

Instead of guessing compiler flags and what libraries you need to link to, you should be using pkg-config, as advised in GLFW's own build guide.

GLFW supports pkg-config, and the glfw3.pc pkg-config file is generated when the GLFW library is built and is installed along with it. A pkg-config file describes all necessary compile-time and link-time flags and dependencies needed to use a library. When they are updated or if they differ between systems, you will get the correct ones automatically.

Glew supports pkg-config too. Any library you make should support pkg-config too, that way it doesn't matter who uses what build system, pkg-config provides all the flags you need, specified by people who maintain the library and/or the package, there's no reason to ever not use this. Simply stop creating problems where there are none. You should only ever write flags manually when the library in question does not support pkg-config, better yet, you could contribute to the library by advising them to support it so you don't have to split hairs over trifle matters like this. pkg-config is not the holy grail, there's alternatives, like vcpkg, conan, you name it, but my point is, please use them. Rant over.

DEPENDENCIES = 'glew glfw3'

CXXFLAGS = $(shell pkg-config --cflags $(DEPENDENCIES))
LDLIBS = $(shell pkg-config --libs $(DEPENDENCIES))

ALL: main
    ./main

main: main.o
    g   main.o -o main $(LDLIBS)

main.o: main.cpp
    g   -c main.cpp $(CXXFLAGS)

test: test.o
    g   test.o -o test $(LDLIBS)

test.o: test.cpp
    g   -c test.cpp $(CXXFLAGS)

.PHONY:
clean:
    rm main main.o *.o

This is clean, simple, and when you will want to add, I don't know, libcurl, the only thing you will have to do is change DEPENDENCIES variable to include it.

If you installed those libraries in /usr/local, then depending on your system configuration, you may have to

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

before running any commands depending on pkg-config. If you run these pkg-config commands and check what they return, you will also notice that you don't have to specify where to search for headers nor libraries either.

  • Related