开源不是「代码公开了就可以随便用」——每个仓库都有许可证每个许可证都有一组权利和义务。cann-agreements 是 CANN 社区的许可证管理仓库明确每个仓库使用的许可证、第三方依赖的许可证合规性、以及贡献代码时的 CLAContributor 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 仓库可能引用 FFTWGNU GPLML 仓库可能引用某些 CC 协议库。cann-agreements 定义了依赖许可证的审核流程依赖许可证审核流程 Step 1发现依赖 ├── 显式依赖package.json / requirements.txt / CMakeLists.txt └── 间接依赖依赖的依赖transitive dependencies Step 2分类许可证风险 ├── 高风险需替换或隔离 │ ├── GPL / AGPL传染性强使用者必须开源 │ ├── SSPLMongoDB 许可证禁止直接 SaaS 使用 │ └── Custom/Proprietary需要商业谈判 │ ├── 中风险需要确认兼容性 │ ├── LGPL动态链接可接受静态链接需要特殊处理 │ ├── MPL文件级许可证允许部分开源 │ └── CC-BY-NC非商业用途限制 │ └── 低风险直接可用 ├── Apache 2.0 / MIT / BSD / ISC直接使用 └── 木兰宽松许可证 v2国内场景优先选贡献者的 CLA 签署在 CANN 社区提交 PR 之前需要签署 CLAContributor License Agreement。CLA 的核心作用是贡献者授权华为将代码合入 CANN 仓库并确保贡献的代码没有侵犯第三方知识产权。# 签署 CLA 的流程# 1. 在 AtomGit 上打开 PRCLA 机器人会自动检测# 2. 首次贡献需要先签署 CLA# CLA 签署页面# https://atomgit.com/cann/cann-agreements/blob/main/CLA.md# 签署 CLA 的关键步骤# Step 1确认你是个人贡献者还是代表公司# - 个人贡献签署 IC-LA个人贡献者协议# - 公司贡献需要公司签署 CCLCorporate CLA个人签署 IC-LA# Step 2阅读 CLA 内容确认以下条款# - 贡献的代码归贡献者所有有权贡献# - 没有剽窃第三方代码如 GPL 代码未经许可的片段# - 授予华为 在 CANN 仓库中 使用/修改/分发 该代码的权利# - 如果代码涉及专利授予所有用户 免版权费 的专利使用权# Step 3签署电子签名# 在 PR 评论里回复 CLA Signed# 4. CLA Bot 检查通过PR 可以继续审查# 如果 CLA 签署状态有变化Bot 会在 PR 下发评论许可证兼容性的判定矩阵当一个项目依赖多个许可证的组件时需要判断最终产品的许可证。最常见的场景组件 A组件 B组合后许可证说明Apache 2.0Apache 2.0Apache 2.0兼容Apache 2.0MITApache 2.0兼容MIT 被 Apache 2.0 覆盖Apache 2.0BSD-2Apache 2.0兼容Apache 2.0BSD-3Apache 2.0兼容Apache 2.0GPL-3.0冲突GPL 传染性导致整体成为 GPLApache 2.0LGPL-2.1动态链接Apache 2.0静态链接GPL动态链接隔离Apache 2.0MPL-2.0动态链接Apache 2.0静态链接需额外审查文件级许可踩坑一静态链接导致许可证传染一个仓库用了 GPL-licensed 的库ops-fft 引用了 GPL 的 FFT 实现直接把库编译进自己的二进制——这个仓库的许可证就从 Apache 2.0 变成了 GPL。# 错误直接把 GPL 库静态链接到 ops-fft# CMakeLists.txttarget_link_libraries(ops-fft PUBLIC gpl_fft_lib)# ← 传染# 正确做法用动态链接 LGPL 下的动态链接可接受target_link_libraries(ops-fft PUBLIC gpl_fft_lib_shared)# 动态 .so 文件# 或者替换成 Apache 2.0 的 FFT 实现如 kissffttarget_link_libraries(ops-fft PUBLIC kissfft)# MIT 许可证无传染风险踩坑二COPYRIGHT 文件缺失导致的法律风险Apache 2.0 要求保留所有源文件的版权声明。如果删掉了某个源文件头部的版权声明——即使保留了代码本身——也是违反许可证的行为。自动化检查在 CI 里加reuse lintEU 的 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-filescan_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: MITSPDXSoftware Package Data Exchange是 Linux 基金会主导的许可证标识标准——每个许可证的 SPDX Identifier 是唯一的Apache-2.0、MIT、GPL-3.0-only等等。编译器能识别 SPDX 注释CI 能自动检查许可证合规性。开源合规不是法务的事是工程师的事。每个仓库用什么许可证、依赖的库是什么许可证、贡献的代码有没有侵权风险——这些在写代码的时候就要搞清楚而不是等 PR 合入之后才发现许可证冲突。cann-agrereements 把这些规则整理成可操作的手册降低了贡献者踩坑的概率。