Redian新闻
>
编译代码时动态地链接库 | Linux 中国

编译代码时动态地链接库 | Linux 中国

科技
 
导读:编译软件在你如何运行你的系统方面给你很大的灵活性。LD_LIBRARY_PATH 变量,以及 GCC 的 -L 和 -l 选项,是这种灵活性的组成部分。
本文字数:3336,阅读时长大约:4分钟

编译软件在你如何运行你的系统方面给你很大的灵活性。LD_LIBRARY_PATH 变量,以及 GCC 的 -L 和 -l 选项,是这种灵活性的组成部分。

编译软件是开发者经常做的事情,在开源世界中,一些用户甚至选择自己动手。Linux 播客 Dann Washko 称源码为“通用包格式”,因为它包含了使一个应用在任何平台上运行所需的所有组件。当然,并不是所有的源码都是为所有的系统编写的,所以它只是在目标系统的子集内是“通用”的,但问题是,源码是非常灵活的。有了开源,你可以决定代码的编译和运行方式。

当你在编译代码时,你通常要处理多个源文件。开发人员倾向于将不同的类或模块放在不同的文件中,这样它们可以被单独维护,甚至可能被不同的项目使用。但当你编译这些文件时,许多文件会被编译成一个可执行文件。

这通常是通过创建共享库来完成的,然后从可执行文件中动态链接回它们。这样可以通过保持模块化功能的外部性来保持可执行文件的小型化,并确保库可以独立于使用它们的应用而被更新。

在编译过程中定位一个共享对象

当你 用 GCC 编译🔗 opensource.com 时,你通常需要在你的工作站上安装一个库,以便 GCC 能够定位到它。默认情况下,GCC 假定库在系统库路径中,例如 /lib64 和 /usr/lib64。然而,如果你要链接到一个你自己的尚未安装的库,或者你需要链接到一个没有安装在标准位置的库,那么你必须帮助 GCC 找到这些文件。

有两个选项对于在 GCC 中寻找库很重要:

◈ -L(大写字母 L)在 GCC 的搜索位置上增加一个额外的库路径。
◈ -l(小写字母 L)设置你要链接的库的名字。

例如,假设你写了一个叫做 libexample.so 的库,并且你想在编译你的应用 demo.c 时使用它。首先,从 demo.c 创建一个对象文件:

  1. $ gcc -I ./include -c src/demo.c

-I 选项在 GCC 搜索头文件的路径中增加了一个目录。在这个例子中,我假设自定义头文件在一个名为 include 的本地目录中。-c 选项防止 GCC 运行链接器,因为这个任务只是为了创建一个对象文件。结果如下:

  1. $ ls
  2. demo.o include/ lib/ src/

现在你可以使用 -L 选项为你的库设置一个路径,然后进行编译:

  1. $ gcc -L`pwd`/lib -o myDemo demo.o -lexample

注意,-L 选项在 -l 选项之前。这很重要,因为如果在你告诉 GCC 查找非默认库之前没有将 -L 添加到 GCC 的搜索路径中,GCC 就不知道要在你的自定义位置上搜索。编译成功了,但当你试图运行它时,却出现了问题:

  1. $ ./myDemo
  2. ./myDemo: error while loading shared libraries:
  3. libexample.so: cannot open shared object file:
  4. No such file or directory

用 ldd 排除故障

ldd 工具可以打印出共享对象的依赖关系,它在排除类似问题时很有用:

  1. $ ldd ./myDemo
  2. linux-vdso.so.1 (0x00007ffe151df000)
  3. libexample.so => not found
  4. libc.so.6 => /lib64/libc.so.6 (0x00007f514b60a000)
  5. /lib64/ld-linux-x86-64.so.2 (0x00007f514b839000)

你已经知道定位不到 libexample,但 ldd 输出至少确认了它对工作库的期望位置。例如,libc.so.6已经被定位,ldd 显示其完整路径。

LD_LIBRARY_PATH

LD_LIBRARY_PATH 环境变量🔗 opensource.com 定义了库的路径。如果你正在运行一个依赖于没有安装到标准目录的库的应用程,你可以使用 LD_LIBRARY_PATH 添加到系统的库搜索路径。

