fastfetch-cli / fastfetch

An actively maintained, feature-rich and performance oriented, neofetch like system information tool.
MIT License
9.98k stars 398 forks source link

[FEAT] glibc version compatibility & statically linked builds #808

Closed hykilpikonna closed 5 months ago

hykilpikonna commented 5 months ago

Wanted features:

Add some statically linked builds on github release.

Motivation:

The github release for linux amd64 is not runnable on older versions of ubuntu 20 LTS.

image

image

CarterLi commented 5 months ago

The github release for linux amd64 is not runnable on older versions of ubuntu 20 LTS.

It was documented in the README

Add some statically linked builds on github release

It won't work even for MUSL build. Otherwise it has been done years ago.

CarterLi commented 5 months ago

If you don't trust me, you may try it yourself.

hykilpikonna commented 5 months ago

It won't work even for MUSL build. Otherwise it has been done years ago.

Okay, that's fair. Would it be possible to change the build target to lower glibc versions? (e.g. 2.12)? Afaik the latest glibc should be compatible with any version after 2.0.

CarterLi commented 5 months ago

Fastfetch uses Github Action to build binaries, which supports only ubuntu 20.04 and newer.

The binaries released by fastfetch were built with 22.04. If you need old glibc version support, you may download the artifacts named fastfetch-linux-old-amd64

hykilpikonna commented 5 months ago

The binaries released by fastfetch were built with 22.04. If you need old glibc version support, you may download the artifacts named fastfetch-linux-old-amd64

Thanks! Do you want to maybe publish the linux-old build on GitHub releases as well? Or change the default to Ubuntu 20.04? It's a little bit strange to abandon support for 20.04 LTS since it's still being supported by Ubuntu and hasn't reached EOL yet.

CarterLi commented 5 months ago

Even 14.4 is still supported by Ubuntu, but they will only get security fixes, which is so called "stable". Fastfetch targets people who want to try new things. If one stucks at an ancient distro, he may not want to try fastfetch.

Azathothas commented 5 months ago

The github release for linux amd64 is not runnable on older versions of ubuntu 20 LTS.

It was documented in the README

Add some statically linked builds on github release

It won't work even for MUSL build. Otherwise it has been done years ago.

Actually, it is possible to build statically linked musl binaries by changing a few cmake flags. This is how I do it:

!# Verify

You can run the binary in a minimal alpne docker image and it works perfectly

The (ldd | file | du -sh) output are:

./fastfetch: not a dynamic executable | ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped | 1.5M ./flashfetch: not a dynamic executable | ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped | 1.3M

!# Features ❯ fastfetch --list-features Proprietary GPU driver API chafa dbus dconf drm egl gio imagemagick7 libddcutil libnm libpulse linux/videodev2 linux/wireless opencl osmesa sqlite3 threads vulkan wayland x11 xcb xcb-randr xfconf xrandr zlib



You can test the binaries yourself:
- https://bin.ajam.dev/x86_64_Linux/fastfetch
- https://bin.ajam.dev/x86_64_Linux/flashfetch
hykilpikonna commented 5 months ago

Actually, it is possible to build statically linked musl binaries by changing a few cmake flags. This is how I do it:

Oh great! This helps a lot in terms of building compatible binaries. Thanks!

CarterLi commented 5 months ago

The github release for linux amd64 is not runnable on older versions of ubuntu 20 LTS.

It was documented in the README

Add some statically linked builds on github release

It won't work even for MUSL build. Otherwise it has been done years ago.

Actually, it is possible to build statically linked musl binaries by changing a few cmake flags. This is how I do it:

---snip---
git clone --filter "blob:none" --quiet "https://github.com/fastfetch-cli/fastfetch" && cd "./fastfetch"
         mkdir -p "./STATIC_BUILD"
         cmake -DCMAKE_C_FLAGS="-O2 -flto=auto -static -w -pipe" \
         -DCMAKE_EXE_LINKER_FLAGS="-static -s -Wl,-S -Wl,--build-id=none" \
         -DCMAKE_BUILD_TYPE="Release" \
         -DCMAKE_INSTALL_PREFIX="/usr" \
         -DIS_MUSL="ON" \
         -DBUILD_SHARED_LIBS="Off" \
         -DBUILD_TESTS="Off" \
         -DSET_TWEAK="Off" \
         -GNinja \
         -B "./STATIC_BUILD"
         cmake --build "./STATIC_BUILD" --target package -j"$(($(nproc)+1))"
