Skip to content

Dynamic linking hell on Linux #1713

@RevengeRip

Description

@RevengeRip

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

target_link_libraries(UnleashedRecomp PRIVATE ${X11_LIBRARIES})
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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions