Skip to main content

"Undefined reference to ..." How can I find the library to link to?

The most panicking error among all the make errors is the undefined reference error, which is mostly cause by an unlinked library.

For instance, here I forget to link to OpenGL glfw on purpose, so gcc reports the error as following:

main.o: In function `Update':
main.cpp:375: undefined reference to `glfwGetCursorPos'
main.cpp:377: undefined reference to `glfwSetCursorPos'
main.o: In function `AppMain()':
main.cpp:400: undefined reference to `glfwSetErrorCallback'
main.cpp:405: undefined reference to `glfwWindowHint'
main.cpp:406: undefined reference to `glfwWindowHint'
main.cpp:407: undefined reference to `glfwWindowHint'
main.cpp:408: undefined reference to `glfwWindowHint'
main.cpp:409: undefined reference to `glfwWindowHint'
main.cpp:410: undefined reference to `glfwCreateWindow'
main.cpp:415: undefined reference to `glfwSetInputMode'
main.cpp:416: undefined reference to `glfwSetCursorPos'
main.cpp:417: undefined reference to `glfwSetScrollCallback'
main.cpp:418: undefined reference to `glfwMakeContextCurrent'
main.cpp:494: undefined reference to `glfwSetWindowShouldClose'
main.cpp:475: undefined reference to `glfwWindowShouldClose'
error: ld returned 1 exit status

Most of the time, these errors are not bugs in our code, they're just unlinked libraries. We call a function in our code, however the compiler cannot determine the next instruction under that it cannot find the real part(entry) of the function.

Therefore, I wrote a simple shell script that might help us find the undefined reference, the unknown library.

Here's the script:

function findundef() {
    [ -z "$1" ] || [ -z "$2" ] && {
        echo "usage: findundef 'library_dir' 'undefined_symbol'"
        echo "'library_dir' can be separated by ':'"
        return 1
    }

    local libraryDir
    libraryDir=($(echo "$1" | tr ":" " "))

    for i in "${libraryDir[@]}"; do
        find "$i" -type f -regextype posix-egrep -iregex '(.*\.)((a)|(so))' \
          -exec nm -gAC --defined-only {} 2>>/tmp/findundef.err \; \
            | grep "$2"
    done

    [ "$?" -ne 0 ] && cat /tmp/findundef.err

    rm -f /tmp/findundef.err
    unset libraryDir
}

Let's first take our example as a tutorial and let's find the function glfwGetCursorPos

$ findundef "/usr/lib/:/usr/local/lib/" "glfwGetCursorPos"

Here's the output of the run:

$ findundef "/usr/lib/:/usr/local/lib/" "glfwGetCursorPos"
/usr/local/lib/libglfw3.a:input.c.o:0000000000000860 T glfwGetCursorPos

Comments

Comments powered by Disqus