【码动四季·秋】开源许可证怎么选:一个真实 Rust 项目的决策全过程(GPL 传染 / 依赖审计 / DCO)
本文为 AtomGit 码动四季·开源同行征稿活动参与文章难度等级⭐⭐2/5前置知识无概念篇条款原文均附官方链接01 号文章那次开源化体检里CI 打包用了半天CONTRIBUTING 用了一小时LICENSE 卡了我大半天。反复推翻自己好几次返工的根因是三个概念从一开始就理解错了。不是查资料难——GPL-3.0 全文才 674 行MIT 只有 23 行。难的是每次以为选好了就冒出一个新的具体问题Tauri 是 MIT/Apache 双许可我打包出来的 exe 算谁的git2 绑定的是 Apache/MIT 双许可我能用吗别人 fork 我的代码做个商业版扫描工具我管得着吗这些问题抄来的 LICENSE 回答不了。这篇就把我这个 Rust 项目的决策过程完整摊开怎么把一个模糊的选个开源协议问题拆成四个可回答的具体问题以及最后为什么落在了 Apache-2.0 上。给后面要开源的读者省下大半天——按本文的决策路径第二个仓库 10 分钟就能出结论。本文要点四问决策法 · 许可证宽严光谱 · 传染性/专利授权/无许可证三个概念正解 · 依赖审计两条扫描命令 · CLA 与 DCO 选型 · 3 个真实踩坑适用版本Apache-2.0 / GPL-3.0 / MIT / DCO 1.1均为 2026 年现行版本条款以官方原文为准一、先把问题拆对选许可证其实是回答四个问题我卡住的根源是一直试图直接回答哪个许可证好——这是个无法回答的问题因为好取决于你要什么。真正可回答的是下面四个问题答案组合起来许可证基本就自动浮出来了接受不接受在意无所谓衍生品需同协议开源内容为主要控制商用转载问题1别人拿去闭源商用你接受吗?问题2在意专利保护吗?问题3只要求衍生品也开源还是完全禁止商用?Apache-2.0MIT / BSDGPL-3.0 / MPL-2.0内容 CC 系列 代码宽松协议我的四个答案分别是接受他人闭源使用工具类代码传播比控制重要在意专利条款 Rust 生态里专利风险虽低但条款白拿不要钱仓库主体是软件不是内容单人维护、个人项目。这组答案直接指向 Apache-2.0——后面第三节展开。二、前置认知宽严光谱与三个被说错的概念2.1 宽严光谱许可证不是散点是一条连续的光谱宽松permissiveMIT几乎只要求保留版权声明BSD-3额外限制用名字背书Apache-2.0宽松 明确专利授权MPL-2.0文件级 copyleftLGPL库级 copyleftGPL-3.0强 copyleftAGPL-3.0网络服务也触发开源义务从左到右你保留的权利越少、使用者拿到的自由越多反过来越往右衍生品必须同协议开源的义务越重。所有主流许可证都能在这条光谱上找到位置选型就是在光谱上选一个和你态度匹配的点。2.2 三个高频概念的正解传染性copyleftGPL 的传染有明确触发条件——分发distribute。你用 GPL 库写了内部系统自己跑不分发、不提供网络服务不触发开源义务一旦把软件分发给别人卖、送、发包整个衍生作品必须以 GPL 开源。AGPL 多堵了一个网络服务的洞SaaS 化提供也视同分发。网上流传的碰了 GPL 代码就完蛋绝大多数场景是把分发这个前提弄丢了。专利授权这是 Apache-2.0 独有的显式条款——贡献者授予你专利使用权并且有专利报复条款你发起专利诉讼则授权终止。MIT/GPL 默认没有专利条款理论上存在代码开源但专利暗雷的风险敞口。对企业级项目这一条常常是选 Apache-2.0 的决定性理由对个人项目它是条款白拿不要钱的增量保障。无许可证的真实含义没有 LICENSE 文件的仓库默认保留所有权利——你有权看无权复用。很多人以为公开在 GitHub 上 随便用这是错的而且是最常见的合规事故来源。2.3 流传最广的四个错误说法错误说法实际情况“用了 GPL 的库我的整个项目必须开源”只有分发或 AGPL 的网络服务才触发不分发不受影响“MIT 协议的代码可以随便用”须保留版权与许可声明且不含专利授权商标也不在授权范围“开源 放弃版权”版权始终在你手里许可证只是授权他人有限使用“依赖是 MIT/Apache 双许可就随便选一个挂”你分发的是衍生作品声明必须覆盖全部依赖的许可证义务逐个核对三、本仓库的真实决策为什么是 Apache-2.03.1 决策过程复盘我的仓库构成Rust 检查器内核约 3700 行依赖 git2/rayon/serde、Tauri 2 桌面壳 Vue 3 前端约 2600 行依赖 element-plus/pinia/vue、CI 打包脚本。逐个问题的推理过程问题 1商用态度这是一个通用开发工具我希望它被尽量多的人用——包括被公司拿去内部用、被 fork 出改进版。限制商用等于亲手压缩传播面。所以答案是接受闭源使用。这一条直接排除了 GPL 系和 NC 系落点在宽松光谱。问题 2专利宽松光谱里剩 MIT 和 Apache-2.0。仓库虽然没有值得专利保护的资产但 Apache-2.0 的专利授权条款是防下游的万一未来有贡献者贡献了涉及专利的实现显式授权条款能避免贡献者事后用专利讹用户的经典纠纷。条款白拿不要钱选它。问题 3单一客体和文档仓库不同这个仓库客体单一——全是软件代码一个许可证罩得住不需要双许可。唯一的内容是 README 和 docs我按软件项目惯例统一归入 Apache-2.0docs 里如果未来出现成规模的技术文章再单独声明。最终落点客体许可证理由全部源码crates/、ui/、CI 脚本Apache-2.0宽松 显式专利授权与 Tauri 生态主流协议一致README 与 docs 文档Apache-2.0软件项目惯例随仓库统一声明这个落点让我能具体地回答开头那些问题公司拿我的工具内部使用——允许fork 出商业版——允许需保留版权声明与 LICENSE修改处按 Apache-2.0 标注有人拿我的代码申请专利反制用户——Apache-2.0 的专利授权与报复条款兜底把我的工具改名当成自己的作品发布且不保留声明——不允许这是违约。顺带核对过依赖侧的义务Tauri 是 MIT/Apache 双许可我按下游惯例可任选口径git2/git2-rs 是 MIT/Apache 双许可前端 vue/element-plus 均为 MIT——宽松依赖树Apache-2.0 的声明罩得住无 copyleft 污染。这个核对我的做法是把cargo license和license-checker的输出过一遍见第四节。3.2 单许可的声明方式单许可比双许可简单但声明位置依然有讲究LICENSE 是法律文件的锚点README 只做导航。我的做法是根目录放 LICENSE 全文README 加一段声明另外在Cargo.toml里同步元数据LICENSE # Apache-2.0 全文 README.md 中的声明段 ## 许可证 本项目基于 Apache License 2.0 开源发布。 Cargo.tomlworkspace.package license Apache-2.0Cargo.toml里的license字段不是可选项——crates.io 和各类许可证识别工具都以它为准README 里写了但元数据没写工具照样识别不出。四、依赖审计你的仓库里藏着别人的协议选好自己的许可证只完成了一半。另一半是搞清楚你引用的东西允许你这样引用吗4.1 扫依赖树依赖审计三步① 扫描cargo license / license-checker生成依赖许可证清单② 风险判定宽松代码链 GPLAGPL 混入服务端③ 处置替换 or 单独声明排除禁止拖着不处理Rust 和前端两侧各有一条现成的扫描命令# Rust 依赖的许可证清单cargo-edit 提供cargoinstallcargo-licensecargolicense--workspace# npm 依赖的许可证清单npx license-checker--summary实际跑cargo license的输出长这样——每个依赖的名称、版本、许可证一目了然图 4cargo license --workspace实际扫描输出重点关注 License 列的宽松/严格属性扫描结果里要盯的不是有没有 GPL——前面说过不分发就不触发——而是两个真正的风险位你计划以宽松协议MIT/Apache开源的代码直接链接/改编了 GPL 代码——你的 Apache 声明罩不住这段衍生代码分发时违反的是 GPL。Rust 生态整体宽松git2/rayon/serde/thiserror 全部 MIT 或 Apache 双许可我的依赖树扫描结果全绿前端 element-plus/pinia/vue 也全部 MIT。AGPL 组件混进了服务端链路——只要你的服务对外提供网络访问开源义务就触发和是否分发无关。本项目是纯本地桌面应用无服务端链路这一位天然安全——但同类项目引入任何联网同步功能前必须重审这一位。我的依赖树里这次没扫出污染但上一轮内容仓库审计时真实扫出过一个早期文章里复用的一段工具函数溯源后发现改编自一个 GPL-3.0 的开源项目。处理方式二选一重写这段函数我选了这个函数不长或者这段代码单独声明 GPL 并从宽松协议范围中排除。拖着不处理是最差的选项——合规债务只会长利息。4.2 图标与素材软件仓库特有的审计位桌面应用有一类内容仓库没有的客体图标、演示 GIF、UI 素材。我的三条原则自绘图标与截图——版权归自己随仓库协议分发无额外义务引用第三方图标库——查清它的协议多数图标库是 MIT/CC0也有要求署名的 CC-BY按其要求在 README 致谢段标注演示 GIF 里若出现第三方软件界面——标注来源与版本避免代言误会。五、CLA 与 DCO贡献者的授权方式仓库开放 PR 之后外部贡献的代码我用什么权利就有了现实意义。两种机制维度CLA贡献者许可协议DCO开发者原始声明形式签一份法律文件首次贡献前完成每次 commit 加一行Signed-off-by给维护者的权利宽泛授权可再许可、可变更协议确认这是我写的我有权按仓库协议贡献贡献者成本高要读合同、可能走法务极低git commit -s顺手的事典型使用者大型基金会项目、商业开源Linux 内核及多数个人/社区项目个人项目的选择几乎没有悬念DCO。理由是 CLA 的核心价值——给维护者将来可以变更许可证、可以再商业许可的灵活性——对一个不打算变更协议的个人仓库没有意义而它给贡献者增加的摩擦是实打实的。CLA 适合的场景是公司主导、可能商业转化的项目。DCO 的启用成本也极低CONTRIBUTING.md 里声明提交即代表遵循 DCO 1.1然后 CI 里加一道 sign-off 检查# CI 中校验所有 commit 均含 Signed-off-bygitlog--format%borigin/main..HEAD|grep-qSigned-off-by\||{echoFAIL: commit 缺少 Signed-off-bygit commit -s 即可;exit1;}六、三个真实踩坑1. 先写代码后想协议依赖审计被迫返工现象开源决策时回溯依赖树发现有个阶段为图方便引入过一个实验性 crate它的传递依赖里有 GPLv2 项——而彼时代码已经引用了它的 API。根因开发期没有引入依赖先查协议的习惯合规债务被推迟到开源决策点集中爆发。解决换用宽松协议的等价 crate 并重写适配层此后 CONTRIBUTING.md 明确新增依赖必须附带许可证核对。教训引入合规是编码时一分钟的事事后换依赖是半天的事——这笔成本只会涨不会跌。2. 把免费用等同于随便用现象选型前默认 MIT 最无负担细读条款才发现版权声明必须保留、作者不承担担保责任、商标不在授权范围。根因把宽松误读为没有义务只看了传播自由没看约束条款。解决逐条读完主流许可证原文再决策关键义务写进 README 的声明段。教训不得用作者名字做宣传正是 BSD-3 存在的理由——许可证的每个差异条款背后都有真实场景这些不是废话。3. 元数据与 LICENSE 文件不同步现象LICENSE 文件放好了但Cargo.toml的license字段是初始模板里的占位值——许可证识别工具读出来的是占位协议crates.io 侧的元数据校验也会拒绝发布。根因以为声明就是放一个 LICENSE 文件忽略了包管理器生态有自己的元数据校验链。解决把三处一致写进发布检查单LICENSE 文件、README 声明段、Cargo.toml/package.json的 license 字段三处必须指向同一协议。教训每个包管理生态都有自己的许可证元数据位声明要覆盖全部锚点——只改一处等于没改。七、效果与边界指标决策前决策后选型决策耗时大半天反复摇摆复用本决策树第二个项目 10 分钟出结论依赖许可证盲区全部未知cargo licenselicense-checker全量扫描宽松依赖树确认无污染转载/商用问题无从回答声明段一句话可查贡献授权未定义DCO 1.1CI 强制校验适用边界本文的决策样本是通用工具型个人软件仓库。两类场景请另行评估内容为主的仓库文章、文档、知识库应当拆内容 代码双许可CC 系列条款与本文路径不同企业代码开源的合规权重完全不同——专利风险、竞业与商业秘密审查、CLA甚至贡献者协议必须有法务参与会成为主问题。请把本文当个人工具项目参考不要当模板。八、总结回头看我卡住的大半天问题出在一开始就把选协议当成一道选择题来做。拆成四个具体问题之后它其实是一道填空题商用态度、专利诉求、copyleft 底线、客体构成四个答案一填协议自己就浮出来了。几个我付过学费的认知传染性以分发为触发条件不弄清这个前提GPL 恐惧和 GPL 大意都会出错工具类代码优先选带专利授权的 Apache-2.0条款白拿不要钱依赖审计要覆盖 Rust/npm 两个生态的元数据锚点LICENSE 文件、README、包元数据三处一致才算声明完成个人项目用 DCO 不用 CLA给贡献者的摩擦降到最低。最后的决策清单拿去直接用回答四个问题商用态度 / 专利诉求 / copyleft 底线 / 仓库客体构成在宽严光谱上落点内容为主的仓库拆内容 代码双许可扫描依赖cargo license/license-checker处理宽松代码链 GPL 和 AGPL 混入两个风险位图标、GIF 等素材查清来源协议按要求致谢个人项目配 DCO 1.1CI 加 sign-off 校验LICENSE 文件、README 声明段、包管理器元数据三处一致九、常见问题Q1Tauri 这类 MIT/Apache 双许可的框架我分发衍生作品时要遵守哪个双许可的意思是你可以任选其一作为自己的合规口径——两个都满足义务即可保留版权声明、附许可证副本。我统一按 Apache-2.0 口径管理LICENSE 文件里除了自己项目的声明保留一份依赖协议清单cargo license 输出这样任何人审查时都能一次性看到整棵树的授权链。Q2MIT 和 Apache-2.0 到底怎么选一句话个人小工具选 MIT企业级或可能有专利纠纷的选 Apache-2.0。差别就两点——Apache-2.0 有显式专利授权 报复条款约多 50 行法律文本MIT 更短更没有心智负担。本文仓库选 Apache-2.0 的核心理由是防下游专利纠纷的那份增量保障以及与 Tauri 生态主流口径一致。Q3同一仓库能放多个许可证吗会不会冲突可以前提是客体不重叠。冲突只发生在同一个文件同时被两个协议声明。如果要拆按目录划界并写清楚对照表。有一个实操细节仓库根目录的README.md本身算内容还是配置软件仓库的惯例是随仓库主协议走它本质是软件的使用说明内容仓库才需要把 README 归入内容协议——两种做法都成立关键是写明。你的仓库现在挂的是什么许可证如果答案是没挂或者不知道现在就去补——这可能是开源合规里性价比最高的十分钟。真实性声明本文决策过程来自 repo-balance 仓库 2026-09 开源改造的真实选型记录依赖审计结果来自cargo license --workspace与license-checker实际扫描输出git2/rayon/serde/thiserror/vue/element-plus 等依赖协议均已核对文中 GPL 污染案例为此前仓库审计中的真实事件涉事代码已重写。许可证条款表述以各协议官方原文为准本文不构成法律意见商业决策请咨询专业法务。案例仓库atomgit.com/dickeryang/repo-balance。参考资源choosealicense.comGitHub 官方许可证指南GNU GPL-3.0 全文Apache-2.0 全文DCO 1.1 声明原文Tauri 许可证说明专栏导航上一篇给一个 Rust 桌面应用做开源化体检下一篇03 从 commit 到发版全自动semantic-release 发布流水线如果本文对你有帮助欢迎点赞、收藏、转发。有任何问题或建议请在评论区留言交流。行文仓促定有不足之处欢迎各位朋友在评论区批评指正不胜感激。

