理解LGPL协议
2013-05-26 07:09:06 阿炯

LGPL(GNU Lesser General Public License)GPL的一个为主要为类库使用设计的开源协议,被用于一些(但不是全部)GNU程序库。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。 LGPL 允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并发布和销售。

但是如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。GPL/LGPL都保障原作者的知识产权,避免有人利用开源代码复制并开发类似的产品。

对于LGPL能否以及怎样用于开发闭源程序需要做重点分析。因为其他的开源许可协议在这点上很容易理解,而LGPL协议的条款本身则比较拗口。我们关心的是,如何使用LGPL协议开发商业程序。请注意这里所说的闭源程序,是指不以某种形式开放源代码,也就是说用户(包括其他开发者)不能获取其源代码的程序。首先说明一点,LGPL协议是一个商业友好的协议。这里的含义是,你可以用LGPL协议开发商业程序,当然也可以是非商业的闭源程序。但是,它仍有一些限制的。

既然我们已经对其定性,那么我们直接进入主题:使用LGPL协议开发闭源程序,如果你使用动态链接的形式,那么你可以以任何形式(商业的、非商业的、开源的、非开源的等等)发布你的应用程序。因为动态链接并没有把LGPL函数库的二进制内容包含到我们的应用程序可执行文件体中,严格地说这并非LGPL函数库的衍生作品,因而不在LGPL许可证的范围之内。对于二进制的LGPL动态链接库能否打包到闭源程序的安装包中一起发布(这对发布商业软件至关重要,否则程序根本就无法使用),在LGPL协议中并没有做规定,这完全取决于函数库的官方。LGPL协议只涉及源代码的版权,并不针对编译好的.dll库(或.so库)。如果你要使用官方编译好的动态库,要确定它没有额外的版权或者版权允许你自由发布它。你也可以自行编译dll库来使用(不修改源码),而不是使用官方编译好的。当然也要看官方的说明,但如果对自行编译的动态库官方都声称会带上额外的版权,那LGPL就没有存在的意义了。

通常很多LGPL库的官方并没有对编译好的动态库的分发做特别规定(除非是第三方编译的动态库,可能会有一些自行的规定),你最好要先取得他们的分发授权。一般的原则是只要不修改源代码并且动态链接,你是完全可以发布编译好的库,也可以和你的闭源软件一同发布,这是没有问题的。在你的软件版权声明中说明使用了哪些LGPL库,并确保软件使用者了解这些库来自哪里,以便能获得LGPL库的源码。在发布的软件中也要包含函数库的原有LGPL版权声明(LGPL.txt)。注意对于库的分发,LGPL的重点在于不修改源码、动态链接、不修改原来LGPL库的分发版权,并提供原有的版权声明。

如果你因某种原因必须静态链接一个基于LGPL协议发布的库,这会在应用程序可执行文件中包含LGPL函数库的一部分内容,从而成为函数库的衍生作品。那么,你有义务进行下面的工作:
(1).你必须在你的文档中说明,你的程序中使用了LGPL库,并且说明这个库是基于LGPL发布的;
(2).你必须在你的应用程序发布中包含一份LGPL协议,通常就是那个文本文件;
(3).你必须开放使用了LGPL库代码的所有代码,例如某些封装器。但是其他使用这些封装器的代码就不需要开放了;
(4).你必须包含你的应用程序余下部分的目标文件(通常就是我们所说的.o,.obj等等),或者是其他等价的文件。源代码并不是必须的。

是不是很难理解呢?我们来详细说明一下。第一条很容易理解;第二条也很容易理解,你可以在此处找到LGPL协议的内容,复制下来随你的程序一起发布就可以了。第三条就不那么好理解了。简单来说,LGPL协议要求,如果你的类使用了LGPL库的代码,那么必须把这个类开源。例如,如果程序app.exe每个源文件都使用了LGPL库的代码,那么所有源代码都要开源并遵守LGPL。为了避免这种情况,我们通常编写一个封装器,把LGPL库的代码封装起来,这样就只需要开放这个封装器的代码,而其他使用了这个封装器的代码就不需要开放。第四条是对第三条的一种补充:那些使用了封装器的程序不需要开源,但是你必须把你编译的那些中间文件开放出来,比如gcc编译器的那些.o目标文件。

为什么LGPL协议要这样规定呢?原来LGPL所做的工作是,它保证了库的使用者能够有这样一种能力:修改你使用LGPL库函数的方式(那些封装器就是你使用LGPL库的方式,现在已经开源了),重新编译这些代码,然后重新对程序进行连接(连接所需要的目标文件也是包含了的,这是第四条规定的),就可以得到一个新的可执行程序。

可见静态链接LGPL库时软件虽然可以只开放部分源代码,但其他用户仍然可以修改其中使用LGPL库的那部分代码。当LGPL库被重新设计或修复bug时,软件用户可以修改使用LGPL库的那部分代码,重新链接成新的程序。实际上,LGPL许可证的宗旨和精神是禁止将自由软件成为专用和独享的软件(GPL也是这样),因此至少应该确保其他用户也能通过某种途径使用这个LGPL函数库的接口,在你的软件中开放使用了LGPL库的那部分代码就是为了做到这一点。LGPL也具有传染性,但限制在其基础上开发的库上,而并不限制使用它的程序本身,它的传染性远小于GPL。

以上这就是在使用LGPL库开发闭源程序所需要遵守的东西,建议大家能够遵守协议,尊重原作者的劳动成果。