gcc -L 命令混乱

gcc -L command confusion

假设我有一个共享库文件 libdemo.so,其中 libdemo.so 是最终的 linker.

如果我想构建可执行文件,并且如果库文件在当前工作目录中,我 link 它带有 -L. -ldemo 标志。

但是当我 运行 可执行文件时,除非我指定库路径 LD_LIBRARY_PATH=.,否则可执行文件找不到 link。那么为什么需要额外的 LD_LIBRARY_PATH 设置呢?这些标志用于 link-time 库路径,环境变量应该是 运行-time 库路径。

或者,如果我构建可执行文件并使用 -Wl,-rpath,. 指定 运行-time 库路径,我可以省略 -L. -ldemo.

我知道这与 link-time 和 运行-time 有关,但我不清楚有什么区别。例如,当不使用 -rpath 时,如果可执行文件需要 LD_LIBRARY_PATH 来查找库文件,-L. -ldemo 实际上做了什么?而在使用后一种方法时,如果指定-rpath意味着将目录位置复制到运行时的库路径中,为什么这也允许省略-L. -ldemo

如果link-time库路径和运行-time库路径不同,为什么后一种方法在构建时不需要link-time库路径? link-time 库路径和运行-time 库路径有什么区别?

因为 linking 是由两个不同的链接器实例完成的。

当您编译并link您的程序时,link像/usr/bin/ld一样检查外部引用并构建您的可执行文件添加外部引用libdemo.so

当你运行你的程序时,运行-time linker /lib64/ld-linux-x86-64.so.2(或者通常说ld.so)加载所有需要的共享对象-L没有保存的原因有几个:

  • libdemo.so 不必位于与编译期间相同的路径(因为您可以将二进制文件复制到另一台主机,该路径是内部构建路径等)
  • 它可能不安全,所以 ld.so 通常会查找 "trusted" 非根用户无法写入的路径列表

然而,有些情况下保存 -L 会有用(即软件安装到 /opt),因此 some 的 Unixes 引入了 RPATH。

经过一些研究(阅读教科书),我找到了我要找的答案。

基本上,由于可执行文件不再包含目标文件的副本,它需要一些方法来识别它需要的共享库。在link阶段,共享库的名称被嵌入到可执行文件中,但具体位置尚未指定。所以 -L. -ldemo 实际上只是提供库文件的名称。请注意,在问题中,我说在设置 -rpath 时未指定 -L. -ldemo。那是因为在该命令中我实际上直接传递了库的名称,libdemo.so。如果我没有这样做,那么需要用 -L. -ldemo 指定它。

后续提供运行-time库路径,指定执行时的准确位置