相关新闻

Jetson AGX Orin 64GB / JetPack 6.x 进入 L4T Recovery Boot 的故障排查与修复

Jetson AGX Orin 64GB / JetPack 6.x 进入 L4T Recovery Boot 的故障排查与修复

Jetson AGX Orin 64GB / JetPack 6.x 进入 L4T Recovery Boot 的故障排查与修复 1. 文档目的 本文记录一次 Jetson AGX Orin 64GB(系统安装于 eMMC、JetPack 6.x / L4T 36.4.3)无法正常进入 Ubuntu,反复进入 L4T Recovery Boot/initrd shell …

2026/10/8 8:16:33 阅读更多 →
核心能力盘点|Paperxie 五大核心板块,一站式搞定毕业论文全流程

核心能力盘点|Paperxie 五大核心板块,一站式搞定毕业论文全流程

前言 市面上很多 AI 学术工具大多只做单点功能,要么只能翻译文献,要么只能简单润色文字,无法支撑完整的毕业论文工作。Paperxie 作为面向国内本科、硕士毕业生打造的一站式 AI 论文辅助平台,整合了五大核心板块,覆盖从…

2026/10/8 8:16:33 阅读更多 →
论文辅助工具怎么选?看懂这几点,选对 Paperxie 少走弯路

论文辅助工具怎么选?看懂这几点,选对 Paperxie 少走弯路

