介绍
在项目中第三方代码的时候,要注意源码许可证问题,因为这涉及到:
- 使用和修改的条件是什么?
- 商用和分发的条件是什么?
- 本项目开源后使用什么许可证?
本文将简要介绍对许可证(license)的理解,着重介绍一个实战项目处理方式。
许可证介绍
许可证的内容,其实是博大精深。
首先许可证的种类特别的多,其次不同的许可的条款和细节也特别的多。
下面主要是介绍若干主流且具有代表性
的许可证。
主要参考了开源许可证教程-阮一峰的网络日志
名词解释
分发
将版权作品从一个人转移到另外一个人;例如提供给别人;如果是本公司使用,不算分发。
传染
一个项目用到了某个许可证的代码,在某些条件下(例如分发),这个项目本身也需要使用这种许可证
许可证版本
同一个许可证,有版本号之间的区别,例如 GPL 有 v1/v2/v3。
宽松的许可证
包含 MIT/ISC/BSD/Apache等,基本上这类许可证,是可以放心使用。
1 | (1)BSD(二条款版) |
Copyleft 许可证
代码可以随意复制,有如下前提:
1 | - 如果分发二进制格式,必须提供源码 |
核心在于,修改后的代码,不得闭源。
- AGPL
最严格的 GPL,除非获得商业授权,否则无论以何种方式修改或者使用代码,都需要开源。
云服务使用AGPL 的源码,不构成分发,也也需要开源
- GPL
如果分发软件,则使用和修改都必须开源,整个项目都必须采用 GPL许可。
- LGPL
分发时,如果是使用动态类库的方式引用,可以不开源
- MPL
分发时,只要该许可证的代码在单独的文件中,新增的其他文件可以不用开源。
无论是商业应用,还是开源项目,在采用 AGPL/GPL/LGPL/MPL都要特别的小心。
许可证检测
介绍两个工具,分别检测代码文件和依赖的 license。
检测代码
1 | go get -u github.com/google/addlicense |
可以递归检测当前目录下的所有代码文件,许可证声明的情况,例如:
1 | addlicense -check ./ |sort > lc.txt |
可以把未添加许可证的文件都输出到lc.txt 文件中,方便后续进行检查。
检测依赖库
1 | go get -u github.com/google/go-licenses |
查看一个依赖库所使用的版权信息:
1 | go-licenses csv repo |
可以通过一个这个脚本项目进行批量测试:
1 | cat dep.txt |while read line |
许可证添加
笔者主要使用 idea 的 IDE 进行程序开发,它有管理版权信息的功能:
1 | Preference->editor->Copyright |
可以添加不同的 Profiles,然后使用 IDE的功能进行自动添加和更新。
1 | 1)设置默认 copyright |
项目实战
下文介绍对于一个实际项目进行许可证声明。
项目背景
该项目主语言是 golang,采用了自某 LGPL 的项目的一部分类库作为基础代码。
版权主体
也就是版权声明的第一行的关键信息,例如:
- go-ethereum
1 | Copyright 2016 The go-ethereum Authors |
- go-algorand
1 | Copyright (C) 2019-2020 Algorand, Inc. |
可以选择是作者主体,或者公司主体。
项目 license
由于该项目的代码,部分使用了修改了 LGPL 项目代码作为基础工具。
根据 LGPL 的规定,本项目也需要使用 LGPL 作为 license。
版权声明
声明版权,一般两部分:
1)项目级别的 LICENSE 文件
由于大部分的许可证都是控制包级别的许可,所以这种方式也足够
2)代码级别的 copyright 文件头
每一个原创的文件都设置了版权信息
项目级别的 license
一般而言,是找到你的 license 的文本,将文件放置于项目根目录。
不同许可证可能有点不一样
一般而言,在 github 建立公开项目的时候,会提示选择一个 license。
如果初始化忘记了,也可以web
界面上,新建一个名字是LICENSE
的文件,来显式触发选择
license。
代码级别的 copyright 文件头
使用第三方代码,主要分为,fork 引用
和
library 依赖
。
fork 是指把代码直接放到了代码库中,修改或者不修改。
library 是库依赖,例如通过 go.mod 的方式进行依赖。
fork 引用
代码分类 1
2
3
4
5
6
7
8
9
10
11
12
13
141)项目原创文件
2)项目修改第三方库的文件
3)项目直接引用第三方库的文件
4)fork 过来的开源库
可能存在包内 license,单文件可能没有copyright
5)忽略 license 文件的内容
非 golang 文件
gencode 生成的以 gen_开头的文件
其他自动生成的文件
有了如上的分类,你就可以使用 IDE 创建多个不同的 Copyright Profiles 来处理不同的文件了。
结合 addlicense 工具,相信这部分工作将可以顺利完成。
library 依赖
使用上述的依赖检测工具,查看是否有不合适的许可证。
如果一个依赖库,license 不是MIT/ISC/BSD/Apache 其中的一种,那就要小心了!
TBD-Topics
有一些话题需要进一步讨论:
1 | 1)如果项目源码计划商用,如何处理? |
总结
本文简要介绍了license 的原理,着重介绍了项目实战,希望对读者有启发,欢迎讨论!
参考
https://www.ruanyifeng.com/blog/2017/10/open-source-license-tutorial.html
https://www.gnu.org/licenses/gpl-faq.html
https://choosealicense.com/