静态链接是否允许跨平台执行?

我很好奇静态链接的 C 可执行文件如何在不同的环境中工作。假设我们编译我们的 C 代码以针对 x86 MacO,并且我们静态地包含它在可执行文件中使用的所有内容(print、strlen)。如果我们包含它需要的每个库,什​​么真正阻止这个可执行文件在 Windows 操作系统中运行?我知道文件格式可能不同并且会中断,但除此之外,这在技术上是否能够运行?

回答

我知道你从哪里来,操作系统让我们作为程序员认为库是编程的最终目的,调用库是使复杂的事情发生所需要的一切,并且一切都包含在他们。

但事实是,库大多提供了一个抽象层。例如,让我们创建一个名为“hello_world.so”的库,它会打印“Hello World!” 到控制台。我们创建的那个库依赖于 stdio 来处理复杂的 I/O 内容,但 stdio 本身至少依赖于另一件事:内核(某些特定目标在没有内核的情况下工作,但这些系统超出了本答案的范围)。

在桌面世界中,事情会变得非常复杂,即使在空闲系统中,我们也有数百个进程同时运行,所有这些应用程序都需要访问硬件(可能也是同时),因此决定需要一个控制器,某些软件可以协调在同一台计算机上运行的所有其他软件。这块软件通常称为内核。在 Windows 上是 NT 内核,在 macOS 上是 XNU,在 Linux 上是……Linux 内核!

在这些系统上,库的最大工作是抽象内核,让我们相信在 Linux 或 Windows 控制台上打印文本的工作方式完全相同,但实际上可能完全不同!像 stdio/time/etc 这样的库有不同的“实现”,但有相同的“接口”:从开发的角度来看,它们看起来是一样的,但它们实现目标的方式可能大不相同,它们可以进行转换,调用其他隐藏的或非隐藏功能......所有这些都可以从一个操作系统完全移植到另一个操作系统,但是当内核调用开始出现时,事情开始向南发展。

内核调用是程序与内核“对话”的方式。它们可以用来做成千上万种不同的事情,但例如有一个(或几个)请求内存(通常用 malloc 调用),一个打印到控制台,一个询问网络数据包是否到达,要求与您的 GPU 通话...这些系统调用从一个内核到另一个内核完全不同,有时甚至对于同一内核的两个版本!

这些“内核调用”是阻止您在 Windows 上运行静态编译的 linux 程序的唯一原因。

PS:尽管以上所有内容都是完全正确的,内核可以随心所欲地彼此不同,但由于内核和计算的历史,一些内核实际上共享相同的接口(即使它们的实现如您所料,可以完全不同)。我所知道的最好的例子是我所知道的大多数内核都是基于 UNIX 内核的。

这意味着——即使我自己从未测试过——我认为你应该能够静态链接一个 Linux 应用程序并在 Linux、大多数 BSD 甚至 macOS 上使用它


以上是静态链接是否允许跨平台执行?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>