在Linux上部署C++游戏

10

我是一名独立游戏开发者,使用Windows平台开发游戏,但对于Linux以及为其部署应用程序几乎没有任何经验。我正在优化自己用C++'11编写的游戏,基于SDL 2.0以及其他几个跨平台依赖项(例如AngelScript或PugiXML)在Windows上,并希望在Linux上分发它,并有以下几个问题。

1.) 主要的Linux发行版是否ABI(应用程序二进制接口)兼容?或者我需要在每个支持的发行版/平台上编译我的游戏吗?

2.) 如果是这样,哪些发行版/平台是合理的选择来进行支持?

3.) 在Linux上安装应用程序及其依赖的最佳方法是什么?我已经阅读了关于deb和rpm系统的文章,但仍感到困惑--是否有任何自动生成不同发行版的安装程序的方法?

4.) Steam如何在Linux上工作?我应该如何准备我的应用程序通过Steam分发?

如果我提出了错误的问题,请原谅,整个Linux世界对我来说还是很陌生的,我看了各种文章和手册页也搞混了...


抱歉重新打开这个问题,但您是否曾经能够进行过稳定的Linux发布?我正在尝试做同样的事情,但在不同发行版上的不同glibc版本方面遇到了困难。 - scippie
3个回答

4
  1. 这取决于发行版的来源。通常情况下,只要代码保持不变,在像Ubuntu到Fedora这样的操作系统上无需重新编译程序。由于Ubuntu和Fedora必须使用相同的库(可能在不同的位置),而任何与OpenGL相关的都是驱动程序问题;因此,重新编译软件几乎不是必需的。如果您需要重新编译软件,我会感到非常惊讶,因为所有发行版使用的基本上是相同的库/使用bash/使用Linux内核,但具有不同的包管理器。最后一个部分才是复杂的所在:

  2. 上述发行版具有不同的包管理器,这需要您相应地重新打包软件。您可以在tar.gz文件中发布预编译的二进制文件,并简单地让发行版维护者为您打包软件;但是,如果您想控制如何分发您的软件,则最好自己完成。由于围绕着众多包管理器的这个问题,人们仍然通过makefile重新编译源代码,这可以通过cmake生成。只有在某些依赖项出现“重命名”的情况下,才会发生这种情况,因此由于名称更改,程序神奇地找不到依赖项。由于没有命名约定,这甚至使生活更加困难。这里最重要的美德是信任,信任开发人员遵循命名约定,以便每个人都可以引用相同名称的相同软件包。

最好支持的发行版是最受欢迎的发行版:Ubuntu和openSUSE将是很好的起点。Linux Mint、Fedora、Red Hat和Debian也使用与上述类似的包管理器。

  1. 同时,您应该知道,您不能在没有使您的软件成为GPL的情况下静态链接GPL的代码。解决依赖项的一种方法是:A.将相关依赖项包含在可执行文件所在的同一文件夹中(就像Windows上的*.dll文件)或依赖于运行程序的系统来查找编译和链接时您的程序所查找的相同目录。后者实际上更加危险,因为它假设用户拥有库并且未经修改。前者将使您的整体软件使用更少的存储空间,但包含依赖项只会增加软件包的大小,但确保所有系统的一致性。

至于安装,您需要一个bash可执行文件,将您的目录内容移动到正确的位置。通常,主应用程序放置在/usr/bin中,任何与应用程序相关的数据都放在主目录中。这又取决于发行版;查找.local目录,或者您可以创建一个专用于您的应用程序的隐藏目录。隐藏文件夹以句点为前缀。为什么将此内容放置在主目录中?因为默认情况下,主目录为每个人提供读写权限。什么是放置在主目录中需要运行而无需用户授权的任何内容。因此,依赖项应位于主目录中,最好位于您自己的目录下。不同的约定遵循;有些人可能不同意我对此的看法。

您可能还想使用Steam的API,该API可以为您完成大部分工作。在Steam下,您的应用程序可能位于Steam自己的目录下,因此作为具有所有功能的Steam APP而运行。
要了解更多有关如何将您的应用程序放入Steam的信息,请访问http://www.steampowered.com/steamworks/。我必须说我印象非常深刻,他们甚至包括了代码示例。最好的部分是这个API也在Linux上。我不知道除此之外的东西,但Steam将通过其自己的层处理您的应用程序的执行。在其中,没有必要独立分发您的应用程序前面的步骤。
请注意,如果您有兴趣,还可以通过Ubuntu软件中心分发您的软件。http://developer.ubuntu.com/apps/。尽管Ubuntu更专注于使应用程序在任何平台上运行。
请注意,Linux没有单一的约定,但它的约定仅仅源自实用主义,而不是理论。归根结底,您希望如何在Linux上运行您的软件取决于您。

