hedge-dev / hedge-dev/UnleashedRecomp

Dynamic linking hell on Linux

Open
#1,713 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

linux
Dominant language
C++
Stars
5.1k
Forks
421
PR merge metrics
No merged PRs in 30d

Description

Validation
  • I have checked the Issues page to see if my problem has already been reported
  • I have confirmed that this bug does not occur in the original game running on original Xbox 360 hardware
If you have DLC installed, please specify which ones you have.
  • Apotos & Shamar Adventure Pack
  • Chun-nan Adventure Pack
  • Empire City & Adabat Adventure Pack
  • Holoska Adventure Pack
  • Mazuri Adventure Pack
  • Spagonia Adventure Pack
If you have mods enabled, please specify which ones you have.

No response

If you have codes enabled, please specify which ones you have.

No response

Describe the Bug

If you compile Sonic Unleashed on Linux and check dynamic libraries with ldd utility you would be horrified with the amount of libraries executable is linked against. This makes Sonic Unleashed Linux executables absolutely not future-proof. Many of those libraries aren't necessary for the game and some of them aren't advertising stable ABI meaning one day a single update may break those binaries, and it's absolutely guaranteed that these executables won't work for example in 5 years because of linking to gtk-3, libpng16.
No, seriously, why would you need to link against X11 https://github.com/hedge-dev/UnleashedRecomp/blob/3c1badf1832e806c80374d2ae89fb137dd9de87f/UnleashedRecomp/CMakeLists.txt#L415 and Wayland when you're using SDL? Why would you need to link against systemd for the Christ sake?

