Опция G CC -l указана в случае большого количества библиотек - PullRequest
0 голосов
/ 01 мая 2020

Возможно, я что-то упускаю, но когда я компилирую свою программу с общими библиотеками *. Поэтому мне всегда приходится использовать -llib для каждой библиотеки, которую я использую.

Теперь у меня есть проект, который связывает против 40 из них (возможно) и учитывая, что этот «каркас» библиотеки довольно большой, совсем непросто выяснить, где находится каждая ссылка.

Нужно ли мне знать, в каком файле * .so есть это то, что я ищу или есть автоматический / более быстрый способ, например, использование -L для полного пути и указание здесь поиска компилятора?

Команда "ldd" может помочь в случае, если у меня есть подобное приложение, которое использует ту же библиотеку, но мне все еще нужно добавить их хотя бы один раз в gcc / makefile.

Это единственный способ или есть более быстрый / простой способ? Я понимаю, что у меня может быть 2 * .so файл с тем же именем функции, но в этот момент я был бы рад получить «переопределенную» ошибку.

Более того, как мне узнать, что такое * .so или Файл * .dll (даже * .a stati c lib) содержит с точки зрения возможных полезных ссылок?

Спасибо,

1 Ответ

0 голосов
/ 01 мая 2020

Нужно ли мне знать, в каком * .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

Может быть, с некоторой работой это может быть Сценарий для автоматической работы и автоматического обнаружения недостающих символов. Тем не менее, для этого еще много работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...