谢谢,这绝对是这里最好的答案 - 只有一个问题:如果我将依赖项存储在“home”目录中,那么它们是否对所有用户都可用?资产也应该存储在“home”中吗? - PiotrK

4

我不是游戏开发者,来自开源社区,所以无法就发布二进制文件提供建议。不过我会尽力回答你的问题:

Valve有一个针对Linux的Steam运行库(https://github.com/ValveSoftware/steam-runtime) - 这将是移植游戏的最佳方式。我在他们的Linux开发视频中看到了它被提到,我的理解是它捆绑了一堆库,包括SDL,并设置为模拟特定版本的Ubuntu。因此,如果您针对Steam运行时编写游戏,则可以在已移植Steam的任何Linux发行版上运行。

至于本地打包您的游戏,需要考虑的一件事是,如果您将其打包为deb或RPM并指示其依赖于发行版提供的库,则在更新库时可能会导致应用程序崩溃(某些发行版经常更新库-其他则更稳定)。动态链接系统库对于开源软件很有效,因为人们可以在库更改时修补代码,但不适用于闭源软件。

您可以在构建时静态链接您的二进制文件,这意味着您有一个更大的二进制文件大小。但是,当库被更新时,您就不必担心应用程序崩溃。

像Chrome这样的一些程序捆绑了自己的库(本质上是系统库的分支),这使得下载大小更大,但也有可能导致安全问题,人们倾向于反对这种做法。(参见:http://lwn.net/Articles/378865/


我无法静态链接所有内容,因为我的某些依赖项受GPL许可证保护。 - PiotrK
你可能可以打包这些库(但是你需要提供GPL许可的库的源代码,或者至少链接到源代码)。或者你可以动态链接到系统库,并接受将来某个时候可能会出现故障的风险。我内心的怀疑者认为,如果你开源你的游戏,那么这将会更容易 - 毕竟你已经在使用开源库了。 - Matt
@PiotrK 如果你的库采用GPL许可,那么你的代码也必须遵循该许可;你可以链接到LGPL代码而不使你的代码开源,但GPL代码要求你的代码也必须遵循GPL(或者你与库作者达成另一种许可协议)。 - Elliott Frisch
@PiotrK 可能有一个BSD版本,但是BSD的人们做像libedit这样的事情,而不是使用readline,这其中肯定有原因。 - Elliott Frisch
1
@ElliottFrisch 是的,仍然有人敢称GPL为“言论自由的自由”...类似病毒的许可证是个大麻烦,它们绝对不意味着自由。我过去支持和贡献了一些开源项目,发布我的代码在X11/BSD类似的许可证下。我只是不理解GPL背后的“自由”。这并不是为了引发争吵,提前感谢... - PiotrK
显示剩余5条评论

1

1.) 不,主要Linux发行版的ABI并不完全兼容。狭义上来说,它们是“大多数”兼容的。但广义上来说,在系统工作、配置等方面有许多不同之处。另一方面,“制作软件包”本身并不是一个大问题,只需要一些工作。此外,对于“主要”的发行版(如Debian),在所有派生版本(如Ubuntu、Mint等)上都可以使用(几乎总是)。

2.) 支持的好的起点列表包括:Debian (.deb)、RedHat和Fedora (.rpm)。它们的软件包格式和工具已经成熟并广为人知。这将“覆盖”很多派生版本。

3.) 有一些“跨发行版”的软件包构建器,但大多数情况下无法胜任任务。一旦你掌握了写定义脚本的技巧,大多数软件包格式的脚本编写并不难。此外,一些商业工具有“Linux安装脚本生成器”,可以为您处理这些事情(它们不会生成.deb或.rpm文件,而是类似于Windows EXE安装程序的复杂shell脚本)

4.) 抱歉,我不太了解Steam。O:)

根据我的经验,最好的方法是接受一个丑陋的事实,即您需要选择几个主要的发行版和它们的版本(因为在不同的版本之间可能会有很大的变化),并为它们制作软件包,并经常在所有版本上进行测试。如果你不得不开发一些长期存在的内核模块/驱动程序,那么就要感到幸运,因为如果你将跟踪内核API变化添加到整个项目中...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接