Actually, the answer is pretty much simple: this is happening due to this project is heavily relying on static linking: instead of dynamically linking against SDL and having SDL to resolve its dependencies (which is done at package manager level) you statically link SDL and now have ALL its dependencies as dependency for your executable. As for SDL it's a VERY ABI stable project (there's no ABI breaks inside major versions and backwards compatibility with older versions provided by sdl12-compat and sdl2-compat), and it's already provided by most distributions as a dependency for other components (for example, on Arch Linux plasma-desktop has sdl2 as dependency meaning all Plasma users will have SDL anyway), so there's no reason to statically link to SDL unless you want to make user experience worse (which was already mentioned in #1666).

Factorio devs faced similar issue: https://factorio.com/blog/post/fff-408 section Dynamically linked libraries

IMO static linking should be used only as a last resort and only for the libraries that won't bring million of dependencies with them.

Steps to Reproduce
  1. Compile UnleashedRecomp
  2. Check linked libraries with ldd utility.
Expected Behavior

Dynamic libraries of properly compiled executable should look like this

$ ldd bin/FinalReleasex64Clang/factorio
        linux-vdso.so.1 (0x00007fff96ff2000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fd2df8a9000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fd2df7c8000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fd2df5e6000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd2df8d6000)

Here's another example with OpenJK

ldd /opt/openjk/JediAcademy/openjk.x86_64 
        linux-vdso.so.1 (0x00007fdf317ab000)
        libz.so.1 => /usr/lib/libz.so.1 (0x00007fdf31718000)
        libSDL2-2.0.so.0 => /usr/lib/libSDL2-2.0.so.0 (0x00007fdf316b5000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fdf2fe00000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007fdf315d4000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fdf301cb000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007fdf2fa00000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fdf317ad000)
Footage

See additional info.

Version

latest git

CPU

9800x3d

GPU

6700xt

GPU Driver

whatever

Memory

64 GiB

Operating System

Arch Linux

Additional Context
ldd SonicUnleashed.x86_64 
        linux-vdso.so.1 (0x00007f28e4964000)
        libSM.so.6 => /usr/lib/libSM.so.6 (0x00007f28e48ff000)
        libICE.so.6 => /usr/lib/libICE.so.6 (0x00007f28e48e1000)
        libX11.so.6 => /usr/lib/libX11.so.6 (0x00007f28df895000)
        libXext.so.6 => /usr/lib/libXext.so.6 (0x00007f28e48c6000)
        libgtk-3.so.0 => /usr/lib/libgtk-3.so.0 (0x00007f28df000000)
        libgdk-3.so.0 => /usr/lib/libgdk-3.so.0 (0x00007f28deef5000)
        libz.so.1 => /usr/lib/libz.so.1 (0x00007f28e488a000)
        libpangocairo-1.0.so.0 => /usr/lib/libpangocairo-1.0.so.0 (0x00007f28e487a000)
        libpango-1.0.so.0 => /usr/lib/libpango-1.0.so.0 (0x00007f28df81a000)
        libharfbuzz.so.0 => /usr/lib/libharfbuzz.so.0 (0x00007f28ded82000)
        libatk-1.0.so.0 => /usr/lib/libatk-1.0.so.0 (0x00007f28e4854000)
        libcairo-gobject.so.2 => /usr/lib/libcairo-gobject.so.2 (0x00007f28e484b000)
        libcairo.so.2 => /usr/lib/libcairo.so.2 (0x00007f28debe9000)
        libgdk_pixbuf-2.0.so.0 => /usr/lib/libgdk_pixbuf-2.0.so.0 (0x00007f28df7c6000)
        libgio-2.0.so.0 => /usr/lib/libgio-2.0.so.0 (0x00007f28dea17000)
        libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0x00007f28de9b8000)
        libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0x00007f28de860000)
        libm.so.6 => /usr/lib/libm.so.6 (0x00007f28de77f000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f28de400000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f28de74a000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f28de000000)
        libuuid.so.1 => /usr/lib/libuuid.so.1 (0x00007f28e483d000)
        libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00007f28de71d000)
        libgmodule-2.0.so.0 => /usr/lib/libgmodule-2.0.so.0 (0x00007f28e4836000)
        libpangoft2-1.0.so.0 => /usr/lib/libpangoft2-1.0.so.0 (0x00007f28df7a6000)
        libfontconfig.so.1 => /usr/lib/libfontconfig.so.1 (0x00007f28de3a1000)
        libfribidi.so.0 => /usr/lib/libfribidi.so.0 (0x00007f28de6fa000)
        libepoxy.so.0 => /usr/lib/libepoxy.so.0 (0x00007f28de280000)
        libXi.so.6 => /usr/lib/libXi.so.6 (0x00007f28e481d000)
        libatk-bridge-2.0.so.0 => /usr/lib/libatk-bridge-2.0.so.0 (0x00007f28de245000)
        libcloudproviders.so.0 => /usr/lib/libcloudproviders.so.0 (0x00007f28ddfe8000)
        libtinysparql-3.0.so.0 => /usr/lib/libtinysparql-3.0.so.0 (0x00007f28ddf16000)
        libXfixes.so.3 => /usr/lib/libXfixes.so.3 (0x00007f28de6f2000)
        libxkbcommon.so.0 => /usr/lib/libxkbcommon.so.0 (0x00007f28ddea9000)
        libwayland-client.so.0 => /usr/lib/libwayland-client.so.0 (0x00007f28dde99000)
        libwayland-cursor.so.0 => /usr/lib/libwayland-cursor.so.0 (0x00007f28de6e8000)
        libwayland-egl.so.1 => /usr/lib/libwayland-egl.so.1 (0x00007f28df7a1000)
        libXcursor.so.1 => /usr/lib/libXcursor.so.1 (0x00007f28dde8b000)
        libXdamage.so.1 => /usr/lib/libXdamage.so.1 (0x00007f28de240000)
        libXcomposite.so.1 => /usr/lib/libXcomposite.so.1 (0x00007f28de23b000)
        libXrandr.so.2 => /usr/lib/libXrandr.so.2 (0x00007f28dde7c000)
        libXinerama.so.1 => /usr/lib/libXinerama.so.1 (0x00007f28dde77000)
        libthai.so.0 => /usr/lib/libthai.so.0 (0x00007f28dde6b000)
        libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x00007f28ddd4b000)
        libgraphite2.so.3 => /usr/lib/libgraphite2.so.3 (0x00007f28ddd28000)
        libpng16.so.16 => /usr/lib/libpng16.so.16 (0x00007f28ddcd1000)
        libXrender.so.1 => /usr/lib/libXrender.so.1 (0x00007f28ddcc3000)
        libxcb-render.so.0 => /usr/lib/libxcb-render.so.0 (0x00007f28ddcb3000)
        libxcb-shm.so.0 => /usr/lib/libxcb-shm.so.0 (0x00007f28ddcae000)
        libpixman-1.so.0 => /usr/lib/libpixman-1.so.0 (0x00007f28ddb1b000)
        libglycin-2.so.0 => /usr/lib/libglycin-2.so.0 (0x00007f28dd600000)
        libmount.so.1 => /usr/lib/libmount.so.1 (0x00007f28ddac5000)
        libffi.so.8 => /usr/lib/libffi.so.8 (0x00007f28ddab8000)
        libpcre2-8.so.0 => /usr/lib/libpcre2-8.so.0 (0x00007f28dd535000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f28e4966000)
        libXau.so.6 => /usr/lib/libXau.so.6 (0x00007f28ddab2000)
        libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00007f28ddaaa000)
        libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007f28dda79000)
        libatspi.so.0 => /usr/lib/libatspi.so.0 (0x00007f28dd4fc000)
        libdbus-1.so.3 => /usr/lib/libdbus-1.so.3 (0x00007f28dd4a1000)
        libjson-glib-1.0.so.0 => /usr/lib/libjson-glib-1.0.so.0 (0x00007f28dd474000)
        libxml2.so.16 => /usr/lib/libxml2.so.16 (0x00007f28dd33f000)
        libsqlite3.so.0 => /usr/lib/libsqlite3.so.0 (0x00007f28dd1c2000)
        libdatrie.so.1 => /usr/lib/libdatrie.so.1 (0x00007f28dda70000)
        libbz2.so.1.0 => /usr/lib/libbz2.so.1.0 (0x00007f28dd1ad000)
        libbrotlidec.so.1 => /usr/lib/libbrotlidec.so.1 (0x00007f28dd19e000)
        liblcms2.so.2 => /usr/lib/liblcms2.so.2 (0x00007f28dd136000)
        libseccomp.so.2 => /usr/lib/libseccomp.so.2 (0x00007f28dd109000)
        libblkid.so.1 => /usr/lib/libblkid.so.1 (0x00007f28dd0cf000)
        libsystemd.so.0 => /usr/lib/libsystemd.so.0 (0x00007f28dcfa8000)
        libicuuc.so.78 => /usr/lib/libicuuc.so.78 (0x00007f28dcc00000)
        libbrotlicommon.so.1 => /usr/lib/libbrotlicommon.so.1 (0x00007f28dcf85000)
        libicudata.so.78 => /usr/lib/libicudata.so.78 (0x00007f28dac00000)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with UnleashedRecomp/CMakeLists.txt around line 415 and reproduce the Linux build, then inspect the resulting SonicUnleashed.x86_64 with ldd. Trace which dependencies are introduced by the current linking configuration and compare the result with the examples in the issue. Done means the executable builds and its dynamic dependency list no longer includes the unnecessary libraries described here.

Written by the indexing model from the issue text.

Assessment

Tech stack
cmake, cpp, linux
Domain
build-system, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.