语义版本控制是否适用于源或二进制兼容性?

Pau*_*per 10 version backwards-compatibility semantic-versioning

此问题适用于使用一种语言("源")编写的任何语言,例如C或Java,并使用动态链接分布在另一种语言("二进制")中,例如机器代码或Java字节代码.


假设用户已在使用我的库的版本A. 我发布了更新的版本B.

如果他可以在不改变B的情况下编译他的代码并且正确地使用B运行,则从A到B的改变被认为是源兼容的.

如果他可以针对A编译他的代码并且正确地使用B运行,则从A到B的改变被认为是二进制兼容的.当使用没有隔离模块加载的传递依赖图(例如OSGI)时,这种情况很常见.X是根据某些版本的Y和Z编译的,Y是针对不同的某个版本的Z编译的.在运行时,Y对Z的调用可能不正确并且可能会崩溃.

变更可能与源兼容,但二进制不兼容.变更也可能是源不兼容和二进制兼容的.

我使用哪种兼容性进行语义版本控制?我是否使用源兼容性来区分主要和次要/补丁更新,还是使用二进制兼容性来区分主要和次要/补丁更新?


我目前的动机是Scala库.Scala二进制兼容性可能非常难以分析,需要很好地理解编译器细节.源兼容性和二进制不兼容是很常见的.

这不是一些奇怪的边缘情况; 这个问题可以出现在大多数编译的动态链接语言中.

Pau*_*per 8

几个月后,我想我得出了一个好结论.

语义版本控制应考虑两者,并遵循"最改变"的版本.

  • 打破源代码编译是对库用户的不兼容更改.
  • 打破运行时执行是对库用户的不兼容更改.

如果源兼容性或二进制兼容性发生变化,它应该 - 根据语义版本控制 - 是一个新的主要版本.

就我而言,Scala的二进制兼容性有时候很难确定.有几种JAR API 差异工具,例如JDiff.