Dav1dde / glad

Multi-Language Vulkan/GL/GLES/EGL/GLX/WGL Loader-Generator based on the official specs.
https://glad.dav1d.de/
Other
3.79k stars 448 forks source link

Problem Using g++ on Max OS : Undefined symbols for architecture x86_64 #185

Closed Frank-Walker closed 6 years ago

Frank-Walker commented 6 years ago

Basic Info:

  1. system: macOS High Sierra(10.13.6)
  2. editor : vs code(latest version)
  3. Compiler: g++ (Xcode)
  4. Target:deploy GLFW + GLAD

Question Description:
Recently, I'm learning to do some Computer Graphics related work. Everything is going smooth. However, when i create a window to test the env.Link error happened:

Undefined symbols for architecture x86_64:
"_gladLoadGLLoader", referenced from:
  _main in main-5c211c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The terminal process terminated with exit code: 1

It seems I have not link some third party file. I have fixed exactly the same problem by add "-lglfw" args to g++ when using functions in glfw3.h.
But when meeting glad related function : gladLoadGLLoader, I don't know how to do.

Something I have done:

  1. Can find the head file.

    #include glad/glad.h  
    #include GLFW/glfw3.h  
  2. Have put the file "glad.c" in workspace.

  3. Add "g++ -L or I /usr/lib or /usr/local/lib or /usr/local/include", But doesn't work.

Thanks in advance!

Dav1dde commented 6 years ago

You need to compile glad.c with your file(s). E.g. you would compile the example using the following command:

g++ example/c++/hellowindow2.cpp -Ibuild/include build/src/glad.c -lglfw -ldl

Can you show me your build setup or verify that glad.c is passed to the compiler (and optionally glad.o to the linker)?

Frank-Walker commented 6 years ago

Yes you are right! I didn't tell g++ to compile glad.c explicitly, I thought the file will be complied by default. Here is my build setup:

{
"version": "2.0.0",
"tasks": [
    {
        "label": "testwindow",
        "type": "shell",
        "command": "g++",
        "args": [
            "glad.c",
            "-lglfw",
            "${file}",
            "-o",
            "${fileDirname}/${fileBasenameNoExtension}.out",
            "-g",
        ],
             "group": {
                  "kind": "build",
                  "isDefault": true
            }
        }
    ]
}

I still have a concern that I just put glad.c to args without any other operation.
Does the order of the args to g++ matter or Will it lead to some underlying problems?
It troubled me for quite a while. Thanks anyway!

(PS: Honestly, I'm a rookie on C/Cpp. It's my first time using third party lib and compiler without IDE like VS, Do you know some resources online(book/video lecture) on learning how to use complier like g++,gcc, etc?)

Dav1dde commented 6 years ago

Having glad.c included like that is perfectly fine.

You want to move -lglfw to the end of your arguments list (that's the case for basically all linker commands).

The reasoning is, the creation of a binary is split into two phases 1) compilation and 2) linking, normally you'd need a compiler to compile the files (usually done with -c flag and outputting a .o file) and a linker to link the .o files together and create the final executable. GCC/G++ are kind enough to call the linker (usually ld) for you. So if you just pass it a bunch of C/C++ files it compiles and links them into an executable. The linker itself tries to put in as little as possible into the executable, so if you pass it a library e.g. -lglfw at the very beginning (first argument), it sees that the library has a bunch of symbols exported (e.g. glfwGetProcAddress) but no file is referencing any symbols of that library, so it is just discarded (which you don't want because your file is referencing that symbol, but was passed in later).

Personally I'd look for a very simple and basic Makefile and work with that.

Frank-Walker commented 6 years ago

Thank you for your advice and detailed explanation. You resolved my problem perfectly!