【问题标题】:Linux default libraries [closed]Linux默认库[关闭]
【发布时间】:2013-12-28 22:43:25
【问题描述】:

我知道在 Windows 上,默认情况下您会获得一些链接到您的进程的库,例如 kernel32.dll 等。Linux 上是否有任何等效的库?

我正在创建一些 Linux 二进制文件并寻找支持例程,尤其是 malloc 等。在 Windows 上,我只是在 HeapAlloc 之上实现了 malloc()(这也是 VS CRT 采用的方法)但我不确定在这里做什么。由于某些原因,如果可能的话,我不会在创建二进制文件时链接到 libc。

【问题讨论】:

  • 据我所知,libc 是由 gcc 自动链接的(我认为链接实际上是动态的,所以它不应该占用更多的二进制空间)。因此,您应该可以通过包含适当的标头来访问 malloc() 等。你打算使用哪个编译器?
  • 您实际上是在问默认库是什么,还是只需要有人指出“-nostdlib”?
  • AFAIK Linux 只响应系统调用,而 libc 几乎直接使用这些系统调用,并且唯一链接的东西是您正在使用的东西或它需要的东西。
  • 也许这就是你要找的stackoverflow.com/questions/2782010/…
  • @DeadMG 我认为您需要较低级别的调用来分配内存。请参阅我的答案中的编辑。可能是mmap 可以帮助你。

标签: c++


【解决方案1】:

默认情况下,Linux 中的 G++ 将链接 C 标准库和 C++ 标准库。有时它还会自动引入数学库,尽管从历史上看,您需要通过 -lm 来请求。

在我的 Ubuntu 机器上,我编译并链接了以下简单的“Hello World”应用程序:

#include <iostream>

int main()
{
    std::cout << "Hello world!" << std::endl;
}

我编译如下:g++ hello.cpp

ldd 实用程序列出了 g++ 链接的库:

$ ldd a.out
linux-vdso.so.1 =>  (0x00007fff1d344000)
libstdc++.so.6 => /usr/local/lib64/libstdc++.so.6 (0x00007fd7fb031000)
libm.so.6 => /lib/libm.so.6 (0x00007fd7fadae000)
libgcc_s.so.1 => /usr/local/lib64/libgcc_s.so.1 (0x00007fd7fab97000)
libc.so.6 => /lib/libc.so.6 (0x00007fd7fa813000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd7fb365000)

第一行,linux-vdso.so.1 实际上并不是一个库。如果您想了解一些魔法黑客,请在 Google 上搜索。其余的都是行人:

  • libstdc++ 是 C++ 标准库
  • libm 是前面提到的数学库。我不知道 C++ 是否默认包含它,但历史上 C 编译器不包含它,除非您在链接时指定 -lm
  • libgcc_s 是一个 GCC 特定的支持库,包含各种支持例程(即,用于奇怪的东西,如奇怪的划分、结构副本等)
  • libc 是 C 标准库。它还包含许多 POSIX 功能。
  • ld-linux-x86-64 是动态库加载器。这实际上是一个可执行文件

所以,这是套件的默认位。

mallocnewprintf 等片段以及完整的 C++ 标准库(有些人称之为“STL”)都在其中。

如果您要问默认提供哪些支持,就是这样。如果您尝试实现这些东西的自己的版本...... -nodefaultlibs 标志会让您。您可能还需要-ffreestanding,甚至可能需要-fno-builtins

如果您想了解这些部分是如何构建的(包括 glibc 如何调用 mmap 和/或 sbrk 以获取内存以填充 malloc 堆),您可以下载 glibc 的源代码并查看.除了直接进行系统调用之外,没有低于glibc 的级别可以直接定位。

假设您使用 GCC / G++ 构建代码,您可能需要包含其中一些库,例如 libgcc_slibstdc++。如果您不使用标准库函数,并使用-ffreestanding 构建,您可能能够限制/消除您对libstdc++ 的依赖。但是,老实说:我只知道旗帜,我从未使用过它。

【讨论】:

  • 很抱歉,这是您要的吗?
  • 你为什么不编译和链接这个:int main(){},看看什么是真正需要的?在您的代码中,您使用 iostream,这可能会引入一些依赖项
  • 仅供参考,尽管标准规定应该这样做,但-ffreestanding 对我来说表现不佳,但有例外;除非我也禁用异常,否则东西会中断。我收回了……它可以起作用,但我不得不包含像运行时库的内部异常东西一样嘎嘎作响的函数。
【解决方案2】:

我认为您需要一些较低级别的 API 来进行内存管理。那么这个question 可能会对你有所帮助。

它建议mmap 功能。希望对你有所帮助。

【讨论】:

  • 近 84k 代表,超过 60k 在 C 和 C++ 标签中。我相当肯定他知道如何链接(或不链接)。
  • 你说得对,但你从哪里知道,他之前不是在windows下编程,现在想换成linux?
【解决方案3】:

根据ldd,以下库默认链接到我的ubuntu linux机器上的g++ 4.8,用于基本的c++程序。

linux-vdso.so.1 =>  (0x00007fffe11fe000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1d1e49b000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1d1e285000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1d1debc000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1d1dbb8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1d1e7c7000)

您可以使用-nodefaultlibs 开关禁用链接它们,但您还需要指定它们需要稍后使用适当的开关链接。

【讨论】:

    【解决方案4】:

    在 Linux 上,glibc 相当于 Windows 库中的很多东西。 POSIX C 接口函数,包括 C 标准库以及内核系统调用包装器都在 libc 中。它是提供不同内核版本之间的 ABI 兼容性的主要包装层。不使用它是非常愚蠢的。

    Windows CRT 确实有不同的状态,因为 POSIX 在 Windows 上有不同的状态。 Win32 API 在 Windows 上提供 OS 接口的地方,在 Linux 上是 POSIX(包括 C stdlib!)。

    在 Linux 上,链接 glibc。

    您还需要链接一些编译器支持库,无论是 LLVM 的 compiler-rt 还是 GCC 的 libgcc。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多