Rust 为什么可执行文件依赖于glibc?

Rust 为什么可执行文件依赖于glibc?,rust,Rust,是因为Rust标准库通过glibc调用内核系统调用吗?但是,用Rust本身编写系统调用包装不是很难吗?库/二进制文件不应该直接调用系统调用,而应该始终调用相应的函数: 只要实现了合适的底层库,二进制文件就可以在不同的操作系统上运行 您可以使用LD_PRELOADlivrary覆盖库函数 POSIX在一级定义了一个API,但不强制任何类型的系统调用约定 例如,Wine项目通过提供在本机libc之上实现Windows API的库来运行Windows程序。如果有一个程序直接进行Windows系统调

是因为Rust标准库通过glibc调用内核系统调用吗?但是,用Rust本身编写系统调用包装不是很难吗?

库/二进制文件不应该直接调用系统调用,而应该始终调用相应的函数:

  • 只要实现了合适的底层库,二进制文件就可以在不同的操作系统上运行
  • 您可以使用
    LD_PRELOAD
    livrary覆盖库函数
POSIX在一级定义了一个API,但不强制任何类型的系统调用约定

例如,Wine项目通过提供在本机libc之上实现Windows API的库来运行Windows程序。如果有一个程序直接进行Windows系统调用,Wine将无法执行任何操作,因为Wine不实现系统调用,而只在库级别实现Windows API

此外,Rust在libc和其他库中调用了许多其他东西:

  • malloc
    free
  • pthread_mutex
    pthread_cond
  • strcmp
    strlen
    strncpy
  • qsort
    b搜索

当一种语言基于C库时,其库调用通常如下所示:

Language API -> C API -> System API
当一种语言不使用C库时,它的库调用直接委托给系统API:

Language API -> System API

当你在中间有C API时,语言API的实现将更简单,因为你几乎不需要编写任何OS特定的代码。这反过来又使跨平台语言变得更容易——您只需委托给跨平台C库,而不用考虑如何使用特定于平台的具体函数


原则上,Rust中没有任何东西可以阻止您删除C库并直接使用系统调用。正如您所注意到的,Go正是这样做的。但是,Rust开发人员并不认为依赖libc会给在标准库中编写那么多平台特定代码带来负担。

您是在“正常”可执行文件的上下文中问这个问题的(
rustc foo.rs
)或者说@Shepmaster normal executablesAFAIK golang可执行文件不依赖glibc,我还没听说这会导致任何问题。那么为什么Rust不能做到这一点呢?我对Go不太了解,但Go中的Hello World是1.9 MiB,而Rust中的Hello World是320 KiB(在OSX上,两者都没有特殊的编译选项)。也许Go只是简单地将glibc(或任何平台库)编译成二进制?Go(通常)不静态地包含libc:
du-hc$(strace-f Go build test.Go 2>&1 | grep open | grep-o'/.\\.a'| grep/usr | uniq)
告诉我它只链接自己的静态库(包括
syscall.a
)。@alice“没有引起任何问题”是错误的,这引入了错误。它们当然已经被修复,但确实发生了。