Deploying C++ Game in Linux

Deploying C++ game in Linux

  1. This depends on what the distribution is derived from. Generally, there's no need to recompile a program on something like Ubuntu under Fedora so long as the code remains unchanged. Since Ubuntu and Fedora would have to be using the same libraries (albeit in different locations perhaps) and anything OpenGL-related would be a driver issue; therefore it is hardly a requirement to recompile your software. I would be extremely surprised if you had to recompile your software since all distros use pretty much the same set of libraries/got bash/use the Linux kernel but have different package managers. The last part is where it gets complex:

  2. The aforesaid distributions have different package managers which requires you to repackage your software accordingly. You could release pre-compiled binaries under a tar.gz file and simply have distro maintainers package the software for you; though if you want to control how your software is distributed then you should better do that yourself. Because of this issue surrounding the many package managers out there, people still resort to recompiling source code through a make file which can be generated through cmake. This only happens if certain dependencies are, for whatever reason, 'renamed' in which case because of a simple name change the program magically doesn't find the dependency. Since there's also no naming convention it even makes life harder. The most important virtue here is Trust, and Trust therein to have developers follow naming conventions so everyone can reference the same package of the same name.

The best distros to support are the most popular ones: Ubuntu and openSUSE would be great starting points. Linux Mint, Fedora and Red Hat and Debian use package managers likewise of the aforesaid.


  1. Meanwhile, you should know that you can't statically link GPL'd code in your software without also making your software also GPL. A way to work round this is to resolve dependencies by either: A. Including the relevant dependencies in the same folder as the executable (much like *.dlls on Windows) or to depend on the system upon which your program is run to look inside the same directories your program looked into while compiling and linking. The latter is actually riskier since it bears the assumption the user will have the libraries and unmodified. The former will make your overall software use less storage, but including the dependencies would only mean increasing the size of your package but ensures consistency across all systems.

As for installation, you would need a bash executable that moves the contents of your directory to the right locations. Generally, the main app goes into /usr/bin and any app-related data goes into the home folder. This again depends on the distro; look for a .local directory, or you could create a directory dedicated to your app that is hidden. Hidden folders are prefixed with a period. Why put this stuff in the home folder, and what? The why: because the home folder gives read-and-write permissions to everyone by default. The what: anything that needs to be run with the app without the user having to authorise it. Dependencies should thus be located in the home folder, preferably under your own directory. Different conventions follow; some may disagree with me on this one.

You might also want to use steam's API which does most of this work for you. Under Steam, your app may be under steam's own directory and thus functions as a steam APP with all the functionality therein.

http://www.steampowered.com/steamworks/

To find out more about how to get your app on steam. I have to say I was really impressed, and they even include code samples. The best part is that this API is on Linux as well. I don't know much apart from that Steam would be handling the execution of your app through its own layer. Wherein, there's no need to independently distribute your app the previous steps.

Note that you can also distribute your software through the Ubuntu Software Centre if you are interested.

http://developer.ubuntu.com/apps/

Though, Ubuntu has more focus on getting apps running regardless of platform.

Know that Linux has no single convention, but its convention is simply derived from pragmatism, not by theory. At the end of the day, how you want your software run on Linux is up to you.

How to properly release C++ software (game) on Linux

I found a solution that seems to work and I think is also used by other games on Steam/GOG/Itch that do not use wine/mono/... to just make their windows game work on Linux.

I installed Ubuntu 18 (or 16 if you prefer it to work on older OSses too) and set up my build environment there (I had to rewrite some of my C++ code because not all new C++ conventions are available yet). Then I installed another Ubuntu 18 machine and started the executable there. It told me which libraries it was missing and I manually added every one of them from my build-Ubuntu 18. After that, my game worked.

Then I installed Linux Mint 19 and hooray... it worked!

Then I ran the executable on Ubuntu 20 and Arch Linux (latest update) and it needed another lib that I also got from my build-Ubuntu 18, and it worked.

I passed on the executable to someone else and it worked fine on his Linux machine too...

What I mean is: if I build it for the lowest version of glibc, it seems to work fine on newer systems too.

This may not be the most waterproof system out there, but at least, like with almost all other games on Steam/GOG, I can now say that the game will run on Ubuntu 18, Ubuntu 20 and know that it also works on several other distro's.

And I don't need any third party tool like Flatpak and Snapcraft. I may still end up using them for supporting their good cause and also because it helps spread my game as well. But then, I will first need to finish my real game of course...

I am marking this as the solution as long as nobody is able to give me a better one without me creating accounts on third party services.

How to deploy a SFML game server to a Linux Server?