写在前面 到了毕业季,身边不少同学都在为论文熬夜。我见过很多人电脑同时开好几个窗口:翻译网页、绘图软件、参考文献工具、文档自查网站、PPT 模板,来回切来切去,文件导出导入,光是复制粘贴就浪费大量时间。更头疼的是…

2026/10/8 8:16:33 阅读更多 →

最新新闻

DeepLabV3实战:Cityscapes标签转trainId与训练迁移全指南

DeepLabV3实战:Cityscapes标签转trainId与训练迁移全指南

简介:面向计算机视觉语义分割研究者的PyTorch实现,基于Cityscapes数据集训练DeepLabV3,解决街景场景中物体边缘模糊与多尺度特征提取问题。压缩包共18个文件,约258MB,其中12个py脚本覆盖模型结构定义、数据预处理、Dat…

2026/10/9 14:38:05 阅读更多 →
NC57与Oracle 10g安装部署实战:从系统参数到应用启动的完整避坑指南

NC57与Oracle 10g安装部署实战:从系统参数到应用启动的完整避坑指南

简介:这份文档面向用友NC57的部署实施人员与运维初学者,聚焦Oracle 10g数据库与NC57产品的完整安装流程,帮助读者在较短时间内理清从数据库准备到系统管理设置的各环节要点。资源包内共1个doc文件,压缩后约2.77MB,以图…

