当前位置: 首页 > news >正文

LGPL与闭源程序

为什么80%的码农都做不了架构师?>>>   hot3.png

最近一直在学习 Qt。Qt 有两个许可证:LGPL 和商业协议。这两个协议在现在的 Qt 版本中的代码是完全一致的(潜在含义是,Qt 的早期版本,商业版的 Qt 通常包含有一些开源版本所没有的库,比如 QtSingleApplication 这个库)。所以现在对于普通开发人员和部分商业公司来说,使用 LGPL 版本的 Qt 可以节省很大的开销。这两个版本最大的区别在于,前者是免费的,后者是收费的。既然代码都是一致的,所以费用就要是用来购买 Qt 的售后服务和培训等等相关服务。

现在我们是来说一下版权的问题。LGPL 是一个开源协议,因此,有人会担心 LGPL 能否用于开发闭源程序,能够拿来卖钱。尽管现在国内有些公司不是很重视这方面的问题,不过,如果你违反了协议,某一天被别人发来一纸律师函的时候,真的是欲哭无泪了哦。所以,我们还是先来研究一下这个协议,LGPL 究竟能不能用于开发闭源程序。

以下内容是我查找了 N 多网站总结出来的,因为豆子不是律师,所以 LGPL 协议基本看不懂。究竟怎样去理解这个协议,还是希望能够有专业人士说出来。这里就算做是一种抛砖引玉吧!尽管没有十分的确定,但是这里所说的理解基本也是八九不离十的了。

至于什么是 LGPL 协议,这里就不再多说了,我们关心的是,如果使用 LGPL 协议开发商业程序。请注意,这里所说的闭源程序,是指不以某种形式开放源代码,也就是说,用户(包括其他开发者)不能获取其源代码的程序。首先说明一点,LGPL协议是一个商业友好的协议。这里的含义是,你可以用 LGPL协议开发商业程序,当然也可以是非商业的闭源程序。但是,它是有一些限制的。这就是我们要讨论的重点。

既然我们已经对其定性,那么我们直接进入主题:使用 LGPL 协议开发闭源程序,如果你使用动态链接的形式,那么,你可以以任何形式发布你的应用程序,商业的、非商业的、开源的、非开源的,随你。

如果你因某种原因必须静态链接一个基于 LGPL 协议发布的库(一下我们简称为 LGPL 库),那么,你有义务进行下面的工作:

  1. 你必须在你的文档中说明,你的程序中使用了 LGPL 库,并且说明这个库是基于 LGPL 发布的;
  2. 你必须在你的应用程序发布中包含一份 LGPL协议,通常就是那个文本文件;
  3. 你必须开放使用了 LGPL 库代码的所有代码,例如某些封装器。但是,其他使用这些封装器的代码就不需要开放了;
  4. 你必须包含你的应用程序的余下部分的目标文件(通常就是我们所说的 .o 等等),或者是其他等价的文件。源代码并不是必须的。

是不是很难理解呢?我们详细的说一下。

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

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

好了,如果你还不明白如何使用,我们来看一个例子。

假设我们使用一个名为 Lib 的库,这个库是基于 LGPL协议发布的。如果你使用 Lib.dll 做动态链接(Windows 下),好,一切 OK。无论你的程序怎么样,你都可以做你所做的事情。

我们主要是来看,如果你要使用静态链接,那么你需要如何组织你的代码。如果你有一个 main.cpp(我们假设所有 Lib 库的函数都是用了 lib_ 前缀):

 
  1. // main.cpp 
  2. int main() { 
  3.     lib_init(); 
  4.     lib_do_something(); 
  5.     lib_done(); 
  6.     lib_close(); 
  7.  
  8.     return 0; 

现在你已经完成了 main.cpp,但是你必须把它开源!因为它使用了 LGPL 库的代码。这是上面第三条规定的。我不想把它开源,怎么办呢?好,我们建一个新的文件 lib_wrapper.cpp:

 
  1. void my_lib_init() 
  2.     lib_init(); 
  3.  
  4. void my_lib_do_something() 
  5.     lib_do_something(); 
  6.  
  7. void my_lib_done() 
  8.     lib_done(); 
  9.  
  10. void my_lib_close() 
  11.     lib_close(); 

在 main.cpp 中,我们做相应的修改:

 
  1. int main() { 
  2.     my_lib_init(); 
  3.     my_lib_do_something(); 
  4.     my_lib_done(); 
  5.     my_lib_close(); 
  6.  
  7.     return 0; 

现在,main.cpp 不再是直接使用了 LGPL 库的代码了,因此它不需要开源,而我们的封装器 lib_wrapper.cpp 必须开源。

好,编译一下我们的程序,你会得到 main.o(Windows 下)这个目标文件。

在最终程序的发布中,你需要包含一下文件:

  1. 一份文档,其中声明:这个程序使用了 Lib库,这个库是基于 LGPL 协议发布的;
  2. LGPL.txt;
  3. lib_wrapper.cpp
  4. main.o

这样,用户可以通过修改 lib_wrapper.cpp  的内容改变你使用 LGPL 库的方式,例如:

 
  1. void my_lib_done() 
  2.     lib_done(); 
  3.     lib_close(); 
  4.  
  5. void my_lib_close() 
  6.     // lib_close(); 

然后编译这个 lib_wrapper.cpp,最终重新链接。一个新的可执行程序诞生啦!

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

附件中是 LGPL协议的文本文件。

转载于:https://my.oschina.net/mskk/blog/2980790

相关文章:

  • 聊聊flink的checkpoint配置
  • 堆的python实现及其应用
  • 创建一种深思熟虑的文化
  • 亚马逊Alexa借助神经网络生成播音员声音
  • 将VCSA 6.5添加到AD域
  • nginx 4层tcp代理获取真实ip
  • 刘鹏教授在新闻出版大数据应用管理技术专题培训班上作报告!
  • Mybatis配置返回为修改影响条数
  • spring源码-aop源码-5.1
  • 洛谷P2805 植物大战僵尸
  • python之上下文管理器与contextlib
  • 数据类型之函数笔记
  • Flutter redux 进阶
  • 为什么携程要做好持续交付?
  • 变频电源老化测试重要吗?需要做老化测试吗
  • AHK 中 = 和 == 等比较运算符的用法
  •  D - 粉碎叛乱F - 其他起义
  • ERLANG 网工修炼笔记 ---- UDP
  • HTTP 简介
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JavaScript设计模式之工厂模式
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Python - 闭包Closure
  • Spring-boot 启动时碰到的错误
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • Webpack 4x 之路 ( 四 )
  • 对象管理器(defineProperty)学习笔记
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 七牛云假注销小指南
  • 强力优化Rancher k8s中国区的使用体验
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 一个项目push到多个远程Git仓库
  • 用Python写一份独特的元宵节祝福
  • 再谈express与koa的对比
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 《天龙八部3D》Unity技术方案揭秘
  • Linux权限管理(week1_day5)--技术流ken
  • PostgreSQL之连接数修改
  • 进程与线程(三)——进程/线程间通信
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #13 yum、编译安装与sed命令的使用
  • #QT(一种朴素的计算器实现方法)
  • (C语言)字符分类函数
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (安卓)跳转应用市场APP详情页的方式
  • (独孤九剑)--文件系统
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (规划)24届春招和25届暑假实习路线准备规划
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (十三)Flask之特殊装饰器详解
  • (四)linux文件内容查看
  • (一)为什么要选择C++
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...