由于 GPL(GNU 公共许可证)等开放源代码许可证对其应用程序的影响,专有软件开发商有时对嵌入式 Linux 平台心存疑虑。他们担心,在 Linux 上运行可能会使他们受到系统中其他软件组件的开放源代码许可证的约束,从而(通过诉讼)被要求与竞争对手、客户或公众共享源代码。
本文无意提供法律建议,而是根据我们许多客户使用 Digi Embedded Yocto、Linaro、Android 等通用平台的典型经验,为那些考虑在开源平台上部署专有应用程序的人提供一些实用的提示和建议。
安卓作为开放源代码的替代方案
诚然,避免 GPL 暴露的最安全、最可靠的方法就是根本不在 GNU/Linux 上运行:谷歌的 Android 操作系统为嵌入式设备提供了一个开放源代码的替代方案,该系统从设计之初就有意在其用户空间环境中取消 GPL 许可的软件,转而使用许可更为宽松的组件(如 Apache 或 BSD 许可),这些组件不要求衍生作品的开发者共享其源代码。
现代的安卓版本基本上不包含 GPL 组件(除了 Linux 内核本身,它对应用程序没有任何限制)。常见硬件(包括 Digi 的 ConnectCore® SOM)都有发行版,Android 已成功移植到许多定制嵌入式电路板上。
另一方面,Android 在传统上不太适合无头系统,而且在某种程度上,它是由手机供应商和移动运营商维护的操作系统。虽然现在有很多人才可以在手机上创建应用程序,但在社区中,对使用嵌入式安卓系统的 BSP(电路板支持包)有经验的开发人员并不多见。
嵌入式 GNU/Linux 的 GPL 考虑因素
嵌入式 Linux 继续享有多种多样的硬件支持,并有一个庞大的开发人员社区在软件堆栈的各个层面开展工作。对于那些不反对使用 GPL 软件的系统的人来说,它可以是一个优秀、可靠的平台选择。至少根据我们的经验,绝大多数应用软件开发人员不会与客户、竞争对手或公众发生法律问题。
不过,嵌入式 Linux 的应用程序开发人员应牢记一些基本概念和经验法则。我们将介绍以下内容:
- GPL 基础知识
- 应用程序与驱动程序
- 开放源代码图书馆
- 静态链接与动态链接
- 进程间通信
- 标准 C 语言库
- Python 和其他编程语言
GPL 基础知识
GPL 许可的软件是开放源代码的:源代码必须与软件分发对象共享。但 GPL(包括 GPLv2 和 GPLv3)最基本也是最显著的概念是自我传播:GPL 许可证适用于任何衍生作品,即其他软件,例如包含 GPL 软件的应用程序,例如通过链接 GPL 库。简而言之,如果您的应用程序链接了 GPL 软件或以任何其他方式纳入了 GPL 软件,那么您就有义务分享您的源代码。
应用程序与驱动程序
在 Linux 系统中,驱动程序一般都是与 Linux 内核一起编译的组件,因此必须遵守 GPL。如果你为 Linux 编写驱动程序,你可能需要共享你的源代码,就像所有主要芯片供应商(恩智浦、德州仪器、英特尔等)所做的那样。也有一些厂商以二进制形式发布内核模块(主要用于加密设备和其他非常敏感的硬件),但这些非自由驱动程序的法律地位尚未确定。
无论如何,在驱动软件运行的总线接口层面,大多数外围设备都不存在严重的知识产权问题。当硬件设备确实包含有价值的 IP 时,这些 IP 通常由设备内部的固件管理,而不会通过总线接口暴露给驱动程序。另一方面,应用程序在用户空间层面运行:它可以与 Linux 内核通信(通过库的系统调用),但人们普遍认为,应用程序与 Linux 内核不存在任何许可依赖关系。
开放源代码图书馆
C/C++ 应用程序通常必须与公开提供的库链接,才能访问系统设施,避免重新发明轮子。(例如,使用蓝牙的 C 程序可能需要链接 libbluetooth,它是 BlueZ 协议栈的一部分,并获得 GPL 许可)。由于 GNU/Linux 上的许多系统库都是 GPL 许可的,因此应用程序在链接这些库时可能会承担 GPL 义务。
静态链接与动态链接
人们普遍认为,动态链接(而不是静态链接)可以保护应用程序不受 GPL 继承的影响,但实际上这是一个有争议的问题,在法庭上还没有完全解决。FSF(自由软件基金会,与 GNU 相关)坚持认为 GPL确实适用于动态链接代码:https://www.gnu.org/licenses/gpl-faq.en.html#GPLStaticVsDynamic。
进程间通信
另一方面,C/C++ 应用程序并不需要与每个系统库链接。许多应用程序在没有 libbluetooth 或其他 GPL 许可库的情况下也能正常运行。如果应用程序不包含 GPL 许可的软件,即使它在 GNU 环境中运行,也不承担 GPL 义务。如果应用程序与 GPL 组件进行进程间通信(如使用 DBus 与 systemd 或其他守护进程通信),一般认为这并不赋予应用程序任何 GPL 义务。
标准 C 语言库
几乎所有 C 应用程序都需要链接的一个库就是标准 C 库:Linux 上最常见的实现是 GNU 的 glibc。尽管嵌入式 Linux 系统中也有采用许可协议的其他 C 库可供选择(如 uclibc 或 musl),但对于专有应用程序开发人员来说,并没有必要因为许可协议而避开 GNU C 库:因为它不是GPL。
GNU C 库实际上是LGPL 许可的:两者之间的主要实际区别在于 LGPL("有限 GPL")明确允许动态链接:如果你的应用程序动态链接 glibc(而不是静态链接),你就没有义务分享你的源代码。
Python 和其他编程语言
其他语言呢?如果你的代码不是用 C 编写的,你能因为没有链接到 GPL 库而规避 GPL 吗?例如,Python 解释器有自己的许可开源许可证。它不要求共享源代码。但 Python 许可证也与 GPL兼容。如果您编写并发布 Python 脚本,并且只导入非 GPL Python 库,那么您就可以避免 GPL 义务。另一方面,有些 Python 库是 GPL 许可的。(例如,如果它们依赖于底层的 GNU C 库,那么 GPL 就会传播到 Python 库)。事实证明,Python 应用程序的情况与 C/C++ 非常相似。
外卖
在 GNU/Linux 系统上,专有的闭源应用程序可以与 GPL 软件组件共存。由于 GPL 下动态链接的法律地位仍有争议,避免意外承担 GPL 义务的安全方法是确保您的应用程序不链接或直接 "包含 "任何 GPL 软件。这可能意味着要寻找某些 C 或 Python 库的替代品。但 GNU 标准 C 库本身并不在其中,因为它只有LGPL许可证。Linux 系统中还运行着许多其他 GPL 许可的组件,但普遍认为这些组件不会将其许可传播给代码并非源自这些组件的应用程序。
我们的团队可以提供设计指导、完整的硬件设计和应用程序开发服务、认证支持等。联系我们,开始对话。