昇腾CANN cann-agreements:开源合规与许可证管理的实战手册
CANN社区通过cann-agreements仓库规范开源许可证管理,明确55个仓库采用不同许可证(Apache 2.0为主,MIT/木兰等为辅),并制定第三方依赖审核流程。核心内容包括:Apache 2.0许可证的四大权利与两项义务、贡献者CLA签署机制、许可证兼容性矩阵,以及常见合规风险(如静态链接传染、版权声明缺失等)。通过SPDX标识、自动化工具链和标准化流程,确保开源合规性贯穿代码开发全
开源不是「代码公开了就可以随便用」——每个仓库都有许可证,每个许可证都有一组权利和义务。cann-agreements 是 CANN 社区的许可证管理仓库:明确每个仓库使用的许可证、第三方依赖的许可证合规性、以及贡献代码时的 CLA(Contributor License Agreement)签署流程。
CANN 仓库的许可证结构
CANN 的 55 个仓库并不共用一个许可证——不同类型的仓库使用不同的许可证:
许可证类型分布
Apache 2.0(允许商用/修改/分发/专利授权,最宽松)
→ 算子仓库(ops-*)、加速库(catlass/ATB 等)、学习资源
→ 覆盖 40+ 个仓库,是 CANN 的主许可证
MIT(极简许可证,仅要求保留版权声明)
→ 工具类小仓库(cmake 辅助脚本、CI 配置片段)
→ 覆盖 < 5 个仓库
木兰宽松许可证 v2(国内开源许可证,兼容多种许可证)
→ 部分社区治理仓库(community、release-management)
→ 覆盖 3-5 个仓库
自定义许可证(华为内部/特殊场景)
→ 涉及固件/驱动/硬件文档的仓库
→ 覆盖 driver、metadef 等编译运行类仓库
许可证的选择影响:企业能否商用、是否必须开源修改的代码、是否需要保留版权声明。
Apache 2.0 的核心条款
算子仓库都用 Apache 2.0——这是业界最宽松的许可证之一:
Apache 2.0 的四大权利
├─ 商用:可以在商业产品中使用,不需要付费
├─ 修改:可以修改代码,不需要通知任何人
├─ 分发:可以把代码打包成产品/库分发
└─ 专利授权:自动授予所有用户使用相关专利的权利
Apache 2.0 的两项义务
├─ 保留版权声明:所有源文件头部保留原始版权声明和 Apache 声明
└─ 声明重大变更:修改后的文件要标注 "Licensed under the Apache License, Version 2.0"
实战场景:一家公司从 ops-nn 拿了 GEMM 优化代码,改了内部的 tiling 参数,装进自己的推理引擎卖给了客户。完全合规——不需要开源,不需要付费,不需要告知昇腾。
第三方依赖的许可证合规
算子仓库不可避免地依赖第三方库——FFT 仓库可能引用 FFTW(GNU GPL),ML 仓库可能引用某些 CC 协议库。cann-agreements 定义了依赖许可证的审核流程:
依赖许可证审核流程
Step 1:发现依赖
├── 显式依赖:package.json / requirements.txt / CMakeLists.txt
└── 间接依赖:依赖的依赖(transitive dependencies)
Step 2:分类许可证风险
├── 高风险(需替换或隔离)
│ ├── GPL / AGPL:传染性强,使用者必须开源
│ ├── SSPL:MongoDB 许可证,禁止直接 SaaS 使用
│ └── Custom/Proprietary:需要商业谈判
│
├── 中风险(需要确认兼容性)
│ ├── LGPL:动态链接可接受,静态链接需要特殊处理
│ ├── MPL:文件级许可证,允许部分开源
│ └── CC-BY-NC:非商业用途限制
│
└── 低风险(直接可用)
├── Apache 2.0 / MIT / BSD / ISC:直接使用
└── 木兰宽松许可证 v2:国内场景优先选
贡献者的 CLA 签署
在 CANN 社区提交 PR 之前,需要签署 CLA(Contributor License Agreement)。CLA 的核心作用是:贡献者授权华为将代码合入 CANN 仓库,并确保贡献的代码没有侵犯第三方知识产权。
# 签署 CLA 的流程
# 1. 在 AtomGit 上打开 PR,CLA 机器人会自动检测
# 2. 首次贡献需要先签署 CLA
# CLA 签署页面
# https://atomgit.com/cann/cann-agreements/blob/main/CLA.md
# 签署 CLA 的关键步骤:
# Step 1:确认你是个人贡献者还是代表公司
# - 个人贡献:签署 IC-LA(个人贡献者协议)
# - 公司贡献:需要公司签署 CCL(Corporate CLA),个人签署 IC-LA
# Step 2:阅读 CLA 内容,确认以下条款
# - 贡献的代码归贡献者所有(有权贡献)
# - 没有剽窃第三方代码(如 GPL 代码未经许可的片段)
# - 授予华为 在 CANN 仓库中 使用/修改/分发 该代码的权利
# - 如果代码涉及专利,授予所有用户 免版权费 的专利使用权
# Step 3:签署(电子签名)
# 在 PR 评论里回复 "+CLA Signed"
# 4. CLA Bot 检查通过,PR 可以继续审查
# 如果 CLA 签署状态有变化,Bot 会在 PR 下发评论
许可证兼容性的判定矩阵
当一个项目依赖多个许可证的组件时,需要判断最终产品的许可证。最常见的场景:
| 组件 A | 组件 B | 组合后许可证 | 说明 |
|---|---|---|---|
| Apache 2.0 | Apache 2.0 | Apache 2.0 | 兼容 |
| Apache 2.0 | MIT | Apache 2.0 | 兼容(MIT 被 Apache 2.0 覆盖) |
| Apache 2.0 | BSD-2 | Apache 2.0 | 兼容 |
| Apache 2.0 | BSD-3 | Apache 2.0 | 兼容 |
| Apache 2.0 | GPL-3.0 | 冲突 | GPL 传染性导致整体成为 GPL |
| Apache 2.0 | LGPL-2.1 | 动态链接:Apache 2.0;静态链接:GPL | 动态链接隔离 |
| Apache 2.0 | MPL-2.0 | 动态链接:Apache 2.0;静态链接:需额外审查 | 文件级许可 |
踩坑一:静态链接导致许可证传染
一个仓库用了 GPL-licensed 的库(ops-fft 引用了 GPL 的 FFT 实现),直接把库编译进自己的二进制——这个仓库的许可证就从 Apache 2.0 变成了 GPL。
# 错误:直接把 GPL 库静态链接到 ops-fft
# CMakeLists.txt
target_link_libraries(ops-fft PUBLIC gpl_fft_lib) # ← 传染!
# 正确做法:用动态链接( LGPL 下的动态链接可接受)
target_link_libraries(ops-fft PUBLIC gpl_fft_lib_shared) # 动态 .so 文件
# 或者替换成 Apache 2.0 的 FFT 实现(如 kissfft)
target_link_libraries(ops-fft PUBLIC kissfft) # MIT 许可证,无传染风险
踩坑二:COPYRIGHT 文件缺失导致的法律风险
Apache 2.0 要求保留所有源文件的版权声明。如果删掉了某个源文件头部的版权声明——即使保留了代码本身——也是违反许可证的行为。
自动化检查:在 CI 里加 reuse lint(EU 的 REUSE 规范)或 licensee(检查许可证合规性的工具)。
# 检查项目许可证合规性
licensee detect
# 输出示例:
# No license file found. Detecting license(s) in code...
# ...
# ✓ LICENSE file matches Apache-2.0
#
# Unused licenses:
# - No SPDX expression in package.json (found: undefined)
# - Some files missing copyright notices
# 未检测到的文件列表
# 需要手动补充 COPYRIGHT 文件或在每个源文件头部加版权声明
踩坑三:贡献代码时剽窃了第三方代码
提交的 PR 里有几行代码是从 Stack Overflow 或某个 GPL 项目复制来的。CLA 签署时声明「贡献的代码归贡献者所有」,但实际代码并非原创——CLA 条款不被满足,PR 合入后可能引发法律纠纷。
自动化检测:CLA Bot 会跑 cloc(代码行数统计)和 scancode-toolkit(许可证扫描)对比 PR 和公开代码库的重合度。
# 检测 PR 中代码和公开代码库的重合度
scancode-toolkit --license \
--classify \
--is-license-text \
--output-file=scan_result.json \
./PR_changes/
# 关键指标:
# - clone_detector:和已知开源项目的代码行重合比例
# - snippet_matches:从 Stack Overflow 等来源的代码片段
# 如果 clone_detector > 30%:
# CLA Bot 会标记 PR 为「需要人工审查」
# 贡献者需要提供代码来源证明(原创/合理使用/已获授权)
踩坑四:多许可证项目的许可证头注释混乱
一个仓库同时包含 Apache 2.0(自研代码)和 MIT(第三方脚本)两个许可证——有的文件头部有版权声明,有的没有。时间久了维护者分不清哪个文件用哪个许可证。
统一格式:在仓库根目录放 NOTICE.md 列出所有第三方来源,在每个源文件头部统一 SPDX 标识。
// 统一格式:用 SPDX 标识许可证
// Copyright (C) 2025 Huawei Technologies Co., Ltd.
// SPDX-License-Identifier: Apache-2.0
// 第三方引入的脚本(COPYING 是 MIT 许可证的原文)
// Copyright (C) 2023 Original Author
// SPDX-License-Identifier: MIT
SPDX(Software Package Data Exchange)是 Linux 基金会主导的许可证标识标准——每个许可证的 SPDX Identifier 是唯一的:Apache-2.0、MIT、GPL-3.0-only 等等。编译器能识别 SPDX 注释,CI 能自动检查许可证合规性。
开源合规不是法务的事,是工程师的事。每个仓库用什么许可证、依赖的库是什么许可证、贡献的代码有没有侵权风险——这些在写代码的时候就要搞清楚,而不是等 PR 合入之后才发现许可证冲突。cann-agrereements 把这些规则整理成可操作的手册,降低了贡献者踩坑的概率。
更多推荐




所有评论(0)