Serial Studio 双重许可架构详解:SPDX 声明、REUSE 合规与构建时 GPLv3/商业边界强制执行
【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio
本文解析 Serial Studio 仓库的双重许可(GPL-3.0-or-later 或 Serial Studio Commercial License)模型:如何以 SPDX 头部作为权威依据划分双许可文件、专有 Pro 模块与第三方依赖,如何用 REUSE.toml 补齐无头部文件的许可声明,以及构建系统如何从 CMake 配置、凭据校验到运行时守卫逐层强制执行许可边界。读完后你可以独立判断仓库中任意文件的法律状态、复现默认的纯 GPL 构建,并理解官方预编译二进制与源码构建之间的许可区别。
1. 许可体系总览:SPDX 头部优先,文档只做路由
License 总说明 开篇即确立了整套许可体系的唯一权威原则:
每个文件的许可状态以其 SPDX 头部声明为准;没有头部的文件由 REUSE.toml 覆盖。SPDX 声明具有最终效力,LICENSE.md 本身不附加任何条款,只负责把你路由到正确的法律文本。
这是典型的 REUSE 合规实践:许可信息下沉到每个文件(SPDX 注释)或集中式注解文件(REUSE.toml),而非依赖一个笼统的顶层 LICENSE 文件。仓库根目录的 LICENSES/ 目录存放全部法律文本的完整副本,包括 GPL-3.0-or-later.txt、LicenseRef-SerialStudio-Commercial.txt、Apache-2.0.txt、MIT.txt、MPL-2.0.txt、OFL-1.1.txt 等 16 份文本,保证分发时许可全文随包携带。
该体系下每个文件恰好落在三类之一:
| 文件类别 | SPDX 表达式 | 法律后果 |
|---|---|---|
| 双许可文件 | GPL-3.0-or-later OR LicenseRef-SerialStudio-Commercial | 用户可选 GPL v3 或商业许可任一臂 |
| 专有 Pro 模块 | LicenseRef-SerialStudio-Commercial(仅此一项) | 无 GPL 权利,编译/使用/分发需有效商业许可 |
| 第三方依赖 | 各自上游许可证(BSD、MIT、MPL-2.0 等) | 遵循上游条款,见 REUSE.toml 注解 |
其中LicenseRef-SerialStudio-Commercial是一个 SPDX LicenseRef 自定义标识符,指向仓库内自持的 LICENSES/LicenseRef-SerialStudio-Commercial.txt,这是 REUSE 规范中声明专有许可的标准做法。
2. 双许可文件:GPL 臂的权利范围
标记为GPL-3.0-or-later OR LicenseRef-SerialStudio-Commercial的文件按你的选择提供两种许可。GPL 臂下,LICENSE.md 明确授予全部 GPLv3 权利:任何用途(含商用)、私有修改并分发、源码或二进制再分发,仅受 GPL 自身条件约束,不附加任何额外条款。
从构建系统结构看,GPL 臂是仓库的默认状态。根 CMakeLists.txt 定义了两个许可相关的构建开关:
option(BUILD_GPL3 "Force GPLv3-only build" ON) # 默认 ON option(BUILD_COMMERCIAL "Enable commercial features" OFF) # 默认 OFF也就是说,直接克隆仓库并按默认选项构建,得到的就是 LICENSE.md 所说的"仅包含双许可文件的构建(默认BUILD_GPL3=ON构建),它是 GPLv3 软件"。文件头部的许可声明也一致,例如根 CMakeLists.txt:
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-SerialStudio-Commercial3. 专有 Pro 模块的判定:只看 SPDX 表达式是否为"单项"
License 总说明 给出了 Pro 模块的严格充要条件:一个文件是 Pro 模块,当且仅当其 SPDX 表达式单独为LicenseRef-SerialStudio-Commercial。这类文件"源码公开发布是为了透明、可审计、可贡献;但它不附带任何 GPL 权利,编译、使用或分发它都需要有效的商业许可",且默认构建排除所有此类文件。
在仓库中可以找到大量符合该判定的文件,其功能面覆盖了 Serial Studio 的 Pro 能力:
- 构建期守卫生成器 cmake/GenLicenseGuards.cmake:
SPDX-License-Identifier: LicenseRef-SerialStudio-Commercial; - 许可 API 处理器 app/src/API/Handlers/LicensingHandler.cpp、LicensingHandler.h;
- AI 助手界面族:app/qml/AI/AssistantPanel.qml、ChatSidebar.qml、KeyManagerDialog.qml、ProUpgradeNotice.qml 等;
- 各协议驱动的配置面板:app/qml/MainWindow/Panes/SetupPanes/Drivers/ 下的 Audio、CANBus、MQTT、Modbus、OpcUa、S7、USB 等 QML;
- 数据库探索器 app/qml/DatabaseExplorer/、仪表盘输出控件(DashboardSlider.qml、DashboardKnob.qml 等)、Waterfall.qml、Plot3D.qml 等高级可视化组件。
这一划分让"开源内核 + 专有增值模块"的边界完全由文件级元数据表达,而不是隐藏在某个中央清单里——审计者只需对每个文件做一条 SPDX 扫描即可复现全部边界。
4. REUSE.toml:无 SPDX 头部文件的集中式许可注解
对于不便逐个加头部的文件(资源、生成物、第三方整体目录),REUSE.toml 以 TOML 注解块集中声明。它有两条关键的工程约定,直接写在文件注释中:
- 首方资源目录逐个枚举,而非用通配吞并。
app/rcc/**被拆成actions/、ai/、icons/、scripts/等十余个子目录逐一列出,原因是其中混有第三方字体(fonts/)与 vendor 资产,通配符会把它们错误地标注为GPL-3.0-or-later OR LicenseRef-SerialStudio-Commercial; precedence = "override"的使用有明确动机。默认优先级是"最接近者优先"(文件自身头部永远赢);但当上游 tarball 携带含 HTML 转义 SPDX 标签的生成文档、或文件内引用了被截断的 SPDX 示例(如 .claude/** 的 agent skills 在代码围栏里引用头部样例)时,用override使注解成为唯一事实来源。
值得注意的第三方依赖声明示例(均出自 REUSE.toml):
| 路径 | 版权人 | SPDX 标识符 | 备注 |
|---|---|---|---|
app/rcc/fonts/GeistMono-*.ttf | The Geist Project | OFL-1.1 | OFL 要求许可文本随字体分发,由 LICENSES/OFL-1.1.txt 满足 |
app/rcc/vendor/highlight* | Ivan Sagalaev 等 | BSD-3-Clause | AI 聊天/Markdown 查看器内嵌的 Web 资产,各带 .LICENSE 副车文件 |
core/Devices/ThirdParty/miniaudio.* | David Reid | MIT-0 OR Unlicense | 单头库,在 REUSE 中声明而非改文件,保持与上游逐字节一致、可 diff |
core/Core/ThirdParty/fast_float.h | fast_float 作者 | Apache-2.0 OR MIT OR BSL-1.0 | 三臂许可,取其一即可 |
core/Core/ThirdParty/atomicops.h | Desrochers / Preshing | BSD-2-Clause AND Zlib | 复合表达式:文件内嵌了 zlib 许可的信号量代码 |
app/src/ThirdParty/tweetnacl.* | Bernstein 等 | LicenseRef-PublicDomain | 公有领域 |
lib/hidapi/** | Alan Ott | GPL-3.0-only OR BSD-3-Clause OR LicenseRef-HIDAPI-Original | 三臂选择 |
lib/mbedtls/** | Mbed TLS Contributors | Apache-2.0 | 上游为 Apache-2.0 OR GPL-2.0-or-later,项目明确取 Apache 臂——这是与本项目两种分发条款都兼容的选项 |
此外,REUSE.toml 还包含一段对依赖策略的审计性说明:libplctag(MPL-2.0)在配置期经 FetchContent 获取、从不 vendored,仓库仅持有自持的 CMake 装配文件;并声明"本项目没有任何 LGPL 依赖,S7 协议客户端是一方 Qt-Core 代码(core/Protocols/S7),因此分发不受换链义务约束;未来引入任何新依赖前,必须针对 PROPRIETARY 分发而非仅 GPL 做许可审查"。这条规则解释了为什么 mbedtls 要显式选 Apache 臂、mbed TLS 的 GPL-2.0 臂会被排除。
5. 构建时强制执行:CMake 如何把许可边界变成硬约束
许可模型不只是文档声明,构建系统将其落实为可失败的配置检查。
5.1 互斥开关:GPL 构建禁止混入商业模块
CMakeLists.txt 在配置期做强制:
if(BUILD_GPL3) if(BUILD_COMMERCIAL) message(FATAL_ERROR "You cannot enable commercial features (BUILD_COMMERCIAL=ON) when BUILD_GPL3=ON.\n" "Set -DBUILD_GPL3=OFF to build with commercial modules.") endif() set(BUILD_COMMERCIAL OFF CACHE BOOL "Commercial features disabled due to GPLv3 build mode" FORCE) endif()即:默认BUILD_GPL3=ON时任何尝试打开BUILD_COMMERCIAL的操作都会在 configure 阶段直接FATAL_ERROR终止,且BUILD_COMMERCIAL被以FORCE写回 OFF。这与 LICENSE.md "默认构建排除所有 Pro 文件" 的承诺形成闭环:纯 GPL 构建从源头保证不链接任何LicenseRef-SerialStudio-Commercial单项文件。
5.2 商业构建:配置期凭据校验
CMakeLists.txt 显示,商业构建(BUILD_COMMERCIAL=ON且BUILD_GPL3=OFF)必须提供SERIAL_STUDIO_LICENSE_KEY与SERIAL_STUDIO_INSTANCE_ID,缺失即FATAL_ERROR。校验流程按源文件注释描述为:检查凭据 → 确认curl可用 → 向 Lemon Squeezy 许可 API 发送校验请求 → 解析 JSON 响应确认"valid":true→ 无效、过期或未激活则构建失败。实现细节上有一处安全考量值得注意:
凭据通过载荷文件传递,绝不出现在 curl 命令行上,因此不会暴露在进程列表或 CI 命令回显中(CMakeLists.txt)。
另外 CMakeLists.txt 的注释说明ARCGIS_API_KEY(Pro 版 ArcGIS 地图功能)仅在BUILD_COMMERCIAL=ON时需要,经环境变量或-D传入。
5.3 运行时守卫:基于构建盐的随机化许可校验函数
商业构建还引入一层生成式防护:cmake/GenLicenseGuards.cmake 在BUILD_COMMERCIAL且设置了COMMERCIAL_BUILD_SALT时,以盐的 MD5 哈希派生出 24 个守卫函数——函数名(动词+名词+后缀组合)、算术校验与期望常数全部由COMMERCIAL_BUILD_SALT派生,每次构建都不同。每个函数在运行时重算盐的变换并与编译期期望值比对;生成器还会先编译一份自测头文件,"非法的输出会在 configure 阶段而非出厂二进制中失败"。守卫头文件生成到${CMAKE_BINARY_DIR}/generated/LicenseGuards.generated.h。从源码结构看,这种"构建盐派生随机常量"的设计使不同合法商业构建之间的守卫互不相同,也令静态比对已知副本变得不可行;该模块自身即 Pro 模块(其 SPDX 为LicenseRef-SerialStudio-Commercial单项)。
6. 官方预编译二进制:EULA 管辖,不是 GPL 构建
License 总说明 划清了一条容易混淆的线:serial-studio.com 与 GitHub Releases 上发布的预编译二进制包含 Pro 模块,仅按 Serial Studio 最终用户许可协议 分发,且每个 release 含 14 天试用;它们不是 GPL 构建。
EULA.md 进一步界定了适用范围与试用规则:
- 适用边界:EULA 只约束官方预编译二进制;不约束源码(归 LICENSE.md 管)、不约束从源码编译的 GPL 构建(仅受 GPLv3 管辖)、也不约束 Pro 模块源码(受商业源码许可管辖)(EULA.md);
- 试用条款:每个 release 每用户每设备 14 天评估期,期间全部功能解锁;试用期内限评估用途——生产、客户工作与营收系统部署需激活许可;同一设备上的重装、改系统时钟或伪造机器身份不能重置试用,新 release 才开启新一轮 14 天(EULA.md);
- 激活后:可在商业、机构、企业与学术环境及生产系统中使用;订阅计划随订阅有效,终身计划授权为永久不可撤销(除用户未补救的重大违约外)(EULA.md);
- 主要限制:未经书面授权不得再分发/转售/镜像/托管(包括嵌入容器镜像、固件或产品);不得反向工程(法定强制例外除外);不得规避激活、试用或许可执行机制;不得移除许可声明;不得将软件呈现为"自由或开源软件"(因其含专有模块且非 GPL 构建)。
这条边界对集成方至关重要:你从本仓库源码自行构建并分发时,走的是 GPLv3(或商业许可)路径;而你下载官方二进制再分发时,走的是 EULA 路径,两条路径的权利与义务完全不同。
7. 实操指引:在仓库中定位任一文件的许可状态
基于上述机制,判断与使用流程可以归纳为:
- 先查文件 SPDX 头部。命中
GPL-3.0-or-later OR LicenseRef-SerialStudio-Commercial→ 双许可文件,可选 GPL;命中单独的LicenseRef-SerialStudio-Commercial→ Pro 模块,需商业许可,且默认构建不会包含它; - 无头部则查 REUSE.toml的注解块,注意
precedence字段(override时注解为唯一事实来源,文件内出现的 SPDX 字符串仅作文本引用); - 复现纯 GPL 构建:按默认选项(
BUILD_GPL3=ON、BUILD_COMMERCIAL=OFF)配置即可,构建系统将强制保证结果不含商业模块; - 评估官方二进制:14 天试用期内全功能可用,但仅限评估;生产部署前需激活许可,且再分发需书面分发许可(EULA.md 第 3、4 节)。
配套文档可继续深入:商标与品牌(名称、Logo)见 TRADEMARKS.md;贡献流程与贡献者许可协议见 CONTRIBUTING.md;第三方组件全清单见 REUSE.toml 与 LICENSES/。许可咨询与商业洽谈联系 alex@serial-studio.com。
8. 小结
Serial Studio 的许可工程展示了"文件级元数据 + 集中式注解 + 构建期强制"三层叠加的做法:SPDX 头部给出每个文件的法律身份,REUSE.toml 用带优先级语义的注解覆盖头部缺失的场景并沉淀依赖策略(如 mbedtls 取 Apache 臂、无 LGPL 依赖承诺),CMake 则把互斥开关、商业凭据校验与盐值派生守卫变成可失败的构建步骤。对使用者而言,核心结论是:默认克隆即得 GPLv3 构建,Pro 模块边界以 SPDX 单项表达式精确划定,官方二进制则另受 EULA 与 14 天试用约束——三者各辖其域,互不替代。
【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考