Skip to content

Commit

Permalink
Merge pull request #290 from canonical/nvidia32
Browse files Browse the repository at this point in the history
Add script to check for 32-bit NVIDIA libraries
  • Loading branch information
kenvandine authored Aug 17, 2023
2 parents 70c105b + 7260836 commit 37f9275
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 10 deletions.
37 changes: 27 additions & 10 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ parts:
source: ./src
override-build: |
mkdir -p $CRAFT_PART_INSTALL/bin
cp steam-snap.sh $CRAFT_PART_INSTALL/bin/
cp desktop-launch $CRAFT_PART_INSTALL/bin/
cp steamreport $CRAFT_PART_INSTALL/bin/
cp vulkaninfo $CRAFT_PART_INSTALL/bin/
cp vkcube $CRAFT_PART_INSTALL/bin/
cp glxinfo $CRAFT_PART_INSTALL/bin/
cp glxgears $CRAFT_PART_INSTALL/bin/
cp * $CRAFT_PART_INSTALL/bin/
stage-packages:
- python3-gi
- gir1.2-gtk-3.0
stage:
- -usr/bin/fc-*
- -usr/share/doc/fontconfig/fontconfig-user.*

alsa-mixin:
plugin: dump
Expand Down Expand Up @@ -343,8 +343,8 @@ parts:
- -usr/lib/*/libLLVM*
build-snaps: [core22]
override-prime: |
craftctl default
set -eux
craftctl default
cp -a /snap/core22/current/usr/lib/i386-linux-gnu/* usr/lib/i386-linux-gnu/
yaru-skin:
Expand All @@ -360,9 +360,25 @@ parts:
- usr/share/fonts/truetype/ubuntu
- usr/share/Steam/skins

cleanup:
conditioning:
after: [steam]
plugin: nil
build-packages:
- shared-mime-info
- gtk-update-icon-cache
override-prime: |
set -eux
craftctl default
update-mime-database usr/share/mime
for dir in usr/share/icons/*; do
if [ -f "$dir/index.theme" ]; then
gtk-update-icon-cache --force "$dir"
fi
done
cleanup:
after: [steam, conditioning]
plugin: nil
build-snaps:
- gaming-graphics-core22/kisak-fresh/candidate
override-prime: |
Expand All @@ -372,7 +388,6 @@ parts:
cd /snap/gaming-graphics-core22/current/usr/share
find . -type f,l -exec rm -f $CRAFT_PRIME/usr/share/{} \;
apps:
steam:
command-chain: [snap/command-chain/alsa-launch, bin/desktop-launch]
Expand All @@ -386,6 +401,8 @@ apps:
ALWAYS_USE_PULSEAUDIO: 1
DISABLE_WAYLAND: 1
PKG_CONFIG_PATH: $SNAP/usr/lib/i386-linux-gnu/pkgconfig:$SNAP/usr/lib/x86_64-linux-gnu/pkgconfig:$SNAP/usr/lib/pkgconfig
PYTHONPATH: $SNAP/usr/lib/python3/dist-packages
GI_TYPELIB_PATH: $SNAP/usr/lib/x86_64-linux-gnu/girepository-1.0
plugs:
- shmem
- desktop
Expand Down
1 change: 1 addition & 0 deletions src/desktop-launch
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,5 @@ if [ -n "$SNAP_DESKTOP_DEBUG" ]; then
echo "Now running: exec $*"
fi

$SNAP/bin/nvidia32 &
exec "$@"
169 changes: 169 additions & 0 deletions src/nvidia32
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/usr/bin/python3

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
import os
import argparse

TITLE = "NVIDIA 32-bit Not Found"
TEXT = """<b>32-bit NVIDIA driver files were not found on your host system.</b>
It is recommended that you install them for the best experience.
See <a href="https://github.com/canonical/steam-snap/wiki/FAQ#32-bit-driver">https://github.com/canonical/steam-snap/wiki/FAQ#32-bit-driver</a> for more information."""
COMMAND = """sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libnvidia-gl-{}:i386"""

DO_NOT_SHOW_PATH = os.path.expandvars("$SNAP_USER_COMMON/.nvidia32")

def do_not_show_file(do_not_show: bool):
"""Ok button press.
`do_not_show`: whether the Do not show again checkbox is checked or not
"""
if do_not_show:
open(DO_NOT_SHOW_PATH, "a").close()
elif os.path.exists(DO_NOT_SHOW_PATH):
os.remove(DO_NOT_SHOW_PATH)


def nvidia_version():
"""Try to find NVIDIA driver version from modinfo.
Returns a tuple of the full NVIDIA version triplet and NVIDIA major version.
"""
modinfo = os.popen(
"modinfo /usr/lib/modules/$(uname -r)/updates/dkms/nvidia.ko 2> /dev/null"
" | grep -m 1 '^version:'"
" | sed 's/version:\s*//'"
).read().splitlines()
modinfo = modinfo or os.popen(
"modinfo /usr/lib/modules/$(uname -r)/kernel/nvidia*/nvidia.ko 2> /dev/null"
" | grep -m 1 '^version:'"
" | sed 's/version:\s*//'"
).read().splitlines()