有几种设置环境变量的方法,但最灵活的是在运行命令前放置环境变量。看看设置 LD_LIBRARY_PATH 对 ldd 命令在分析一个“损坏”的可执行文件时的作用:

  1. $ LD_LIBRARY_PATH=`pwd`/lib ldd ./
  2. linux-vdso.so.1 (0x00007ffe515bb000)
  3. libexample.so => /tmp/Demo/lib/libexample.so (0x0000...
  4. libc.so.6 => /lib64/libc.so.6 (0x00007eff037ee000)
  5. /lib64/ld-linux-x86-64.so.2 (0x00007eff03a22000)

这也同样适用于你的自定义命令:

  1. $ LD_LIBRARY_PATH=`pwd`/lib myDemo
  2. hello world!

然而,如果你移动库文件或可执行文件,它又会失效:

  1. $ mv lib/libexample.so ~/.local/lib64
  2. $ LD_LIBRARY_PATH=`pwd`/lib myDemo
  3. ./myDemo: error while loading shared libraries...

要修复它,你必须调整 LD_LIBRARY_PATH 以匹配库的新位置:

  1. $ LD_LIBRARY_PATH=~/.local/lib64 myDemo
  2. hello world!

何时使用 LD_LIBRARY_PATH

在大多数情况下,LD_LIBRARY_PATH 不是你需要设置的变量。按照设计,库安装到 /usr/lib64 中,因此应用自然会在其中搜索所需的库。在两种情况下,你可能需要使用 LD_LIBRARY_PATH

◈ 你正在编译的软件需要链接到本身刚刚编译但尚未安装的库。良好设计的构建系统,例如 Autotools🔗 opensource.com 和 CMake🔗 opensource.com,可以帮助处理这个问题。
◈ 你正在使用设计为在单个目录之外运行的软件,它没有安装脚本,或安装脚本将库放置在非标准目录中。一些应用具有 Linux 用户可以下载、复制到 /opt 并在“不安装”的情况下运行的版本。LD_PATH_LIBRARY 变量是通过封装脚本设置的,因此用户通常甚至不知道它已被设置。

编译软件为你在运行系统方面提供了很大的灵活性。LD_LIBRARY_PATH 变量以及 -L 和 -l GCC 选项是这种灵活性的组成部分。


via: https://opensource.com/article/22/5/compile-code-ldlibrarypath

作者:Seth Kenlon 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出


LCTT 译者 :geekpi
💎💎💎💎
翻译: 1704.5 篇
|
贡献: 3149 天
2013-10-25
2022-06-09
https://linux.cn/lctt/geekpi
欢迎遵照 CC-BY-SA 协议规定转载,
如需转载,请在文章下留言 “转载:公众号名称”,
我们将为您添加白名单,授权“转载文章时可以修改”。

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
美国三军:"要盯着中国"8岁的孙女也滑得有模有样了Fudgie?令人惊叹的 Budgie 桌面即将登陆 Fedora Linux | Linux 中国使用 dnf 进行 Linux 包管理 | Linux 中国在虚拟机中运行 Linux 的十大优点 | Linux 中国GNU C 编译器的程序员入门指南 | Linux 中国写给老婆大人的两首诗使用 watch 和 tail 命令监视 Linux 上的活动 | Linux 中国好消息!Docker Desktop 现已支持 Linux | Linux 中国你的 Linux 启动时有几只小企鹅? | Linux 中国英伟达在提升 Linux 上的 GPU 使用体验上迈出了一大步 | Linux 中国用 Gwenview 在 Linux 上裁剪和调整照片大小 | Linux 中国如何在 Linux 和 Windows 电脑之间共享文件 | Linux 中国Linux 中国开通播客频道:“开源朗读者”和“硬核观察” | Linux 中国上一个说“丼”不读jǐng的人,已经被我骂哭了实测 Linux Mint 升级工具 | Linux 中国Archinstall 新的菜单系统让安装 Arch Linux 更容易了 | Linux 中国如何在 Linux 桌面中启用 “激活 Linux” 水印通知 | Linux 中国我如何在 Linux 上扫描家庭照片 | Linux 中国最适合程序员的 10 款 Linux 发行版 | Linux 中国HydraPaper:一个支持多显示器的 Linux 壁纸管理器 | Linux 中国在 Linux 上使用 sudo 命令的 5 个理由 | Linux 中国微软还有另一个 Linux 发行版,而且是基于 Debian 的 | Linux 中国Linux 上静态链接库工作原理 | Linux 中国实时动态|Midterm期间你需要知道的大事件在 Ubuntu Linux 如何安装 H.264 解码器 | Linux 中国乌东之战结局将决定今后二十年如何从源码编译 GNOME Shell 和应用 | Linux 中国使用 apt 进行 Linux 包管理 | Linux 中国在美国69. 作假夫妻工吗?Fedora Linux 36 发布 | Linux 中国实时动态|春季末你需要知道的大事件如何在 Linux 上动态链接模块库 | Linux 中国分享 8 篇使用 Linux 命令行的技巧 | Linux 中国硬核观察 #683 不值得使用 -O3 来编译 Linux 内核
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。