Search code examples
c++linkerlibrariesundefined-symbol

How do I find where a symbol is defined among static libraries


Suppose you work with a codebase comprising several tools and libraries and you want to port (or resurrect) some component within such codebase but any clue about where symbols lie within the various libs is either lost or will take ages to find out by looking at the code itself (yes improved documentation can avoid such issues but is quite demanding). What is the fastest way to discover in which library you can find symbols used in the code?


Solution

  • Using nm, it is possible to list the symbols defined in a binary, and the --defined-only switch ignores undefined references.

    Option 1: find

    In a single command:

    find $path -name \*.a -exec bash -c "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}" \;
    

    where $path is the root of the file tree containing the binaries, and $symbol is the name of the symbol you are looking for.

    Option 2: find + GNU parallel

    Running nm on all files can take time, so it could be helpful to process the results of find in parallel (using GNU parallel):

    find $path -name \*.a | parallel "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}"
    

    Option 3: fd

    And at last, my favourite. Using the fd tool, that has a simpler syntax than find, is generally faster, and processes the results in parallel by default:

    fd '.*\.a$' -x bash -c "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}"
    

    Simple benchmark

    Searching for the gz_write symbol in /usr/lib on my laptop:

    • find takes around 23 seconds
    • find | parallel takes around 10 seconds
    • fd takes around 8 seconds