You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用绝对路径链接共享库的差异与运行机制疑问

EDIT2: 我的问题最初没那么复杂,本质是我环境里的特殊GCC构建版本导致的(之前没发现)。具体机制我不清楚,但表现是:只要命令行里加了-L参数或者--no-undefined这类链接器选项,可执行文件就会在当前目录查找共享库。这就解释了为什么除了test6之外,其他测试结果看起来都跟LD_LIBRARY_PATH设成:或.时一样,尽管我的LD_LIBRARY_PATH确实没设置。

我之前一直以为用-L/some/path/ -lfoo和直接用/some/path/libfoo.so链接共享库效果完全一样(但之前从来没用过后者)。最近做了实验才发现两者明显有差异,搞不懂背后的核心机制。

我查过一些资料,但没法完全解释我用下面这个简单示例得到的结果:

测试代码

foo.c

int foo_func(int i)
{
    return i+1;
}

bar.c

#include <stdio.h>

extern int foo_func(int i);

int main(int argc, char *argv[])
{
    fprintf(stdout, "%d\n", foo_func(argc));
    return 0;
}

Makefile

clean:
    mkdir -p install
    rm -f ./install/*

########################

foo_simple: clean
    gcc foo.c -shared -fPIC -o ./install/libfoo.so

foo_soname: clean
    gcc foo.c -shared -fPIC -o ./install/libfoo.so -Wl,-soname=libfoo.so  

######################## 传统链接方式(用-L指定库目录)

bar_libdir_%: %
    gcc bar.c -L`pwd`/install -lfoo -o ./install/bar

######################## 不用-L,直接用绝对路径链接

bar_abspath_%: %
    gcc $(FLAGS) bar.c `pwd`/install/libfoo.so -o ./install/bar

bar_abspath_no_undefined_%: %
    gcc $(FLAGS) bar.c `pwd`/install/libfoo.so -o ./install/bar -Wl,-no-undefined

######################## 测试执行逻辑

sim1_%: %
    cd install ; ./bar

sim2_%: %
    ./install/bar

test1:  sim1_bar_libdir_foo_simple                 # 正常运行
test2:  sim1_bar_libdir_foo_soname                 # 正常运行
test3:  sim2_bar_libdir_foo_simple                 # 失败 - 加载共享库出错
test4:  sim2_bar_libdir_foo_soname                 # 失败 - 加载共享库出错

test5:  sim1_bar_abspath_foo_simple                # 正常运行
test6:  sim1_bar_abspath_foo_soname                # 失败 - 加载共享库出错
test7:  sim2_bar_abspath_foo_simple                # 正常运行
test8:  sim2_bar_abspath_foo_soname                # 失败 - 加载共享库出错

test9:  sim1_bar_abspath_no_undefined_foo_simple   # 正常运行
test10: sim1_bar_abspath_no_undefined_foo_soname   # 正常运行
test11: sim2_bar_abspath_no_undefined_foo_simple   # 正常运行
test12: sim2_bar_abspath_no_undefined_foo_soname   # 失败 - 加载共享库出错

补充说明:我的环境里LD_LIBRARY_PATH是未定义/未设置的。想先问下有没有人能复现我这12个测试的结果?

为了完整起见,Makefile包含了所有组合:是否用绝对路径、是否设置soname、是否用--no-undefined。不是所有组合都有研究价值,但我搞不懂以下几个关键问题:

  • 用-L/some/path/ -lfoo和/some/path/libfoo.so链接的差异很明显,比如test2和test6、test3和test7的结果对比。
  • 给共享库显式设置soname(之前看到有人推荐这么做)反而带来更多问题,比如test5和test6、test7和test8的结果差异。
  • --no-undefined不仅影响链接时的行为,还会影响运行时的行为,比如test6和test10的结果对比。

有没有技术人员能详细解释下这些现象背后的机制?

内容的提问来源于stack exchange,提问作者DaveC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 15:35:20