什么是 SPDX
SPDX(Software Package Data Exchange,软件包数据交换)是 Linux 基金会旗下的项目,是以机器可读方式表示软件组件及其许可证信息的标准。2021 年成为国际标准 ISO/IEC 5962:2021。其中使用最广泛的是 SPDX 许可证列表中的简短标识符。它约定用一个 MIT 来代替「MIT License」「The MIT license」「MIT 许可证」等五花八门的名称。
文件头两行
在源文件顶部以注释形式加入以下两行,人和工具都能立即知道该文件的版权所有者和许可证。
// SPDX-FileCopyrightText: 2026 Jane Doe <jane@example.com>
// SPDX-License-Identifier: MIT
SPDX-License-Identifier填写许可证标识符或表达式(MIT OR Apache-2.0)。SPDX-FileCopyrightText是版权声明。有多人时就写多行。- Linux 内核自 2017 年起采用只放这一行、而非冗长许可声明的方式,减少了数千行重复的样板文字。
生成器的文件头标签页可以用 7 种注释格式生成这两行。
注意已弃用的标识符
从 SPDX 许可证列表 3.0(2017 年 12 月)起,改为在标识符中体现 GNU 许可证的版本条款。
| 已弃用的标识符 | 当前标识符 |
|---|---|
GPL-2.0 | GPL-2.0-only |
GPL-2.0+ | GPL-2.0-or-later |
GPL-3.0 | GPL-3.0-only |
LGPL-2.1 | LGPL-2.1-only |
AGPL-3.0 | AGPL-3.0-only |
因为如果只写 GPL-3.0,就无法知道是「only」还是「or later」。两种方式的区别整理在 only vs or-later 中。
包元数据
大多数包管理器都接受 SPDX 标识符或表达式。
| 生态 | 文件 | 示例 |
|---|---|---|
| npm | package.json | "license": "MIT" · 闭源用 "UNLICENSED" |
| Rust | Cargo.toml | license = "MIT OR Apache-2.0" |
| Python | pyproject.toml | license = "Apache-2.0" (PEP 639) |
| Maven | pom.xml | 在 <licenses> 中写名称和 URL |
npm 的 UNLICENSED 与「Unlicense」意思完全不同,表示这是不允许使用的闭源包。两者拼写相近,经常出错。
REUSE:让整个仓库机器可读
欧洲自由软件基金会(FSFE)的 REUSE 规范规定了在整个仓库中一致地应用 SPDX 文件头的方法。
- 将所有许可证原文以
SPDX标识符.txt的名称放在LICENSES/文件夹中(例如LICENSES/MIT.txt)。 - 在每个文件中加入
SPDX-FileCopyrightText和SPDX-License-Identifier。 - 无法加注释的文件(图片、JSON 等),通过旁边的
文件名.license文件或仓库根目录的REUSE.toml记录信息。 - 用
reuse lint工具检查是否有遗漏的文件。
实务提示
- 标识符区分大小写,须按列表原样书写(是
Apache-2.0,而不是apache2)。 - 列表中没有的自定义许可证,用
LicenseRef-前缀书写(例如LicenseRef-Proprietary)。 - 只有标识符而没有原文,很难说已经履行了声明义务。原文文件要另外放置。
本文为一般信息,不构成法律意见。重要决定请咨询专业人士。
参考来源
- SPDX License List — https://spdx.org/licenses/
- SPDX Specification, Annex: Using SPDX short identifiers in source files — https://spdx.github.io/spdx-spec/v2.3/using-SPDX-short-identifiers-in-source-files/
- REUSE Specification — https://reuse.software/spec/
- npm Docs, package.json license — https://docs.npmjs.com/cli/configuring-npm/package-json#license
- PEP 639 — https://peps.python.org/pep-0639/