【问题标题】:GCC -l option across specified in case of a high number of libraries在大量库的情况下指定的 GCC -l 选项
【发布时间】:2020-05-01 14:01:06
【问题描述】:

也许我遗漏了一些东西,但是当我使用共享库编译我的程序时 *.所以我总是必须为我正在使用的每个库使用 -llib。

现在我有一个项目链接到其中的 40 个(可能),并且鉴于这个库的“框架”相当大,要找出每个引用的位置并不容易。

我真的必须知道在哪个 *.so 文件中有我要查找的内容,还是有自动/更快的方法,例如使用 -L 作为完整路径并告诉编译器在此处搜索?

如果我有一个使用相同库的类似应用程序,但我仍然需要在 gcc/makefile 中添加它们至少一次,“ldd”命令可能会有所帮助。

这是唯一的方法还是有更快/更简单的方法?我知道我可能有 2 个具有相同函数名称的 *.so 文件,但那时我很乐意收到“重新定义”错误。

此外,我如何找出 *.so 或 *.dll(甚至 *.a 静态库)文件在可能的可用引用方面包含的内容?

谢谢,

【问题讨论】:

  • Is this the only way or is there a faster/simpler way?Moreover how do i find out what 似乎是不同的问题。

标签: gcc linker shared-libraries


【解决方案1】:

我真的必须知道在哪个 *.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

也许通过一些工作可以编写脚本以自动神奇地工作并自动检测丢失的符号。不过,左派还有很多工作要做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2016-04-28
    • 2015-12-30
    • 2017-06-30
    • 2013-01-04
    相关资源
    最近更新 更多