Andreia Gaita 将在今年的 OSCON 大会上发表演讲,主题为 跨平台开发者自白。她是一位长期的开源和 Mono 贡献者,主要使用 C#/C++ 进行开发。Andreia 在 GitHub 工作,专注于为 Visual Studio 构建 GitHub 扩展管理器。
在她的演讲之前,我采访了 Andreia,询问了关于跨平台开发以及她在 16 年的跨平台开发者生涯中学到的知识。
您发现哪些语言最容易进行跨平台代码开发,哪些最难?
这与其说是哪些语言好,不如说是这些语言可用的库和工具。语言可用的编译器/解释器/构建系统决定了使用它们进行跨平台工作的难易程度(甚至是否可能),而 UI 和本机系统访问可用的库决定了您可以与操作系统集成多深入。考虑到这一点,我发现 C# 是跨平台工作的最佳选择。该语言本身包含允许快速本机调用和精确内存映射的功能,如果您希望代码与操作系统和本机库对话,那么这些功能是您真正需要的。当需要非常特定的操作系统集成时,我会切换到 C 或 C++。
您使用过哪些跨平台工具包/抽象?
我的大部分跨平台工作都是为其他人开发跨平台应用程序而开发工具、库和绑定,主要使用 Mono/C# 和 C/C++。在这个层面上,除了 glib 及其朋友之外,我没有使用太多抽象。对于任何包含 UI 的跨平台应用程序,我主要依赖 Mono,对于偶尔的游戏开发,我使用 Unity3D。我偶尔也会玩玩 Electron。
您构建系统的方法是什么?这如何因语言或平台而异?
我尝试选择最适合我使用的语言的构建系统。这样,它(希望)能减少我的麻烦。它需要允许平台和架构选择,对构建工件位置(用于多个并行构建)保持智能,并且具有良好的可配置性。大多数时候,我的项目都结合了 C/C++ 和 C#,我希望从同一个源代码树同时构建所有不同的配置(Debug、Release、Windows、OSX、Linux、Android、iOS 等等),这通常需要选择和调用不同的编译器,并为每个输出构建工件使用不同的标志。因此,构建系统必须让我在不(过多地)妨碍我的情况下完成所有这些操作。我时不时地尝试不同的构建系统,只是为了看看有什么新东西,但最终,我最终还是回到了 makefile 和 shell 和 batch 脚本或 Perl 脚本的组合来驱动它们(因为如果我想让用户构建我的东西,我最好选择一种随处可用的命令行脚本语言)。
您如何在对原生外观和感觉的渴望与对统一用户界面的需求之间取得平衡?
跨平台 UI 很难!多年来,我已经实现了几个跨平台 GUI,这是我认为没有最佳解决方案的一件事。基本上有两种选择。您可以选择一个跨平台 GUI 工具包,并做一个在您支持的所有平台上感觉都不太对劲的 UI,但代码库小且维护成本低。或者,您可以选择开发特定于平台的 UI,这些 UI 将看起来和感觉都像原生 UI,并且与更大的代码库和更高的维护成本很好地集成。这个决定真正取决于应用程序的类型、它有多少功能、您有多少资源以及您要交付到多少个平台。
最后,我认为随着 Electron 等框架的出现,用户对“一个 UI 统治一切”的容忍度有所提高。我有一个 Chromium+C+C# 框架的业余项目,有一天希望能让我用 C# 构建 Electron 风格的应用程序,从而给我两全其美的体验。
构建/打包依赖项对您来说是一个问题吗?
我对依赖项的使用非常保守,因为我曾多次被破坏的 ABI、冲突的符号和丢失的软件包所困扰。我决定我要定位的操作系统版本,并选择依赖项的最低公分母版本以最大程度地减少问题。这通常意味着在同一台机器上并排安装五个不同版本的 Xcode 和 OSX Framework 库、五个不同版本的 Visual Studio、多个 clang 和 gcc 版本,以及一堆运行各种其他发行版的 VM。如果我不确定我定位的操作系统中软件包的状态,有时我会静态链接,有时会子模块依赖项,以确保它们始终可用。最重要的是,除非我真的、真的需要那里的东西,否则我会避免使用前沿技术。
您是否使用持续集成、代码审查和相关工具?
一直都在用!这是保持理智的唯一方法。我在项目中所做的第一件事是设置跨平台构建脚本,以确保尽早实现一切自动化。当您定位多个平台时,CI 至关重要。每个人都不可能在一台机器上构建所有不同的平台组合,而且一旦您不构建所有平台,您就会在不知不觉中破坏某些东西。在共享的多平台代码库中,不同的人拥有不同的平台和功能,因此保证质量的唯一方法是将跨团队代码审查与 CI 和其他分析工具相结合。这与其他软件项目没有什么不同,只是故障点更多。
您依赖自动化构建测试,还是倾向于在每个平台上构建并在本地进行测试?
对于不包含 UI 的工具和库,我通常可以通过自动化构建测试来解决问题。如果有 UI,那么我需要两者都做——可靠的、可脚本化的 UI 自动化对于现有的 GUI 工具包来说是罕见的,甚至不存在,所以我要么必须投入创建跨我想要支持的所有平台的 UI 自动化工具,要么我手动完成。如果一个项目使用自定义 UI 工具包(例如,像 Unity3D 那样的 OpenGL UI),那么开发可脚本化的自动化工具并自动化大部分内容就相当容易了。尽管如此,没有什么比人类通过几次点击来破坏东西的能力更强的了!
如果您正在进行跨平台开发,您是否支持跨编辑器构建系统,以便您可以在 Windows 上使用 Visual Studio,在 Linux 上使用 Qt Creator,在 Mac 上使用 XCode?或者您是否倾向于支持一个平台,例如所有平台上的 Eclipse?
我赞成跨编辑器构建系统。我更喜欢为不同的 IDE 生成项目文件(最好以一种更容易添加更多 IDE 的方式),使用构建脚本可以从 IDE 为它们所在的平台驱动构建。编辑器是开发人员最重要的工具。学习它们需要时间和精力,而且它们是不可互换的。我有我最喜欢的编辑器和工具,其他人也应该可以使用他们最喜欢的工具。
您首选的用于跨平台开发的编辑器/开发环境/IDE 是什么?
跨平台开发人员注定要选择在最多平台上工作的最低公分母编辑器。我喜欢 Visual Studio,但我不能指望它除了 Windows 工作之外的任何事情(而且您真的不想让 Windows 成为您的主要交叉编译平台),所以我不能把它作为我的主要 IDE。即使我可以,跨平台开发的一项基本技能是了解和使用尽可能多的平台。这意味着真正了解它们——使用平台的编辑器和库,了解操作系统及其假设、行为和限制等等。为了做到这一点并保持我的理智(和我的快捷键肌肉记忆),我必须依赖跨平台编辑器。所以,我使用 Emacs 和 Sublime。
您最喜欢的过去和现在的跨平台项目有哪些?
Mono 是我一直以来最喜欢的,毫无疑问,大多数其他项目都以某种方式围绕它展开。Gluezilla 是我多年前做的一个 Mozilla 绑定,允许 C# 应用程序嵌入 Web 浏览器视图,那是一个难题。在某个时候,我有一个 Winforms 应用程序,在 Linux 上构建,在 Windows 上运行,其中嵌入了一个 GTK 视图,该视图正在运行一个 Mozilla 浏览器视图。CppSharp 项目(以前称为 Cxxi,以前称为 CppInterop)是我启动的一个项目,用于为 C++ 库生成 C# 绑定,以便您可以从 C# 调用、创建实例和子类化 C++ 类。它的完成方式是,它会在运行时检测您将在哪个平台上运行以及使用哪个编译器来创建本机库,并为其生成正确的 C# 绑定。那很有趣!
您认为跨平台开发的未来走向是什么?
我们构建原生应用程序的方式已经在改变,我感觉各种桌面操作系统之间的视觉差异将变得更加模糊,因此构建可以合理集成但不是完全原生的跨平台应用程序将变得更容易。不幸的是,这可能意味着应用程序在可访问性方面会更差,并且在充分利用操作系统方面创新性会降低。工具、库和运行时的跨平台开发是我们知道如何做得很好的事情,但在跨平台应用程序开发方面仍有许多工作要做。
3 条评论