Anon Asked: 2015-07-29 22:16:57 +0800 CST2015-07-29 22:16:57 +0800 CST 2015-07-29 22:16:57 +0800 CST 什么是动态链接和静态链接? 772 我听到有关打包的术语“动态链接”和“静态链接”,但我一直不清楚这些术语的实际含义。 什么是动态链接和静态链接? packaging 1 个回答 Voted Best Answer zwets 2015-07-31T03:55:37+08:002015-07-31T03:55:37+08:00 这个问题真的应该分为两个:“什么是动态链接和静态链接?”,以及“Click 如何解决依赖问题?”。两者没有关系。在这里我将尝试回答第一个问题。 什么是动态链接和静态链接? 任何软件程序的源代码都使用外部函数。外部函数驻留在库中。当将程序编译成机器代码*时,外部引用必须以某种方式链接到它们的定义,即链接到它们在机器代码中的实现。有两种方法可以做到这一点。(a) 实现代码从库中“拉入”并添加到生成的二进制文件中,或者 (b) 引用悬而未决,将在运行时“指向”它们的实现。我们称之为 (a) 静态链接和 (b) 动态链接。 与任何工程决策一样,两种选择都不比另一种更好。静态链接的优点是不会创建对运行时环境的依赖,因此会生成更可预测的二进制文件。这是以代码重复为代价的,因此会消耗磁盘、网络和内存。动态链接允许在运行时共享库代码。它还支持升级库,例如在发现错误时,无需重新编译使用它们的二进制文件。所有受抚养人都会自动修复。显然,由于新版本引入的错误和不兼容性,它们也会自动损坏。 撇开利弊不谈,动态链接本质上会产生更复杂的系统。有更多的活动部件,尤其是活动部件之间存在依赖关系**。接下来的问题是如何管理这种复杂性。例如,如何在系统上拥有一个应用程序的两个版本,每个版本都需要自己的依赖项,其中可能有一个库的两个不同的次要版本。因为这些库的文件名会发生冲突,目前这在 Ubuntu 上是不可能的。 可以说,每一个打包系统,除了简化软件安装之外,都是一种尝试解决依赖性和版本控制问题,同时获得动态依赖性的好处。当时的 Debian 打包系统在这方面比现有的要好得多。从那时起,出现了许多其他解决方案。GNU Guix及其Guix 包管理器采用了一种非常彻底的方法。点击是另一个。 *) 我们假设程序编译为机器代码,而不是将被解释或编译为中间语言(例如 Python、Java)的程序。在抽象层面上,这些语言都面临着完全相同的动态解析问题(ClassNotFoundException在 Java 中),但将它们包括在这里只会混淆解释。 **) 请注意,如果您坚持使用静态链接的二进制文件,那么就不会有运行时相互依赖性。也就是没有库依赖,还有其他种类。
这个问题真的应该分为两个:“什么是动态链接和静态链接?”,以及“Click 如何解决依赖问题?”。两者没有关系。在这里我将尝试回答第一个问题。
什么是动态链接和静态链接?
任何软件程序的源代码都使用外部函数。外部函数驻留在库中。当将程序编译成机器代码*时,外部引用必须以某种方式链接到它们的定义,即链接到它们在机器代码中的实现。有两种方法可以做到这一点。(a) 实现代码从库中“拉入”并添加到生成的二进制文件中,或者 (b) 引用悬而未决,将在运行时“指向”它们的实现。我们称之为 (a) 静态链接和 (b) 动态链接。
与任何工程决策一样,两种选择都不比另一种更好。静态链接的优点是不会创建对运行时环境的依赖,因此会生成更可预测的二进制文件。这是以代码重复为代价的,因此会消耗磁盘、网络和内存。动态链接允许在运行时共享库代码。它还支持升级库,例如在发现错误时,无需重新编译使用它们的二进制文件。所有受抚养人都会自动修复。显然,由于新版本引入的错误和不兼容性,它们也会自动损坏。
撇开利弊不谈,动态链接本质上会产生更复杂的系统。有更多的活动部件,尤其是活动部件之间存在依赖关系**。接下来的问题是如何管理这种复杂性。例如,如何在系统上拥有一个应用程序的两个版本,每个版本都需要自己的依赖项,其中可能有一个库的两个不同的次要版本。因为这些库的文件名会发生冲突,目前这在 Ubuntu 上是不可能的。
可以说,每一个打包系统,除了简化软件安装之外,都是一种尝试解决依赖性和版本控制问题,同时获得动态依赖性的好处。当时的 Debian 打包系统在这方面比现有的要好得多。从那时起,出现了许多其他解决方案。GNU Guix及其Guix 包管理器采用了一种非常彻底的方法。点击是另一个。
*) 我们假设程序编译为机器代码,而不是将被解释或编译为中间语言(例如 Python、Java)的程序。在抽象层面上,这些语言都面临着完全相同的动态解析问题(
ClassNotFoundException
在 Java 中),但将它们包括在这里只会混淆解释。**) 请注意,如果您坚持使用静态链接的二进制文件,那么就不会有运行时相互依赖性。也就是没有库依赖,还有其他种类。