if not modinfo:
return ()
nvidia_version = modinfo[0].strip()
nvidia_version_major = nvidia_version.split(".")[0]
return (nvidia_version, nvidia_version_major)


def nvidia_missing():
"""Returns whether NVIDIA 32 is missing or not.
"""
version = nvidia_version()
if not version:
return False

print(f"Found NVIDIA version: {version[0]}")
needs_32 = os.path.exists(f"/var/lib/snapd/hostfs/usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.{version[0]}")\
and not os.path.exists(f"/var/lib/snapd/hostfs/usr/lib/i386-linux-gnu/libnvidia-glcore.so.{version[0]}")
print(f"Need NVIDIA 32-bit: {needs_32}")
return needs_32


class NvidiaWindow(Gtk.Window):
def __init__(self):
super().__init__()
self.set_resizable(False)
self.set_border_width(10)
self.set_position(Gtk.WindowPosition.CENTER)
self.set_keep_above(True)

header = Gtk.HeaderBar(title=TITLE)
self.set_titlebar(header)

self.grid = Gtk.Grid(
row_spacing=10,
column_spacing=10
)
self.add(self.grid)

# main text
self.label = Gtk.Label()
self.label.set_markup(TEXT)
self.grid.attach(self.label, 0, 0, 2, 1)

# run prompt
self.run_label = Gtk.Label(
margin_top=20,
halign=Gtk.Align.START
)
self.run_label.set_markup("To install, run:")
self.grid.attach_next_to(self.run_label, self.label, Gtk.PositionType.BOTTOM, 1, 1)

# copy button
self.copy_btn = Gtk.Button.new_from_icon_name("edit-copy-symbolic", Gtk.IconSize.MENU)
self.copy_btn.set_margin_top(20)
self.copy_btn.set_tooltip_text("Copy")
self.copy_btn.connect("clicked", lambda x: self.button_copy())
self.copy_btn.set_halign(Gtk.Align.END)
self.grid.attach_next_to(self.copy_btn, self.run_label, Gtk.PositionType.RIGHT, 1, 1)

# command text
self.nvidia_version = nvidia_version()
self.textview = Gtk.TextView(
editable=False,
monospace=True,
top_margin=5,
bottom_margin=5,
right_margin=10,
left_margin=10
)
self.textview.get_buffer().set_text(COMMAND.format(self.nvidia_version[1]))
self.grid.attach_next_to(self.textview, self.run_label, Gtk.PositionType.BOTTOM, 2, 1)

# Do not show again button
self.checkbox = Gtk.CheckButton(
label="Do not show again",
halign=Gtk.Align.END,
tooltip_markup="This window can always be shown again by running "
"<tt>$SNAP/bin/nvidia32 --reset</tt> in the Steam Snap shell."
)
self.grid.attach_next_to(self.checkbox, self.textview, Gtk.PositionType.BOTTOM, 1, 1)

# Ok button
self.btn = Gtk.Button(label="Ok")
self.btn.connect("clicked", lambda x: self.button_ok(self.checkbox.get_active()))
self.grid.attach_next_to(self.btn, self.checkbox, Gtk.PositionType.RIGHT, 1, 1)


def button_ok(self, toggled: bool):
do_not_show_file(toggled)
self.close()


def button_copy(self):
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clipboard.set_text(COMMAND.format(self.nvidia_version[1]), -1)


def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--reset",
help="Show the dialog again if you selected 'Do not show again'",
action="store_true"
)
parser.add_argument(
"--show",
help="Show the dialog regardless of conditions met",
action="store_true"
)
args = parser.parse_args()

if args.reset:
do_not_show_file(False)

if args.show or (nvidia_missing() and not os.path.exists(DO_NOT_SHOW_PATH)):
win = NvidiaWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()


if __name__ == "__main__":
main()

0 comments on commit 37f9275

Please sign in to comment.