Keep Velocity High | kvh 的个人博客

分享 kvh 对于技术、创业的理解和实践

0%

开源许可证介绍与项目实战

介绍

在项目中第三方代码的时候,要注意源码许可证问题,因为这涉及到:

  • 使用和修改的条件是什么?
  • 商用和分发的条件是什么?
  • 本项目开源后使用什么许可证?

本文将简要介绍对许可证(license)的理解,着重介绍一个实战项目处理方式。

许可证介绍

许可证的内容,其实是博大精深。

首先许可证的种类特别的多,其次不同的许可的条款和细节也特别的多。

下面主要是介绍若干主流且具有代表性的许可证。

主要参考了开源许可证教程-阮一峰的网络日志

名词解释

  • 分发

    将版权作品从一个人转移到另外一个人;例如提供给别人;如果是本公司使用,不算分发。

  • 传染

    一个项目用到了某个许可证的代码,在某些条件下(例如分发),这个项目本身也需要使用这种许可证

  • 许可证版本

    同一个许可证,有版本号之间的区别,例如 GPL 有 v1/v2/v3。

宽松的许可证

包含 MIT/ISC/BSD/Apache等,基本上这类许可证,是可以放心使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(1)BSD(二条款版)

分发软件时,必须保留原始的许可证声明。

(2) BSD(三条款版)

分发软件时,必须保留原始的许可证声明。不得使用原始作者的名字为软件促销。

(3)MIT

分发软件时,必须保留原始的许可证声明,与 BSD(二条款版)基本一致。

(4)Apache 2

分发软件时,必须保留原始的许可证声明。凡是修改过的文件,必须向用户说明该文件修改过;没有修改过的文件,必须保持许可证不变。

Copyleft 许可证

代码可以随意复制,有如下前提:

1
2
3
- 如果分发二进制格式,必须提供源码
- 修改后的源码,必须与修改前保持许可证一致
- 不得在原始许可证以外,附加其他限制

核心在于,修改后的代码,不得闭源。

  • 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
2
3
4
5
6
cat dep.txt |while read line
do
echo "start checking package $line"
go-licenses csv $line
echo ""
done

许可证添加

笔者主要使用 idea 的 IDE 进行程序开发,它有管理版权信息的功能:

1
Preference->editor->Copyright

可以添加不同的 Profiles,然后使用 IDE的功能进行自动添加和更新。

1
2
3
4
5
6
7
1)设置默认 copyright
preference->editor->Copyright
设置 default project copyright,选中一种配置,这个可能会根据不同的文件需要切换

2)选中代码文件或者文件夹

3)菜单栏->Code->Update 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 文件

由于大部分的许可证都是控制包级别的许可,所以这种方式也足够

每一个原创的文件都设置了版权信息

项目级别的 license

一般而言,是找到你的 license 的文本,将文件放置于项目根目录。

不同许可证可能有点不一样

一般而言,在 github 建立公开项目的时候,会提示选择一个 license。

如果初始化忘记了,也可以web 界面上,新建一个名字是LICENSE的文件,来显式触发选择 license。

使用第三方代码,主要分为,fork 引用library 依赖

fork 是指把代码直接放到了代码库中,修改或者不修改。

library 是库依赖,例如通过 go.mod 的方式进行依赖。

fork 引用

代码分类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1)项目原创文件

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/

欢迎关注我的其它发布渠道