Нужно ли мне знать, в каком * .so
Да.
Это единственный способ
Ну, нет, вы можете написать собственное решение самостоятельно.
или есть более быстрый / простой способ?
Я не верю, даже если есть Я не верю, что было бы целесообразно использовать его.
как мне узнать, что такое
Пример:
$ gcc /tmp/1.c
/usr/bin/ld: /tmp/cc2lZAPF.o: in function `main':
1.c:(.text+0x19): undefined reference to `pthread_create'
Оч нет! Еще раз мы забыли связать с -pthread
. Но не бойтесь больше, просто для удовольствия я создал следующий скрипт ,ld_find_symbol
:
#!/bin/bash
# SPDX-License-Identifier: MIT AND Beerware
name=$(basename "$0")
usage() {
cat <<EOF
Usage: $name <symbol>...
Options:
-d <database>
-h
Finds the symbol in libraries.
Written by Kamil Cukrowski
Licensed jointly under Beerware License and MIT License.
EOF
}
args=$(getopt -n "$name" -o d:h -- "$@")
eval set -- "$args"
database=/tmp/database.txt
while (($#)); do
case "$1" in
-d) database=$2; shift; ;;
-h) usage; exit; ;;
--) shift; break; ;;
esac
shift
done
if ((!$#)); then usage; exit 1; fi;
if [[ -e "$database" ]]; then
echo "Using $database"
else
echo "Creating $database"
# list all ld search paths
ld --verbose | grep SEARCH_DIR | tr -s ' ;' '\n' |
# In a format something we can eat
sed 's/SEARCH_DIR("\(.*\)")/\1/' |
# Resolve symlinks, remove duplicates
# Remove non-existent directories
xargs -d'\n' -n1 sh -c '
set -- "$(readlink -f "$1")"
if [ -e "$1" ]; then
printf "%s\n" "$1"
fi
:
' _ |
sort -u |
# List all .so and .a files from that dir
# Calling `file` would be very slow
xargs -d'\n' -I{} find {} -mindepth 1 -maxdepth 1 -type f \
'(' -name 'lib*.so.*' -o -name 'lib*.a' ')' |
# list filename and symbol in each library
(
# we list all symbols listed in any elf section
list_symbols() {
readelf -Ws "$1" |
sed '/^ *[^ ]*: *[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* * [0-9]\{1,\} *\([^ ]\{1,\}\)$/!d; s``\1\t'"$1"'`' ||: |
sort -u
# log the filename that we are ready
echo "Indexed: $1" >&3
}
export -f list_symbols
# extra stdbuf -oL so that buffering can't touch this
# I guess we should be safe till _POSIX_PIPE_BUF
stdbuf -oL xargs -P$(nproc) -n1 \
stdbuf -oL bash -c 'list_symbols "$@"' _
) |
# sort it
sort -t $'\t' -u -o "$database"
fi 3>&1
for i in "$@"; do
look -t $'\t' "$i" "$database" |
grep -F "$i"$'\t'
done
Итак, мы можем запустить:
$ ,ld_find_symbol pthread_create
...
pthread_create /usr/lib/libasan.so.5.0.0
pthread_create /usr/lib/liblsan.so.0.0.0
pthread_create /usr/lib/libpthread.a
pthread_create /usr/lib/libtsan.so.0.0.0
Найден символ Och. Итак, теперь мы можем:
$ gcc /tmp/1.c -l:libpthread.a
... errors ....
/usr/bin/ld: (.text+0x202e): undefined reference to `_dl_stack_flags
Итак, мы можем еще раз:
$ ,ld_find_symbol _dl_pagesize
/usr/lib/libc.a
И исправить это с помощью:
$ gcc /tmp/1.c -l:libpthread.a -l:libc.a
Может быть, с некоторой работой это может быть Сценарий для автоматической работы и автоматического обнаружения недостающих символов. Тем не менее, для этого еще много работы.