2026/10/9 14:38:05 阅读更多 →
机器人学导论教案实战:从位姿到雅可比的完整学习路线

机器人学导论教案实战:从位姿到雅可比的完整学习路线

简介:机器人学导论是连接机械工程与智能控制的桥梁,而位姿描述、坐标变换、正逆运动学与雅可比矩阵则是其中最核心的基础概念。很多学习者拿到教学PPT后,往往只是收藏却难以真正内化,原因在于缺少一条从公式推导到仿真验证的完整路…

2026/10/9 14:38:05 阅读更多 →
Linux下手动搭建Hadoop 3.3.6集群实战指南

Linux下手动搭建Hadoop 3.3.6集群实战指南

简介:本资源是一份面向大数据初学者与高校实验教学的Hadoop集群搭建实操指南,聚焦Linux环境下从零构建分布式Hadoop 2.7集群的核心流程,解决环境配置复杂、节点通信异常、服务启动失败等典型实践痛点。文档为单文件Word格式(.doc&…

2026/10/9 14:38:05 阅读更多 →
agent 时代,动脑子的是什么

agent 时代,动脑子的是什么

结论先行:执行类的事,已经不太需要你动脑子了。 部署一个 deepseek、跑通一个 nanoGPT、把 Ray 在小场景里跑起来——这些事以前能吃掉你好几天,现在有官方文档、有别人踩过的坑、有 agent 帮你写,多半能搞定。真正还要你动脑子的…

2026/10/9 14:38:05 阅读更多 →
SpringBoot+Vue+微信小程序购物系统毕设实战详解

SpringBoot+Vue+微信小程序购物系统毕设实战详解

简介:这是一套基于SpringbootVue微信小程序的购物系统毕业设计资源,面向需要完成电商类项目的计算机专业学生与开发者。系统围绕商品浏览、购物车、订单结算及后台管理等核心模块展开,采用RESTful API通信,并提供完整数据库脚本&a…

2026/10/9 14:37:04 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →