четверг, 10 ноября 2016 г.

Поиск библиотеки, содержащей определение функции

Переодически при компиляции сторонних продуктов возникает ошибка
 undefined reference to <function>
для какой либо функции. Обычно я гуглил имя функции и искал, что кто-нибудь скажет какую библиотеку надо прилинковать к проекту.
Вчера, в очередной раз столкнувшись с подобной проблемой написал, в терминале команду, которая ищет данную функцию.

function="dbus_watch_set_data"; \
for library in $(ls /usr/lib/*.so); do \
    res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); \
    if [ ! -z "$res" ]; then \
        echo "${library}: $res"; \
        break; \
    fi; \
done; \
if [ -z "$res" ]; then \
    echo "function '${function}' not found"; \
fi

Соответственно вместо dbus_watch_set_data нужно подставлять имя искомой функции.
Также можно вместо /usr/lib/ вставлять другие директории, например /usr/local/lib.

Пример удачного поика:
[grin@grinvbox-ol65-x86 ~]$ function="dbus_watch_set_data"; for library in $(ls /usr/lib/*.so); do res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); if [ ! -z "$res" ]; then echo "${library}: $res"; break; fi; done; if [ -z "$res" ]; then echo "function '${function}' not found"; fi
/usr/lib/libdbus-1.so:    473: 0002bdd0   111 FUNC    GLOBAL DEFAULT   12 dbus_watch_set_data@@LIBDBUS_1_3
  1410: 0002bdd0   111 FUNC    GLOBAL DEFAULT   12 dbus_watch_set_data

Функция dbus_watch_set_data найдена (2 раза) в библиотеке /usr/lib/libdbus-1.so


Пример неудачного поиска:
[grin@grinvbox-ol65-x86 ~]$ function="dbusx_watch_set_data"; for library in $(ls /usr/lib/*.so); do res=$(readelf -s ${library} 2> /dev/null | grep ${function} | grep -v 00000000); if [ ! -z "$res" ]; then echo "${library}: $res"; break; fi; done; if [ -z "$res" ]; then echo "function '${function}' not found"; fi
function 'dbusx_watch_set_data' not found

Функция dbusx_watch_set_data не найдена (нет такой функции).


P.S. для более детального понимания, рекомендую man readelf.