Linux systems search for shared libraries by utilizing the LD_LIBRARY_PATH environment variable and they don't automatically look for binary files next to the application, as it is the case on Windows.
An very often used method of deploying with shared libraries, is to include them in an sub-directory or similar and instead of launching the application directly run a shell script that would add the directory with the libraries temporarily to ?LD_LIBRARY_PTH` and then start the application.

The other issue you're having is related to dependencies.

For shared libraries you'd not only have to provide the shared SFML libraries, but also provide the shared libraries of the dependencies, unless you can 100% guarantee that the target system will have the equal library version.

If you just build static libraries of SFML, they'll still point to shared runtime libraries and alike, thus if you don't provide the matching version with the application, it will simply fail to start, since it can't find the library.
If you link statically against the runtime libraries you wouldn't need to provide shared libraries for your application, but since the SFML libraries were still link dynamically against the runtime libraries, they request the shared libraries anyways.

So if you don't want to any shared library files any more, you'll need to link SFML statically against the runtime library (uncheck BUILD_SHARED_LIBS and check SFML_USE_STATIC_STD_LIBS).

Keep in mind that when linking statically, you'll need to link statically against all dependencies - -static might be useful.

Developing and deploying games for Windows, Mac (& Linux)

The "Java platform" works reasonably well, once the JRE is installed -- there is JWS (Java Web-Start) and the JRE can be packaged with the client I suppose.

There are a number of cross-platform game libraries for Java with OpenGL bindings such as Java Monkey Engine. There are also 2D libraries such as Slick. If you want a "really lightweight game library" (e.g. just basic OpenGL, keyboard/mouse IO, and precise timing) then I would highly recommend LWJGL which provides just that.

Java isn't suitable for all games -- but it be an option that worked very well for me for a course project. It was developed on Windows/Linux and played on Windows/Linux/OS X (get a non-ancient JRE installed for OS X ... bundled version is often severely dated.)

Edit I lied -- I really really dislike Java so I actually wrote my game/projects in Scala [it is a must to try for a JVM target] and just took advantage of the JVM and existing libraries ;-) They ran well with no performance/GC issues on Java 6u18+.

How can I deploy a C++11 program (with dependencies) on CentOS 6, whose GCC is C++03?

Actually, you can distribute a program compiled with a newer g++ compiler on a vanilla CentOS 6 platform. There are several ways to do this: The easiest is to use the DevToolset 3, which will give you g++ 4.9.2 (the dev toolset 2 will give you gcc 4.8.2). Then, just compile your application with this g++. When distributing your software, you need to make sure to also ship the libstdc++.so that is being shipped with g++ 4.9. Either set the LD_LIBRARY_PATH so it gets picked up on startup, or set the RPATH to tell your executable where to look first for libraries.

Essentially, you can do this also with newer compilers, but then you first need to compile the compiler itself. If you don't want to compile a compiler first, go with a respective dev toolset and you should be fine.

Yes, you can also try to statically link libstdc++.a. Search for the option -static-libstdc++:

When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically.

But if you statically link, you will not get any security updates etc. Granted, you will not get the updates, if you ship libstdc++.so on your own as well, but incremental updates maybe easier.

And with respect to running your application: The rule of thumb is: Compile on the oldest platform you need to support, then your binaries (with self-shipped libstdc++ and other required libs) will likely work also on newer versions. That is, if you compile on CentoOS 6, and it works, then you can expect it to also work on CentOS 7. On a related subject, this is exactly the reason why for instance AppImage and related solutions recommend to build on an old system.

Building an app on Linux for Windows

I can't recommend enough not cross-compiling, get a virtual machine with your target OS and install the native toolchain plus any required libraries. This is simpler, less error-prone, and issues are easier to diagnose.

There's also the massive advantage that you can test the software on the platform you're building on. Remember you'll still need access to your target OS in order to test what you have built, so in reality cross-compiling offers you no advantage.

Of course everything I've said is irrelevant if you're building for an embedded OS whose toolchain is designed for cross-compilation anyway.

Wrote an SDL game using C++ and want to deploy it

I created an installer using NSIS some time ago. I started out from scratch, and got a reasonable installer in 5-10 minutes, following the examples. Best of all: it's free!

Where do I put third-party libraries to set up a C++ Linux development environment?

Where to put libraries

The best solution is to use your Linux distribution's packaging system (apt-get, yum, or similar) to install libraries from distro-provided packages wherever possible.

If the distro's packaged libraries aren't of a recent enough version, or if you need some nonstandard build options, or if you need a library that your distro doesn't provide, then you can build and install it yourself. You have two main options for where to put the library:

  • /usr/local (libraries under /usr/local/lib, headers under /usr/local/include). This installs the libraries systemwide and is probably the simplest solution, since you should then be able to build against them without taking any extra steps. Do NOT install libraries directly under /usr, since that will interfere with your distro's packaging system.
  • Under your project directory, as you did under Windows. This has the advantages of not requiring root access and not making systemwide changes, but you'll have to update your project's include paths and library paths, and you'll have to put any shared library files someplace where the dynamic linker can find them (using LD_LIBRARY_PATH or ld.so.conf - see the link for more details).

How libraries work

See David A. Wheeler's excellent Programming Library HOWTO. I'd recommend reading that then posting any specific questions as new topics.

How to distribute your program

Traditionally, Unix / Linux programs do not include copies of their dependencies. It's instead up to the end user or developer to install those dependencies themselves. This can require a "large README," as you said, but it has a few advantages:

  • Development libraries can be installed, managed, and updated via the distro's package manager, instead of each source copy having its own set of libraries to track.
  • There's only one copy of any given library on a system, so there's only one place that needs updating if, for example, a security flaw is found. (For example, consider the chaos that resulted when zlib, a very widely used compression library, was found to have a security flaw, so every application that included an affected version needed to be updated.)
  • If your program is popular enough (and is open source or at least freely available), then package maintainers for various Linux distributions may want to package it and include it in their distro. Package maintainers really don't like bundled libraries. See, for example, Fedora's page on the topic.

If you're distributing your program to end users, you may want to consider offering a package (.dpkg or .rpm) that they could simply download and install without having to use source. Ideally, from the end user's perspective, the package would be added to distros' repositories (if it's open source or at least freely available) so that users can download it using their package managers (apt-get or yum). This can all get complicated, because of the large number of Linux distros out there, but a Debian/Ubuntu compatible .dpkg and a Red Hat/CentOS/Fedora-compatible .rpm should cover a good percentage of end users. Building packages isn't too hard, and there are good howtos online.



Related Topics



Leave a reply



Submit