运行时库#

为了说明即使是简单的程序也依赖于外部运行时库,以下是来自 ldd 实用程序的输出,该实用程序报告了此类依赖关系

$ ldd tabulate.exe
        ntdll.dll => /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll (0x7ff88f2b0000)
        KERNEL32.DLL => /cygdrive/c/WINDOWS/System32/KERNEL32.DLL (0x7ff88e450000)
        KERNELBASE.dll => /cygdrive/c/WINDOWS/System32/KERNELBASE.dll (0x7ff88b9e0000)
        cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000)
        cyggfortran-5.dll => /usr/bin/cyggfortran-5.dll (0x3efd20000)
        cygquadmath-0.dll => /usr/bin/cygquadmath-0.dll (0x3ee0b0000)
        cyggcc_s-seh-1.dll => /usr/bin/cyggcc_s-seh-1.dll (0x3f7000000)

其他编译器或同一编译器的其他版本可能需要不同的动态库。只要您在同一台计算机上运行程序——或者更准确地说,在同一环境中——就不会有任何问题。但是,当找不到此类库时,您将(希望)收到错误消息,并且程序会立即停止。

因此,了解需要哪些库是一件好事。在 Linux 和类 Linux 环境中,ldd 实用程序非常有用。在 Windows 上,您可能希望使用 dependency walker(最新版本,可在 Windows 10 上完美运行,位于此处:https://github.com/lucasg/Dependencies

您还应该知道程序尝试在何处查找这些库。这本身就是一个庞大的主题,充满了复杂性和历史。在这里,我们只是触及了表面

在 Linux 上

  • 使用环境变量 LD_LIBRARY_PATH。它由要搜索的目录列表组成,每个目录通过冒号 (:) 与其他目录分隔。例如:/usr/lib:/usr/local/lib — 典型的系统目录。

  • 在链接步骤中,您还可以使用一个选项来设置 RPATH,这是一个目录列表,将其放入可执行文件本身。

  • 然后还有几个要搜索的系统目录。

在 Windows 上

  • 包含可执行程序的目录也可能包含动态库。

  • 使用环境变量“PATH”。同样是搜索目录的列表,但现在分隔字符是分号 (;)。

  • 搜索一组系统目录。

不幸的是,详细信息可能会因操作系统的不同版本而异。以上仅仅是一个指示——使用“ldd”或“dependency walker”之类的工具来找出加载了哪些库以及在何处找到它们。

如果您想与同事、客户或遍布全球的用户共享您的程序,您必须注意,除了程序外,您还必须分发它依赖的库。有关更多信息:请参见下文。