---snip---

!# Verify 
# You can run the binary in a minimal alpne docker image and it works perfectly
# The (ldd | file | du -sh) output are:
./fastfetch: not a dynamic executable | ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped | 1.5M
./flashfetch: not a dynamic executable | ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped | 1.3M

!# Features
❯ fastfetch --list-features
Proprietary GPU driver API
chafa
dbus
dconf
drm
egl
gio
imagemagick7
libddcutil
libnm
libpulse
linux/videodev2
linux/wireless
opencl
osmesa
sqlite3
threads
vulkan
wayland
x11
xcb
xcb-randr
xfconf
xrandr
zlib

You can test the binaries yourself:

This doesn't actually work. Fastfetch makes heavy uses of dlopen, but an statically linked binary can't use that.

image

Take Packages module as an example. RPM uses libsqlite to read rpmdb.sqlite. However dlopen in a statically linked binary always fails, so that fastfetch fails to detect number of rpm packages, and none of the features list above will work.

A program runs doesn't mean it works. I'm the project author, trust me.

Azathothas commented 5 months ago

The github release for linux amd64 is not runnable on older versions of ubuntu 20 LTS.

It was documented in the README

Add some statically linked builds on github release

It won't work even for MUSL build. Otherwise it has been done years ago.

Actually, it is possible to build statically linked musl binaries by changing a few cmake flags. This is how I do it:

---snip---
git clone --filter "blob:none" --quiet "https://github.com/fastfetch-cli/fastfetch" && cd "./fastfetch"
         mkdir -p "./STATIC_BUILD"
         cmake -DCMAKE_C_FLAGS="-O2 -flto=auto -static -w -pipe" \
         -DCMAKE_EXE_LINKER_FLAGS="-static -s -Wl,-S -Wl,--build-id=none" \
         -DCMAKE_BUILD_TYPE="Release" \
         -DCMAKE_INSTALL_PREFIX="/usr" \
         -DIS_MUSL="ON" \
         -DBUILD_SHARED_LIBS="Off" \
         -DBUILD_TESTS="Off" \
         -DSET_TWEAK="Off" \
         -GNinja \
         -B "./STATIC_BUILD"
         cmake --build "./STATIC_BUILD" --target package -j"$(($(nproc)+1))"
---snip---

!# Verify 
# You can run the binary in a minimal alpne docker image and it works perfectly
# The (ldd | file | du -sh) output are:
./fastfetch: not a dynamic executable | ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped | 1.5M
./flashfetch: not a dynamic executable | ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped | 1.3M

!# Features
❯ fastfetch --list-features
Proprietary GPU driver API
chafa
dbus
dconf
drm
egl
gio
imagemagick7
libddcutil
libnm
libpulse
linux/videodev2
linux/wireless
opencl
osmesa
sqlite3
threads
vulkan
wayland
x11
xcb
xcb-randr
xfconf
xrandr
zlib

You can test the binaries yourself:

This doesn't actually work. Fastfetch makes heavy uses of dlopen, but an statically linked binary can't use that.

image

Take Packages module as an example. RPM uses libsqlite to read rpmdb.sqlite. However dlopen in a statically linked binary always fails.

A program runs doesn't mean it works. I'm the author, trust me.

Ah I see. I use fastfetch similar to how I use neofetch. Nothing like you have showed in the screenshot. So some features that can't be built statically is okay for me. Also, it actually works very well on debian based distros (as rpm is not needed here)

❯ ./fastfetch-dynamic -s packages -l none
Packages: 1681 (dpkg), 48 (nix-default), 8 (snap)

❯ ./fastfetch -s packages -l none
Packages: 1681 (dpkg), 48 (nix-default), 8 (snap)

So it's less of a doesn't mean it works but more of a lacks features Though it might be possible to convert the dynamically linked full featured binary using https://github.com/JonathonReinhart/staticx

# Try the binary yourself: https://bin.ajam.dev/x86_64_Linux/fastfetch-staticx

❯ staticx --loglevel DEBUG "./fastfetch-dynamic" --strip "./fastfetch-staticx"
❯ ldd "./fastfetch-staticx" ; file "./fastfetch-staticx" ; du -sh "./fastfetch-staticx"
not a dynamic executable
./fastfetch-staticx: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
1.6M    ./fastfetch-staticx

