移植性一直是 Unix 的主要优势。Unix 程序员往往设想硬件是易变的,只有 Unix API 本是稳定的。

Unix 程序员往往尽量避免软件依赖于某种特殊易逝的技术, 而严谨地遵循开放标准。这
种考虑可移植性的编码习惯在 Unix 传统中根深蒂固,甚至应用于那些一次性小型单用途
的代码中。

可移植性最直接的效益是工具和应用程序无需每隔几年就重写,因为 Unix 软件比起原生的硬件平台来得长久,这是再正常不过的。

间接的益处并不明显但可能更为重要。可移植性的戒律往往在架构、接口和实现上施加了一种简单化的影响。这既提高了项目成功的几率也降低了生命期的维护成本。

#17.2 Unix 标准

#17.2.3 开源世界的 Unix 标准

大量的 Unix 发布者—随着 Linux 发布市场的统一,越来越清楚真正的问题是时间变化率。API 是稳定的,但是系统管理文件的预期位置、实用程序以及用户邮箱名和日志文件的前缀路径等常常发生变化。

#17.3 IETF 和 RFC 标准化过程

在 IETF 传统中,标准必须来自于一个可用原型实现的经验——但是一旦成为标准,同标准不一致的代码就被认定是不合规范的,必须无情地抛弃。

不幸地是,这并不是标准通常发展的方式。计算机历史充满了许多这样的例子,技术标准是别有企图研究的最糟糕特征与黑暗密室政治结合的产物一一这样产生的规格说明在任何曾经的实现中都找不到踪影。更糟糕的是,许多规范不是严苛得无法实际实现,就是说明不够充分,解决的问题远不如产生的困惑多。这些规范随之被塞给软件商,它们如果发现什么地方不易实现,就忽略掉标准。

IETF 的哲学已经被概括为著名的“我们反对国王、总统和投票。我们信任大致的共识和可运行代码”。

#17.4 规格 DNA,代码 RNA

IETF 传统反复教导我们将代码作为标准的从属物来思考。正是标准让程序可以协作,将各项技术结合起来成为比部分之和更大的整体。

在最好的 Unix 实践中,程序的文档就近似于规范主体的“提议标准”,需要不断修正订正。

以考虑周全的规格说明来驱动开发可能会引起“bug 还是功能”的小小争论;但没有正确实现规格说明的系统就是破损不全的,必须得到修正。
一个在 Bellevue 以东一家小公司工作的朋友奇怪,Linux 应用程序开发者为什么可以随着应用程序发布版本同步地进行 OS 改动。在那个公司里,主要的系统级 API 频繁改动以容纳一些古怪念头,所以基本的 OS 功能必须常常随着每个应用程序一起发布。
我向他描述了规格说明所具有的威力以及实现应当如何遵从规格,然后接着断言,如果一个应用程序按接口文档得到一个非预期的结果,那么不是违反了规格,就是发现了 bug。他认为这个观念非常令人吃惊。
分辨这类 bug 再简单不过了,只要检查接口实现是否违反了规格。当然,如果有实现的源码会更简单。
—— Keith Packard

#17.5 可移植性编程

软件可移植性通常是准空间问题:代码可以从其诞生的环境移到别的硬件和软件平台吗?但是几十年的 Unix 经验告诉我们时间上的持久性同样重要,甚至更重要。软件的未来如果可以详细地预测,最好现在就来预测——然而,在可移植性编程中,我们应该尝试考虑选定最可能持续的软件环境特征作为构建软件的基础,同时要避免不久的将来就可能消亡的技术。

#17.7 可移植性、开放标准以及开放源码

IETF 自从大约 1997 年前后,愈发抵制连一个开源基准实现都没有的 REC 成为预备标准将来与某标准是否一致,似乎愈发有可能以“是否同已经得到标准作者们认可的开源实现相一致(或者完全使用该实现)”来判定。

暗含的意思就是,成为标准的最好办法就是发布一个高质量的开源实现
Henry Spencer

最后,确保代码移植性最有效的一个环节就是不要依赖于专有技术。永远不会知道所依赖的闭源库 / 工具 / 代码生成器或网络协议何时会结束生命,接口何时会以某种非向后兼容的方式改变,从而崩溃掉已有的项目。而使用开源代码,即使前沿版本的改变方式足以崩溃已有的项目,也有前行之路:因为可以获取源码,如果需要,就可以向前移植项目到新的平台。