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库路径,指定执行时的准确位置
假设我有一个共享库文件 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库路径,指定执行时的准确位置