❯ ./fastfetch-staticx --list-features
Directx Headers
Proprietary GPU driver API
dbus
dconf
drm
egl
gio
glx
imagemagick6
imagemagick7
libddcutil
libnm
libpulse
opencl
osmesa
rpm
sqlite3
threads
videodev2
vulkan
wayland
x11
xcb
xcb-randr
xfconf
xrandr
zlib
CarterLi commented 5 months ago

Try the binary yourself: https://bin.ajam.dev/x86_64_Linux/fastfetch-staticx

It crashes.

It's easy to check whether the binary work or not. You should try fastfetch -s sound --show-errors and it should not print Sound: Failed to load libpulse.so

Azathothas commented 5 months ago

Try the binary yourself: https://bin.ajam.dev/x86_64_Linux/fastfetch-staticx

It crashes.

It's easy to check whether the binary work or not. You should try fastfetch -s sound --show-errors and it should not print Sound: Failed to load libpulse.so

That's because I used the precompiled binary that are released here (https://github.com/fastfetch-cli/fastfetch/releases/download/2.10.2/fastfetch-linux-amd64.tar.gz) , which also crashes image

If you have libpulse.so on your system (I am using the default GH Runner Ubuntu Image which doesn't) and then you create it, that will be included in the staticx version.

CarterLi commented 5 months ago

image

This is what I meant crash

CarterLi commented 5 months ago

This is what I meant *test`

image

Azathothas commented 5 months ago

Hmm, interesting. I always test all my binaries on the absolute most minimal containers, and thus far these all work and function (except for the libpulse.so). staticx isn't true static anyways, so crash is expected. But if you can, please link/upload the fastfetch binary you have on your system here, so I can take a look. Regardless, there should be a static release which has few features removed, so people can use it anywhere. At the very least, this issue should provide reference to people who want to tinker with this in the future.

CarterLi commented 5 months ago

If you don't have libpulse installed, you may also try opengl, vulkan, media, song...

image

Azathothas commented 5 months ago

If you don't have libpulse installed, you may also try opengl, vulkan, media, song...

image

If we are talking in terms of regular distros and "real-systems" instead of containers, the very same container GH Actions uses to release the binaries of fastfetch, then sure. But the problem is that the official GH Actions doesn't have a display or opengl, vulkan, media, song so I can't build a staticx binary with those libs included. I had really appreciate it if you could provide the fastfetch binary from your system.

CarterLi commented 5 months ago

If you don't have libpulse installed, you may also try opengl, vulkan, media, song... image

If we are talking in terms of regular distros and "real-systems" instead of containers, the very same container GH Actions uses to release the binaries of fastfetch, then sure. But the problem is that the official GH Actions doesn't have a display or opengl, vulkan, media, song so I can't build a staticx binary with those libs included. I had really appreciate it if you could provide the fastfetch binary from your system.

I downloaded the binary from Github releases

CarterLi commented 5 months ago

But the problem is that the official GH Actions doesn't have a display or opengl, vulkan, media, song so I can't build a staticx binary with those libs included.

A container doesn't have a display or opengl, vulkan, media, song, doesn't mean it can't build a binary that uses so libs that connect a display or opengl, vulkan, media, song in compile time.

Azathothas commented 5 months ago

Ah yes, my bad. staticx finds and links from your own system, so ofc it won't build on actions. It finds and packs libs at runtime. if you really want to tinker:

!# Install : https://staticx.readthedocs.io/en/latest/installation.html
# Make sure you also have: ldd , readelf, objcopy, patchelf (https://github.com/NixOS/patchelf) & scons

!# After you have installed those, you can create a staticx binary using:
staticx --loglevel DEBUG "./fastfetch-dynamic" --strip "./fastfetch-staticx"

!# Try the staticx build now it should mostly work
CarterLi commented 5 months ago

staticx finds and links from your own system, so ofc it won't build on actions. It finds and packs libs at runtime.

So I have to build in my machine? Then what's the point of static link?

Talk is cheap. Unless you show me the binary, your words are meaningless.

Azathothas commented 5 months ago

staticx finds and links from your own system, so ofc it won't build on actions. It finds and packs libs at runtime.

So I have to build in my machine? Then what's the point of static link?

Talk is cheap. Unless you provide the binary, your words is meaningless.

Once you build the binary from a machine where staticx can find and pack as much features/runtime deps as possible, you can then release those binaries here on your repo. Those binaries will work anywhere.

CarterLi commented 5 months ago

Talk is cheap.