User:Vadcx/Linux change glibc version
PLEASE NOTE: This is a DRAFT. If you follow these instructions, fix any issues or ask questions you have had along the way.
If you want to start Factorio 2.0 on an older Linux distro release (usually server OS distributions with long support cycles), you might encounter this:
user$ ./bin/x64/factorio
./bin/x64/factorio: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by ./bin/x64/factorio)
./bin/x64/factorio: /lib64/libpthread.so.0: version `GLIBC_2.30' not found (required by ./bin/x64/factorio)
This error message means that Factorio was compiled with a newer GLIBC version and it's not found on your system. Generally, your entire operating system depends on one and only one GLIBC version that it has installed.
Preparation
Find your GLIBC version
user$ ldd --version
ldd (GNU libc) 2.24
Manual GLIBC compilation
Don't be afraid, there are enough guides out there. Warning: you must NOT "install" the freshly compiled GLIBC system-wide. You'll simply need it in a folder for Factorio to use.
Linux From Scratch is an elaborate and reliable book: https://www.linuxfromscratch.org/lfs/view/stable/chapter08/glibc.html
Official releases: https://ftp.gnu.org/gnu/glibc/
Solutions
Non-solution: don't replace your system-wide glibc
Everything depends on it and if it breaks, every single piece of your OS will stop working.
#1: Upgrade to a newer distro release
Not easy, but it's probably about time to update?
#2: Start Factorio with custom GLIBC using ldd
In short, you'll override the path to load a different GLIBC version.
This is the equivalent of "LD_PRELOAD" for regular dynamic libraries, but GLIBC is so fundamental to everything that it needs to be done differently.
Note: this works only because GLIBC strives to be backwards compatible in its ABI (Application Binary Interface). For other libraries, you would need to watch out for compilation settings and ABI changes: https://abi-laboratory.pro/index.php?view=timeline&l=glibc
Approach A
Follow "Side by Side glibc 2.18" by millisa & GodricSeer: https://forums.factorio.com/viewtopic.php?t=54654#p324493
It boils down to starting Factorio with "ld-linux-x86-64.so" yourself to override which GLIBC it will load.
PATH=/opt/glibc-2.18/bin:$PATH LD_LIBRARY_PATH=/opt/glibc-2.18/lib:/usr/lib64 /opt/glibc-2.18/lib/ld-linux-x86-64.so.2 /home/factorio_user/factorio/bin/x64/factorio --create /home/factorio_user/factorio/saves/newmap16.zip
For our purposes the above should be equivalent to this (Factorio's binary is statically compiled):
user$ ~/f/s/b/x64 $ /opt/glib-2.40/bin/ld.so --library-path /opt/glib-2.40/lib ./factorio
Error: This is a headless executable, cannot start in graphical mode (use --start-server).
Downsides: Factorio will probably be unable to restart itself.
As a script:
#!/bin/sh
factorio_bin="$1"
echo "$1"
shift; # arguments to server start at $1 now
/opt/glib-2.40/bin/ld.so \
--library-path /opt/glib-2.40/lib \
"$factorio_bin" \
"$@"
todo: variable for glib path
Other links:
- https://github.com/Tantrisse/Factorio-mods-manager#on-the-error-version-glibc_218-not-found
- https://github.com/Bisa/factorio-init#notes-for-users-with-an-os-that-has-a-older-glibc-version
Approach B
Patch the Factorio binary to request a different interpreter path of ld:
patchelf --set-interpreter /opt/glib-2.40/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glib-2.40/lib factorio-patched
The below script patches it in-place and needs some refinement.
#!/usr/bin/env bash
SCRIPT_PATH=$(dirname "$0")
SCRIPT_PATH=$(readlink -f -- "$SCRIPT_PATH")
LD_LOADER=$(readelf -l "$SCRIPT_PATH/bin/x64/factorio" | grep -oP "\[Requesting program interpreter: (\K.*)(?=\])")
if [[ "$LD_LOADER" != "/opt/glib-2.40/lib/ld-linux-x86-64.so.2" ]]; then
echo "Patching Factorio..."
/usr/bin/patchelf \
--set-interpreter \
/opt/glib-2.40/lib/ld-linux-x86-64.so.2 \
--set-rpath \
/opt/glib-2.40/lib \
"$SCRIPT_PATH/bin/x64/factorio"
fi
"$SCRIPT_PATH/bin/x64/factorio" "$@"
todo: variable for glib path, LC_ALL=C just in case (although readelf doesn't translate strings)
#3: Run Factorio in a chroot with custom GLIBC
Technically, you can have a whole different "universe" on your current system side-by-side, where all the software is compiled against another GLIBC version, separate from your ordinary system runtime.
This would be a proper solution and work for any other library with major breaking changes I suppose. But it's a lot of effort for a game server. Ain't nothing like a temporary and hacky workaround like #2, right?
Possible issues
Error configuring paths
Error configuring paths: There is no package core in /usr/share/factorio.
Factorio tries to determine its game folder and fails. A quick "./factorio --help" reveals this argument:
--executable-path PATH Override autodetected __PATH__executable.
Usually not needed except on very weird systems.
Simply point it to the Factorio's binary folder: --executable-path /something/something/bin/x64/