diff --git a/nixos/modules/programs/steam.nix b/nixos/modules/programs/steam.nix index 3c919c47a0c..6e9b7729ad6 100644 --- a/nixos/modules/programs/steam.nix +++ b/nixos/modules/programs/steam.nix @@ -4,6 +4,13 @@ with lib; let cfg = config.programs.steam; + + steam = pkgs.steam.override { + extraLibraries = pkgs: with config.hardware.opengl; + if pkgs.hostPlatform.is64bit + then [ package ] ++ extraPackages + else [ package32 ] ++ extraPackages32; + }; in { options.programs.steam.enable = mkEnableOption "steam"; @@ -18,7 +25,7 @@ in { hardware.steam-hardware.enable = true; - environment.systemPackages = [ pkgs.steam ]; + environment.systemPackages = [ steam steam.run ]; }; meta.maintainers = with maintainers; [ mkg20001 ]; diff --git a/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix b/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix index 572f12cdf83..3985eca4243 100644 --- a/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix +++ b/pkgs/build-support/build-fhs-userenv-bubblewrap/default.nix @@ -1,4 +1,6 @@ -{ lib, callPackage, runCommandLocal, writeShellScriptBin, coreutils, bubblewrap }: +{ lib, callPackage, runCommandLocal, writeShellScriptBin, glibc, pkgsi686Linux, coreutils, bubblewrap }: + +let buildFHSEnv = callPackage ./env.nix { }; in args @ { name @@ -60,21 +62,45 @@ let in concatStringsSep "\n " (map (file: "--ro-bind-try /etc/${file} /etc/${file}") files); + # Create this on the fly instead of linking from /nix + # The container might have to modify it and re-run ldconfig if there are + # issues running some binary with LD_LIBRARY_PATH + createLdConfCache = '' + cat > /etc/ld.so.conf < /dev/null + ''; init = run: writeShellScriptBin "${name}-init" '' source /etc/profile + ${createLdConfCache} exec ${run} "$@" ''; bwrapCmd = { initArgs ? "" }: '' blacklist=(/nix /dev /proc /etc) ro_mounts=() + symlinks=() for i in ${env}/*; do path="/''${i##*/}" if [[ $path == '/etc' ]]; then - continue + : + elif [[ -L $i ]]; then + symlinks+=(--symlink "$(readlink "$i")" "$path") + blacklist+=("$path") + else + ro_mounts+=(--ro-bind "$i" "$path") + blacklist+=("$path") fi - ro_mounts+=(--ro-bind "$i" "$path") - blacklist+=("$path") done if [[ -d ${env}/etc ]]; then @@ -112,8 +138,26 @@ let ${lib.optionalString unshareCgroup "--unshare-cgroup"} --die-with-parent --ro-bind /nix /nix + # Our glibc will look for the cache in its own path in `/nix/store`. + # As such, we need a cache to exist there, because pressure-vessel + # depends on the existence of an ld cache. However, adding one + # globally proved to be a bad idea (see #100655), the solution we + # settled on being mounting one via bwrap. + # Also, the cache needs to go to both 32 and 64 bit glibcs, for games + # of both architectures to work. + --tmpfs ${glibc}/etc \ + --symlink /etc/ld.so.conf ${glibc}/etc/ld.so.conf \ + --symlink /etc/ld.so.cache ${glibc}/etc/ld.so.cache \ + --ro-bind ${glibc}/etc/rpc ${glibc}/etc/rpc \ + --remount-ro ${glibc}/etc \ + --tmpfs ${pkgsi686Linux.glibc}/etc \ + --symlink /etc/ld.so.conf ${pkgsi686Linux.glibc}/etc/ld.so.conf \ + --symlink /etc/ld.so.cache ${pkgsi686Linux.glibc}/etc/ld.so.cache \ + --ro-bind ${pkgsi686Linux.glibc}/etc/rpc ${pkgsi686Linux.glibc}/etc/rpc \ + --remount-ro ${pkgsi686Linux.glibc}/etc \ ${etcBindFlags} "''${ro_mounts[@]}" + "''${symlinks[@]}" "''${auto_mounts[@]}" ${init runScript}/bin/${name}-init ${initArgs} ) diff --git a/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix b/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix index 8b2d46c4ae9..b9c719a4c78 100644 --- a/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix +++ b/pkgs/build-support/build-fhs-userenv-bubblewrap/env.nix @@ -1,4 +1,4 @@ -{ stdenv, buildEnv, writeText, pkgs, pkgsi686Linux }: +{ stdenv, lib, buildEnv, writeText, writeShellScriptBin, pkgs, pkgsi686Linux }: { name, profile ? "" , targetPkgs ? pkgs: [], multiPkgs ? pkgs: [] @@ -49,6 +49,9 @@ let [ (toString gcc.cc.lib) ]; + ldconfig = writeShellScriptBin "ldconfig" '' + exec ${pkgs.glibc.bin}/bin/ldconfig -f /etc/ld.so.conf -C /etc/ld.so.cache "$@" + ''; etcProfile = writeText "profile" '' export PS1='${name}-chrootenv:\u@\h:\w\$ ' export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive' @@ -86,7 +89,8 @@ let # Composes a /usr-like directory structure staticUsrProfileTarget = buildEnv { name = "${name}-usr-target"; - paths = [ etcPkg ] ++ basePkgs ++ targetPaths; + # ldconfig wrapper must come first so it overrides the original ldconfig + paths = [ etcPkg ldconfig ] ++ basePkgs ++ targetPaths; extraOutputsToInstall = [ "out" "lib" "bin" ] ++ extraOutputsToInstall; ignoreCollisions = true; }; @@ -132,7 +136,20 @@ let mkdir -m0755 usr cd usr ${setupLibDirs} - for i in bin sbin share include; do + ${lib.optionalString isMultiBuild '' + if [ -d "${staticUsrProfileMulti}/share" ]; then + cp -rLf ${staticUsrProfileMulti}/share share + fi + ''} + if [ -d "${staticUsrProfileTarget}/share" ]; then + if [ -d share ]; then + chmod -R 755 share + cp -rLTf ${staticUsrProfileTarget}/share share + else + cp -rLf ${staticUsrProfileTarget}/share share + fi + fi + for i in bin sbin include; do if [ -d "${staticUsrProfileTarget}/$i" ]; then cp -rsHf "${staticUsrProfileTarget}/$i" "$i" fi diff --git a/pkgs/games/steam/fhsenv.nix b/pkgs/games/steam/fhsenv.nix index 924714d802a..42faaf287d7 100644 --- a/pkgs/games/steam/fhsenv.nix +++ b/pkgs/games/steam/fhsenv.nix @@ -134,6 +134,20 @@ in buildFHSUserEnv rec { libuuid libbsd alsaLib + + # needed by getcap for vr startup + libcap + + # dependencies for mesa drivers, needed inside pressure-vessel + mesa.drivers + expat + wayland + xlibs.libxcb + xlibs.libXdamage + xlibs.libxshmfence + xlibs.libXxf86vm + llvm_11.lib + libelf ] ++ (if (!nativeOnly) then [ (steamPackages.steam-runtime-wrapped.override { inherit runtimeOnly; @@ -251,6 +265,8 @@ in buildFHSUserEnv rec { fi export STEAM_RUNTIME=${if nativeOnly then "0" else "/steamrt"} + + export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/intel_icd.x86_64.json:/usr/share/vulkan/icd.d/intel_icd.i686.json:/usr/share/vulkan/icd.d/lvp_icd.x86_64.json:/usr/share/vulkan/icd.d/lvp_icd.i686.json:/usr/share/vulkan/icd.d/nvidia_icd.json:/usr/share/vulkan/icd.d/nvidia_icd32.json:/usr/share/vulkan/icd.d/radeon_icd.x86_64.json:/usr/share/vulkan/icd.d/radeon_icd.i686.json '' + extraProfile; runScript = writeScript "steam-wrapper.sh" ''