为什么 bambu_networking 违反了 Bambu Studio 中的 AGPL

2026-05-18 1 阅读 marcosscriven
为什么 bambu_networking 违反 Bambu Studio 中的 AGPL 本文基于公共 Bambu Studio 源代码描述了 bambu_networking 的问题。这与 Bambu Lab 是否必须允许每个分叉进入其云无关。这是一个单独的主题。这是一个更简单的事情:Bambu Studio 是一个 AGPL v3 程序,其公开代码显示封闭的 bambu_networking 组件被下载、安装、动态加载并用作程序运行的一个组成部分。在我看来,这是一个 AGPL 合规性问题,因为 AGPL 要求提供程序的“对应源”,而“对应源”的定义还包括共享库和动态链接子程序的源代码,如果程序是专门设计为通过亲密的数据通信或控制流要求它们的话。这正是 Bambu Studio 代码中可见的情况。 1. Bambu Studio 是 AGPL,并且 bambu_networking 被描述为非自由 在 Bambu Studio README 中,Bambu Lab 自己写道: Bambu Studio 在 GNU AGPL v3 下获得许可 Bambu Studio 基于 PrusaSlicer,即 AGPL v3 PrusaSlicer 基于 Slic3r,即 AGPL v3 bambu 网络插件基于非自由库,无需插件,SD 卡打印在安装后仍然可用切片来源:https://github.com/bambulab/BambuStudio/blob/e8c7dc1b84f5e3816238e070e04eeeb67cd92783/README.md#L42-L52 这是整个问题的起点。 Bambu Studio 不是一个从头开始编写的闭源程序。它是从 AGPL 代码派生的 AGPL 程序。如果该插件在技术上被设计为 AGPL 程序操作的一部分,那么 Bambu Lab 不能简单地将运行时的关键部分移动到封闭的二进制文件中并将其称为“插件”。 2. bambu_networking 看起来不像是一个独立的附加组件 “插件”这个词本身并不能决定任何事情。重要的是程序的真实架构。公开代码显示bambu_networking不是用户独立启动的外部工具。 Bambu Studio:知道确切的库名称 知道网络代理版本 从 Bambu 服务器下载插件 将插件安装到 Bambu Studio 数据目录中 加载 bambu_networking.dll 、 libbambu_networking.so 或 libbambu_networking.dylib 解析 bambu_network_* 函数符号 将 C++ 结构和回调传递给插件 允许插件在主 UI 线程上执行工作 使用插件进行登录、监控、LAN/云打印, MakerWorld/MakerLab、相机、MQTT/设备消息、预设、灯丝、遥测和文件传输版本插件针对 Bambu Studio 版本通过 OTA 机制更新插件这不是偶然的兼容性。这是一个设计的运行时组件。 3.库名称和代理版本写入AGPL代码公共Bambu Studio标头包含:#define BAMBU_NETWORK_LIBRARY“bambu_networking”#define BAMBU_NETWORK_AGENT_NAME“bambu_network_agent”#define BAMBU_NETWORK_AGENT_VERSION“02.06.01.50”来源: https://github.com/bambulab/BambuStudio/blob/e8c7dc1b84f5e3816238e070e04eeeb67cd92783/src/slic3r/Utils/bambu_networking.hpp#L103-L106 这表明AGPL程序没有“任何插件”的通用机制。它知道特定的 Bambu 组件、特定名称和特定版本。这对于 AGPL 很重要,因为它表明该程序是专门为此组件设计的。 4. AGPL 代码为关闭的插件定义共享 ABI public bambu_networking.hpp 标头定义 Bambu Studio 和插件之间传递的回调类型: typedef std::function< void ( int online_login, bool login)> OnUserLoginFn; typedef std::function< void (std::string topic_str)> OnPrinterConnectedFn; typedef std::function OnLocalConnectedFn; typedef std::function< void ( int return_code, int Reason_code)> OnServerConnectedFn; typedef std::function < void (std::string dev_id, std::string msg)> OnMessageFn; typedef std::function OnHttpErrorFn; typedef std::function OnUpdateStatusFn; typedef std::function WasCancelledFn; typedef std::function< bool ( int status, std::string job_info)> OnWaitFn; typedef std::function < void (std::string dev_info_json_str)> OnMsgArrivedFn; typedef std::function< void (std::function< void ()>)> QueueOnMainFn;来源:https://github.com/bambulab/BambuStudio/blob/e8c7dc1b84f5e3816238e070e04eeeb67cd92783/src/slic3r/Utils/bambu_networking.hpp#L123-L145 这里最重要的是 QueueOnMainFn 。这不是一个简单的文本参数。它是一个回调,允许插件传递要在 Bambu Studio 的主 UI 线程上执行的函数。这种机制意味着控制流从插件返回到 AGPL 应用程序。这意味着 bambu_networking 不是一个独立的应用程序。这是