简体   繁体   English

在 Linux 上分发一个 C++ 应用程序(游戏):共享或 static 库?

[英]Distribute a C++ application (game) on Linux: shared or static libraries?

I have a C++ game/application which use several libraries: OpenGL, OpenAL, Curl, Freetype2, GLFW, etc. Should I distribute my C++ binary application on Linux using the shared libraries or should I link them statically?我有一个 C++ 游戏/应用程序,它使用多个库:OpenGL、OpenAL、Curl、Freetype2、GLFW 等。我应该使用共享库在 Linux 上分发我的 C++ 二进制应用程序,还是应该静态链接它们?

  • Static libraries : it seems a good solution to have my application working on most of the Linux distributions. Static 库:让我的应用程序在大多数 Linux 发行版上运行似乎是一个很好的解决方案。 Indeed, my application won't depend on libraries version installed on the system.事实上,我的应用程序不会依赖于系统上安装的库版本。 Unfortunately, it seems quite painful to perform this static link because most of libraries don't provide a static library file (*.a) by default.不幸的是,执行这个 static 链接似乎很痛苦,因为默认情况下大多数库不提供 static 库文件 (*.a)。 Therefore, I have the felling that it isn't a common pratice.因此,我觉得这不是一种常见的做法。 However, I checked several games distributed by GOG.com and all games I checked don't depend of shared libraries (checked with lddtree )但是,我检查了 GOG.com 分发的几款游戏,我检查的所有游戏都不依赖于共享库(使用lddtree检查)
  • Shared libraries : it seems to be the recommended solution but it seems almost impossible that my C++ application will be compatible with all Linux distributions.共享库:这似乎是推荐的解决方案,但我的 C++ 应用程序似乎几乎不可能与所有 Linux 发行版兼容。 I should build a binary specific for Ubuntu 16.04, then build another binary for Ubuntu 20.04, etc... That seems very time consuming for a single developper.我应该构建一个特定于 Ubuntu 16.04 的二进制文件,然后为 Ubuntu 20.04 构建另一个二进制文件,等等......对于单个开发人员来说这似乎非常耗时。

Did I miss something?我错过了什么? Note: on Windows, it is more simple: I can use shared libraries (*.dll) and provide them with my application.注意:在 Windows 上,它更简单:我可以使用共享库 (*.dll) 并在我的应用程序中提供它们。 On Linux, it seems quite difficult to provie the shared libraries.在 Linux 上,似乎很难提供共享库。 Example: "libcurl-gnutls.so.4" depends of > 20 others shared libraries: it is not the case on Windows with "libcurl-x64.dll" which is self sufficient.示例:“libcurl-gnutls.so.4”依赖于 > 20 个其他共享库:Windows 上的情况并非如此,“libcurl-x64.dll”是自给自足的。

I finally answer myself to my question after analyzed dozens of video games more.在分析了数十款电子游戏后,我终于回答了自己的问题。 There are mainly two categories:主要有两类:

  1. Games built with only static libraries.仅使用 static 个库构建的游戏。 Most of the time, it seems related to games using Unreal Engine.大多数时候,它似乎与使用虚幻引擎的游戏有关。

  2. Games built with shared libraries which are delivered with the game.使用随游戏交付的共享库构建的游戏。 The game starts via a bash script and use LD_LIBRARY_PATH to define the path to these shared libraries.游戏通过 bash 脚本开始,并使用 LD_LIBRARY_PATH 定义这些共享库的路径。 Seems the best solution for me even if it is not the spirit of the shared libraries.对我来说似乎是最好的解决方案,即使它不是共享库的精神。

Side notes:旁注:

  • Game distributed through packages (RPM, DEB, etc..) for the main versions of the Linux distributions exist but are quite rare. Linux 发行版的主要版本通过软件包(RPM、DEB 等)分发的游戏存在,但非常少见。
  • There are also games using dynamic libraries which are not distributed with the game but only 60% of these game are able to start on my Linux distribution !还有一些使用动态库的游戏没有随游戏一起分发,但只有 60% 的游戏能够在我的 Linux 分发中启动!
  • I haven't seen game using Snap / Flatpak / AppImage.我还没有看到使用 Snap / Flatpak / AppImage 的游戏。

I don't see a reason why your C++ shared library would necessarily be incompatible with different Ubutu releases, or why it would need to resort to LD_LIBRARY_PATH.我看不出为什么您的 C++ 共享库必然与不同的 Ubutu 版本不兼容,或者为什么它需要求助于 LD_LIBRARY_PATH。 Different releases (version numbers) of a shared library can co-exist in the system, and the program loader is able to search for the correct version based on ELF metadata annotated in the binary.共享库的不同版本(版本号)可以在系统中共存,程序加载器可以根据二进制文件中注释的 ELF 元数据搜索正确的版本。 Moreover, GNU/Linux shared objects are equivalent to Windows DLLs for this purpose.此外,为此,GNU/Linux 共享对象相当于 Windows 个 DLL。 If your code is portable, you may even use MinGW to build both.so and.dll objects from the same source file (GNU build system, aka Autotools may be of great help).如果您的代码是可移植的,您甚至可以使用 MinGW 从同一个源文件构建 .so 和 .dll 对象(GNU 构建系统,又名 Autotools 可能会有很大帮助)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM