klei1984 / max

M.A.X. Port
https://klei1984.github.io/max/
MIT License
51 stars 4 forks source link

[Bug] Installing M.A.X. Port on Linux #30

Closed chw-1 closed 3 months ago

chw-1 commented 8 months ago

Operating System

Linux

Source of bug?

M.A.X. Port Version

0.6.1

M.A.X. and DOS or DOSBox Versions

1.04 on Ubuntu 23.10

What is the issue you encountered?

Hi @klei1984 ,

First thanks for you great work, it looks very promising! I just managed to launch M.A.X. and start a new game. I'm looking forward to playing the game again after so many years without crashing in round 1xx :) I really admire your endurance and energy you put into this project!

However I had some problems for launching the game, so I decided to open an Issue for sharing my problems and solutions.

I first tried to run M.A.X. Port on Ubuntu 20.04, but when launching the executable, it was complaining about missing libraries. Not all were in the official repositories, so I manually installed a few ones. But I gave up after some time, as I didn't see an end. Then I decided to upgrade to Ubuntu 23.10, as I saw in the build instructions that you used this version.

However this didn't work either. I got this error:

./max: error while loading shared libraries: libiconv.so.2: cannot open shared object file: No such file or directory

While searching for a solution, I found this post:

libiconv is included in the libc6 package as a GNU standard C library.

But I have libc6 installed:

sudo dpkg -s libc6
Package: libc6
Status: install ok installed

My solution is to build the required version and add it to the path using an environment variable:

tar -xzf libiconv-1.17.tar.gz
cd libiconv-1.17
./configure --prefix=/usr/local/libiconv
make
export LD_LIBRARY_PATH=/my_path/libiconv-1.17/lib/.libs/
cd max_install_dir
./max

This is for testing, I know that I can also install it to the system using sudo make install.

How did you setup your libiconv library?

Is there an easy way to install all the required dependencies ? It would be nice if M.A.X. Port could also run on Ubuntu versions, e.g. LTS, that are different from your environment. This would also avoid that other users run into similar problems.

I also had difficulties installing the deb package. For me it is not clear how to install it into the same folder than the M.A.X. installation. Finally I opened the deb file using my archive manager and extracted the files. Is this the right approach ?

If something is not clear, I will try to supply further information.

Anything to add?

No response

klei1984 commented 8 months ago

Unfortunately GitHub Actions preconfigured Ubuntu virtual environments, runners or build servers do not support 32 bit multilib environments anymore.

At the time when GitHub Actions dropped 32 bit support M.A.X. Port had no working 64 bit build so I had no choice, but to migrate the build system to docker images they provided at the time. This was the only workaround that GitHub professional support came up with for my use case. Since then, to support application dependencies better, minimum CMake 3.24 features are required by the build system which is supported by official update channels since Ubuntu 23.xyz only. Now the game is built on 23.10 till its gone from the image repository. 23.04 might work, I did not test it. I assume any older Ubuntu version would work as well if someone writes custom scripts and workarounds to install a decent version of CMake from a custom source and maybe a few other tools too...

Every dependency of the game is downloaded and configured by the build system itself. You do not need to build and install iconv or the other libraries by hand. The iconv library in particular supports both shared and static builds. I assume libiconv.so.2 is needed by the shared build configuration.

On my workstation I have a virtual Ubuntu 22.10 setup which I use for occasional (regression) testing when Ubuntu builds fail on GitHub. I quickly built the software using shared libs option on. The libiconv.so.2 thingy is produced by the build script itself as intended during compilation. It is found at <Build Target>/_deps/iconv-build/lib/libiconv.so.2 for example on my system. I did not run install targets, I assume they are not copied around into system folders or whatnot. As far as I know linux uses rpath and similar stuff any ways to find its own custom built shared dependencies which should work fine if you built the software yourself.

On Windows I release only static builds. Sharing static builds on linux is probably a very bad idea, so I only provide shared builds for that platform. I just realized that the generated deb packages do not contain any shared libraries. In the past I removed CPACK_DEBIAN_PACKAGE_SHLIBDEPS from the CMake file as it did nothing... now I added CPACK_DEBIAN_PACKAGE_DEPENDS and the previous too and it still does not do anything... I assume this means the deb files found on the download page are useless. Good to know.

As I mentioned I built today the shared lib version, but amusingly that is crashing on my test setup within a Pulse audio hook :D I have no clue whats going on... will try to look into these issues and will let you know if i figure out anything.

klei1984 commented 8 months ago

The crash in the audio hook is resolved. Apparently the miniaudio library crashes if it does not find an audio device, just "dummy audio". I will report the issue to the library maintainer.

I also looked into the deb package manager. As it turns out such packages never embed shared libraries, just instructs the deb package manager to make it sure that detected or more like expected shared libraries will be made available on the system upon install. This sucks... one way around this is to add CMake code that detects runtime libraries by searching various configured paths and copy them as files to install. Another way it seems is to use different package managers and package formats like snap, flatpak or appimage.

I have absolutely no clue about any of these so it will take some time to figure out how to provide linux packages for end users that are not absolute trash.

chw-1 commented 8 months ago

As far as I remember, Snap packages contain all required libraries for an application to run, in contrast to dep packages which might depend on other packages. Therefore Snap applications require more disk storage, but can be updated independently. I even found the post where I read this.

However, Snap seems to install an application or libraries to a specific location. Whereas M.A.X. Port needs to copy the files to the already existing M.A.X. directory.

DPKG seems to have the --root option to specify a directory. And Flatpack seems also to support custom locations, but my feeling is that this is not very user friendly, neither flexible.

To avoid all these problems, wouldn't it be possible to first install the M.A.X. Port package/snap to a default system location and then provide to the max executable the installation directory of M.A.X.? The max executable could then change the working directory to the M.A.X. installation directory.

klei1984 commented 8 months ago

I spent the whole day on this to no avail. CPACK and in particular dpkg-shlibdeps only finds dependent shared libraries that are installed onto the system via the OS package manager even if the tool gets all custom shared library paths. RPATH entires are not found in the executable or at least tools that would report RPATH show nothing, which is a bit odd as how on earth does it work then after build without install from arbitrary locations. Manually looking up runtime dependencies is useless as the library name never equals the required package name not to mention the architecture and the minimum versions. I do not know how these tools are useful at all if we have libraries that cannot be installed by the system from an official source any ways (e.g. libinconv which is embedded into libc).

Snap only works if the package is uploaded to the official snap store or something like that, so that I stopped looking into already. I also found flatpak to be inconvenient, stopped looking into it too.

I will try to do one more thing using DEB format still. I will let system libraries be installed by depends rules in the deb file libc6 (>= 2.34), libgcc-s1 (>= 4.2), libstdc++6 (>= 11) and will manually copy all custom libraries next to the executable and will "install" them like that. This of course means that if any of those depend on something that is not present on the system the game will not work or crash or who knows...

My problem with appimage format up front is that it seems to create a single file executable with all assets embedded into it which is not unpacked at all on "install." That is a no go as users can only configure setttings.ini by hand not via the executable...

Pointing the port executable to an existing MAX installation location could potentially work. But that means the resource manager module needs another rewrite... I am not doing that now as an asset installer is in the works anyways... Regardless, this does not resolve the distribution of shared libs issue on unix and the likes.

klei1984 commented 8 months ago

I was able to add the runtime dependencies to the deb installer. Now CMake does the dependency lookup automatically, but if CMake does not do dependency walking recursively it could happen that prerequisites of added dependencies would still be missing. The dependencies added by CMake also include basic system libraries that would normally the DEB installer would handle which might cause some unexpected issues later.

The --root option of dpkg sets not the install directory, but the dpkg "repository" root folder. This means that changing root will create new usr and var folders. var will contain dpkg metadata like how to remove the package later. Based on the folder structure, this will never install the max executable to an existing max game folder. Further issue is that in the alternative root folder if system packages are not installed, like libc6, then dpkg will not be able to configure the installed package correctly. To me, to a novice, this indicates that the --root option is not a viable option. Furthermore, it seems that if we want to install anything under linux, then it should follow the GNU standard installation directories concept which means that e.g. under usr/local/ the game files would be thrown into a big mass of existing folders where tons of files are present which means that file names like settings.ini or readme.txt or any such names could clash with something. Even worse, it could easily happen that some shared libs would be present in these common folders e.g. under lib that are incompatible or would make other applications incompatible. I have no clue how others install custom shared libraries into such "common" folders. Every tutorial I found contradict some other tutorials.

I will try to take all best practices from imhex found on github as it provides ready to use installers for many unix like systems inclusing deb, appimage and the likes. The only risk or pitfall is, that it could easily happen that the game as it works today will simply not be possible to be installed via any conventional way, but by manual build and copy files to correct locations... e.g. one would provide a shell script and would run that to "install" stuff.

klei1984 commented 5 months ago

Status update. Ubuntu as well as Arch Linux installation is still problematic. As of today the DEB installer script still raises a dozen linter errors, while the PKGBUILD script fails installation step. The game does not support game binary and port assets to be separated, and the recently introduced portable mode installation is simply not possible to configure currently via DEB or anything else. The investigation will be continued.

klei1984 commented 3 months ago

External libiconv is replaced by SDL's own internal implementation, the dependency is removed. There are GitHub Actions scripts to build valid deb package, flatpak package, and arch linux pacman pkg.tar.zst package, plus a PKGBUILD script is also provided for AUR like build capability.

The next release plans to provide the above mentioned binary packages, updated build instructions, installation guidelines and probably a basic man page.

In the mean time the GitHub Actions build artifacts can be downloaded from the Actions page.

A debian/ubuntu/arch specific portable archive is targeted to be delivered with no need for installation and XDG standard compliance with the release.

These changes should resolve the linux installation issues.