packages: Add a patched buildFHSUserEnvBubblewrap
This commit is contained in:
parent
682ce9c22a
commit
7a0d7b1f94
216
packages/build-support/build-fhs-userenv-bubblewrap/default.nix
Normal file
216
packages/build-support/build-fhs-userenv-bubblewrap/default.nix
Normal file
@ -0,0 +1,216 @@
|
||||
{ lib, callPackage, runCommandLocal, writeShellScriptBin, glibc, pkgsi686Linux, coreutils, bubblewrap }:
|
||||
|
||||
let buildFHSEnv = callPackage ./env.nix { }; in
|
||||
|
||||
args @ {
|
||||
name
|
||||
, runScript ? "bash"
|
||||
, extraInstallCommands ? ""
|
||||
, meta ? {}
|
||||
, passthru ? {}
|
||||
, unshareUser ? true
|
||||
, unshareIpc ? true
|
||||
, unsharePid ? true
|
||||
, unshareNet ? false
|
||||
, unshareUts ? true
|
||||
, unshareCgroup ? true
|
||||
, dieWithParent ? true
|
||||
, specifyHomeDirs ? false
|
||||
, mountInHome ? []
|
||||
, chdirTo ? "\"$(pwd)\""
|
||||
, additionalBlacklist ? []
|
||||
, additionalMounts ? []
|
||||
, extraEnv ? {}
|
||||
, ...
|
||||
}:
|
||||
|
||||
with builtins;
|
||||
let
|
||||
buildFHSEnv = callPackage ./env.nix { };
|
||||
|
||||
env = buildFHSEnv (removeAttrs args [
|
||||
"runScript" "extraInstallCommands" "meta" "passthru" "dieWithParent"
|
||||
"unshareUser" "unshareCgroup" "unshareUts" "unshareNet" "unsharePid" "unshareIpc"
|
||||
]);
|
||||
|
||||
etcBindFlags = let
|
||||
files = [
|
||||
# NixOS Compatibility
|
||||
"static"
|
||||
"nix" # mainly for nixUnstable users, but also for access to nix/netrc
|
||||
# Shells
|
||||
"bashrc"
|
||||
"zshenv"
|
||||
"zshrc"
|
||||
"zinputrc"
|
||||
"zprofile"
|
||||
# Users, Groups, NSS
|
||||
"passwd"
|
||||
"group"
|
||||
"shadow"
|
||||
"hosts"
|
||||
"resolv.conf"
|
||||
"nsswitch.conf"
|
||||
# User profiles
|
||||
"profiles"
|
||||
# Sudo & Su
|
||||
"login.defs"
|
||||
"sudoers"
|
||||
"sudoers.d"
|
||||
# Time
|
||||
"localtime"
|
||||
"zoneinfo"
|
||||
# Other Core Stuff
|
||||
"machine-id"
|
||||
"os-release"
|
||||
# PAM
|
||||
"pam.d"
|
||||
# Fonts
|
||||
"fonts"
|
||||
# ALSA
|
||||
"alsa"
|
||||
"asound.conf"
|
||||
# SSL
|
||||
"ssl/certs"
|
||||
"pki"
|
||||
];
|
||||
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 <<EOF
|
||||
/lib
|
||||
/lib/x86_64-linux-gnu
|
||||
/lib64
|
||||
/usr/lib
|
||||
/usr/lib/x86_64-linux-gnu
|
||||
/usr/lib64
|
||||
/lib/i386-linux-gnu
|
||||
/lib32
|
||||
/usr/lib/i386-linux-gnu
|
||||
/usr/lib32
|
||||
EOF
|
||||
ldconfig &> /dev/null
|
||||
'';
|
||||
init = run: writeShellScriptBin "${name}-init" ''
|
||||
source /etc/profile
|
||||
${createLdConfCache}
|
||||
exec ${run} "$@"
|
||||
'';
|
||||
|
||||
extraEnvString = lib.foldl (acc: val: acc + val + "\n") "" (lib.mapAttrsToList (name: value: "--setenv ${name} \"${value}\"") extraEnv);
|
||||
|
||||
bwrapCmd = { initArgs ? "" }: ''
|
||||
blacklist=(/nix /dev /proc /etc ${lib.optionalString specifyHomeDirs "/home"} ${builtins.toString additionalBlacklist})
|
||||
ro_mounts=()
|
||||
symlinks=()
|
||||
for i in ${env}/*; do
|
||||
path="/''${i##*/}"
|
||||
if [[ $path == '/etc' ]]; then
|
||||
:
|
||||
elif [[ -L $i ]]; then
|
||||
symlinks+=(--symlink "$(${coreutils}/bin/readlink "$i")" "$path")
|
||||
blacklist+=("$path")
|
||||
else
|
||||
ro_mounts+=(--ro-bind "$i" "$path")
|
||||
blacklist+=("$path")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -d ${env}/etc ]]; then
|
||||
for i in ${env}/etc/*; do
|
||||
path="/''${i##*/}"
|
||||
# NOTE: we're binding /etc/fonts and /etc/ssl/certs from the host so we
|
||||
# don't want to override it with a path from the FHS environment.
|
||||
if [[ $path == '/fonts' || $path == '/ssl' ]]; then
|
||||
continue
|
||||
fi
|
||||
ro_mounts+=(--ro-bind "$i" "/etc$path")
|
||||
done
|
||||
fi
|
||||
|
||||
declare -a auto_mounts
|
||||
# loop through all directories in the root
|
||||
for dir in /*; do
|
||||
# if it is a directory and it is not in the blacklist
|
||||
if [[ -d "$dir" ]] && [[ ! "''${blacklist[@]}" =~ "$dir" ]]; then
|
||||
# add it to the mount list
|
||||
auto_mounts+=(--bind "$dir" "$dir")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${lib.optionalString specifyHomeDirs "1"}" = "1" ]]; then
|
||||
for entry in ${builtins.toString mountInHome}; do
|
||||
auto_mounts+=(--bind "/home/$USER/$entry" "/home/$USER/$entry")
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ ! -z "${builtins.toString additionalMounts}" ]]; then
|
||||
for entry in ${builtins.toString additionalMounts}; do
|
||||
auto_mounts+=(--bind "$entry" "$entry")
|
||||
done
|
||||
fi
|
||||
|
||||
cmd=(
|
||||
${bubblewrap}/bin/bwrap
|
||||
--dev-bind /dev /dev
|
||||
--proc /proc
|
||||
--chdir ${chdirTo}
|
||||
${lib.optionalString unshareUser "--unshare-user"}
|
||||
${lib.optionalString unshareIpc "--unshare-ipc"}
|
||||
${lib.optionalString unsharePid "--unshare-pid"}
|
||||
${lib.optionalString unshareNet "--unshare-net"}
|
||||
${lib.optionalString unshareUts "--unshare-uts"}
|
||||
${lib.optionalString unshareCgroup "--unshare-cgroup"}
|
||||
${lib.optionalString dieWithParent "--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[@]}"
|
||||
${extraEnvString}
|
||||
${init runScript}/bin/${name}-init ${initArgs}
|
||||
)
|
||||
exec "''${cmd[@]}"
|
||||
'';
|
||||
|
||||
bin = writeShellScriptBin name (bwrapCmd { initArgs = ''"$@"''; });
|
||||
|
||||
in runCommandLocal name {
|
||||
inherit meta;
|
||||
|
||||
passthru = passthru // {
|
||||
env = runCommandLocal "${name}-shell-env" {
|
||||
shellHook = bwrapCmd {};
|
||||
} ''
|
||||
echo >&2 ""
|
||||
echo >&2 "*** User chroot 'env' attributes are intended for interactive nix-shell sessions, not for building! ***"
|
||||
echo >&2 ""
|
||||
exit 1
|
||||
'';
|
||||
};
|
||||
} ''
|
||||
mkdir -p $out/bin
|
||||
ln -s ${bin}/bin/${name} $out/bin/${name}
|
||||
${extraInstallCommands}
|
||||
''
|
185
packages/build-support/build-fhs-userenv-bubblewrap/env.nix
Normal file
185
packages/build-support/build-fhs-userenv-bubblewrap/env.nix
Normal file
@ -0,0 +1,185 @@
|
||||
{ stdenv, lib, buildEnv, writeText, writeShellScriptBin, pkgs, pkgsi686Linux }:
|
||||
|
||||
{ name, profile ? ""
|
||||
, targetPkgs ? pkgs: [], multiPkgs ? pkgs: []
|
||||
, extraBuildCommands ? "", extraBuildCommandsMulti ? ""
|
||||
, extraOutputsToInstall ? []
|
||||
, ...
|
||||
}:
|
||||
|
||||
# HOWTO:
|
||||
# All packages (most likely programs) returned from targetPkgs will only be
|
||||
# installed once--matching the host's architecture (64bit on x86_64 and 32bit on
|
||||
# x86).
|
||||
#
|
||||
# Packages (most likely libraries) returned from multiPkgs are installed
|
||||
# once on x86 systems and twice on x86_64 systems.
|
||||
# On x86 they are merged with packages from targetPkgs.
|
||||
# On x86_64 they are added to targetPkgs and in addition their 32bit
|
||||
# versions are also installed. The final directory structure looks as
|
||||
# follows:
|
||||
# /lib32 will include 32bit libraries from multiPkgs
|
||||
# /lib64 will include 64bit libraries from multiPkgs and targetPkgs
|
||||
# /lib will link to /lib32
|
||||
|
||||
let
|
||||
is64Bit = stdenv.hostPlatform.parsed.cpu.bits == 64;
|
||||
isMultiBuild = multiPkgs != null && is64Bit;
|
||||
isTargetBuild = !isMultiBuild;
|
||||
|
||||
# list of packages (usually programs) which are only be installed for the
|
||||
# host's architecture
|
||||
targetPaths = targetPkgs pkgs ++ (if multiPkgs == null then [] else multiPkgs pkgs);
|
||||
|
||||
# list of packages which are installed for both x86 and x86_64 on x86_64
|
||||
# systems
|
||||
multiPaths = multiPkgs pkgsi686Linux;
|
||||
|
||||
# base packages of the chroot
|
||||
# these match the host's architecture, glibc_multi is used for multilib
|
||||
# builds. glibcLocales must be before glibc or glibc_multi as otherwiese
|
||||
# the wrong LOCALE_ARCHIVE will be used where only C.UTF-8 is available.
|
||||
basePkgs = with pkgs;
|
||||
[ glibcLocales
|
||||
(if isMultiBuild then glibc_multi else glibc)
|
||||
(toString gcc.cc.lib) bashInteractive coreutils less shadow su
|
||||
gawk diffutils findutils gnused gnugrep
|
||||
gnutar gzip bzip2 xz
|
||||
];
|
||||
baseMultiPkgs = with pkgsi686Linux;
|
||||
[ (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'
|
||||
export LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
|
||||
export PATH="/run/wrappers/bin:/usr/bin:/usr/sbin:$PATH"
|
||||
export TZDIR='/etc/zoneinfo'
|
||||
|
||||
# Force compilers and other tools to look in default search paths
|
||||
unset NIX_ENFORCE_PURITY
|
||||
export NIX_CC_WRAPPER_TARGET_HOST_${stdenv.cc.suffixSalt}=1
|
||||
export NIX_CFLAGS_COMPILE='-idirafter /usr/include'
|
||||
export NIX_CFLAGS_LINK='-L/usr/lib -L/usr/lib32'
|
||||
export NIX_LDFLAGS='-L/usr/lib -L/usr/lib32'
|
||||
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
|
||||
export ACLOCAL_PATH=/usr/share/aclocal
|
||||
|
||||
${profile}
|
||||
'';
|
||||
|
||||
# Compose /etc for the chroot environment
|
||||
etcPkg = stdenv.mkDerivation {
|
||||
name = "${name}-chrootenv-etc";
|
||||
buildCommand = ''
|
||||
mkdir -p $out/etc
|
||||
cd $out/etc
|
||||
|
||||
# environment variables
|
||||
ln -s ${etcProfile} profile
|
||||
|
||||
# symlink /etc/mtab -> /proc/mounts (compat for old userspace progs)
|
||||
ln -s /proc/mounts mtab
|
||||
'';
|
||||
};
|
||||
|
||||
# Composes a /usr-like directory structure
|
||||
staticUsrProfileTarget = buildEnv {
|
||||
name = "${name}-usr-target";
|
||||
# ldconfig wrapper must come first so it overrides the original ldconfig
|
||||
paths = [ etcPkg ldconfig ] ++ basePkgs ++ targetPaths;
|
||||
extraOutputsToInstall = [ "out" "lib" "bin" ] ++ extraOutputsToInstall;
|
||||
ignoreCollisions = true;
|
||||
};
|
||||
|
||||
staticUsrProfileMulti = buildEnv {
|
||||
name = "${name}-usr-multi";
|
||||
paths = baseMultiPkgs ++ multiPaths;
|
||||
extraOutputsToInstall = [ "out" "lib" ] ++ extraOutputsToInstall;
|
||||
ignoreCollisions = true;
|
||||
};
|
||||
|
||||
# setup library paths only for the targeted architecture
|
||||
setupLibDirsTarget = ''
|
||||
# link content of targetPaths
|
||||
cp -rsHf ${staticUsrProfileTarget}/lib lib
|
||||
ln -s lib lib${if is64Bit then "64" else "32"}
|
||||
'';
|
||||
|
||||
# setup /lib, /lib32 and /lib64
|
||||
setupLibDirsMulti = ''
|
||||
mkdir -m0755 lib32
|
||||
mkdir -m0755 lib64
|
||||
ln -s lib64 lib
|
||||
|
||||
# copy glibc stuff
|
||||
cp -rsHf ${staticUsrProfileTarget}/lib/32/* lib32/ && chmod u+w -R lib32/
|
||||
|
||||
# copy content of multiPaths (32bit libs)
|
||||
[ -d ${staticUsrProfileMulti}/lib ] && cp -rsHf ${staticUsrProfileMulti}/lib/* lib32/ && chmod u+w -R lib32/
|
||||
|
||||
# copy content of targetPaths (64bit libs)
|
||||
cp -rsHf ${staticUsrProfileTarget}/lib/* lib64/ && chmod u+w -R lib64/
|
||||
|
||||
# symlink 32-bit ld-linux.so
|
||||
ln -Ls ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/
|
||||
'';
|
||||
|
||||
setupLibDirs = if isTargetBuild then setupLibDirsTarget
|
||||
else setupLibDirsMulti;
|
||||
|
||||
# the target profile is the actual profile that will be used for the chroot
|
||||
setupTargetProfile = ''
|
||||
mkdir -m0755 usr
|
||||
cd usr
|
||||
${setupLibDirs}
|
||||
${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
|
||||
done
|
||||
cd ..
|
||||
|
||||
for i in var etc; do
|
||||
if [ -d "${staticUsrProfileTarget}/$i" ]; then
|
||||
cp -rsHf "${staticUsrProfileTarget}/$i" "$i"
|
||||
fi
|
||||
done
|
||||
for i in usr/{bin,sbin,lib,lib32,lib64}; do
|
||||
if [ -d "$i" ]; then
|
||||
ln -s "$i"
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
in stdenv.mkDerivation {
|
||||
name = "${name}-fhs";
|
||||
buildCommand = ''
|
||||
mkdir -p $out
|
||||
cd $out
|
||||
${setupTargetProfile}
|
||||
cd $out
|
||||
${extraBuildCommands}
|
||||
cd $out
|
||||
${if isMultiBuild then extraBuildCommandsMulti else ""}
|
||||
'';
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
47
packages/games/steam/build-wrapped.sh
Normal file
47
packages/games/steam/build-wrapped.sh
Normal file
@ -0,0 +1,47 @@
|
||||
source $stdenv/setup
|
||||
|
||||
outp=$out/lib/steam-runtime
|
||||
|
||||
buildDir() {
|
||||
paths="$1"
|
||||
pkgs="$2"
|
||||
|
||||
for pkg in $pkgs; do
|
||||
echo "adding package $pkg"
|
||||
for path in $paths; do
|
||||
if [ -d $pkg/$path ]; then
|
||||
cd $pkg/$path
|
||||
for file in *; do
|
||||
found=""
|
||||
for i in $paths; do
|
||||
if [ -e "$outp/$i/$file" ]; then
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ -z "$found" ]; then
|
||||
mkdir -p $outp/$path
|
||||
ln -s "$pkg/$path/$file" $outp/$path
|
||||
sovers=$(echo $file | perl -ne 'print if s/.*?\.so\.(.*)/\1/')
|
||||
if [ ! -z "$sovers" ]; then
|
||||
fname=''${file%.''${sovers}}
|
||||
for ver in ''${sovers//./ }; do
|
||||
found=""
|
||||
for i in $paths; do
|
||||
if [ -e "$outp/$i/$fname" ]; then
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ -n "$found" ] || ln -s "$pkg/$path/$file" "$outp/$path/$fname"
|
||||
fname="$fname.$ver"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
eval "$installPhase"
|
26
packages/games/steam/default.nix
Normal file
26
packages/games/steam/default.nix
Normal file
@ -0,0 +1,26 @@
|
||||
{ pkgs, newScope, buildFHSUserEnv }:
|
||||
|
||||
let
|
||||
callPackage = newScope self;
|
||||
|
||||
self = rec {
|
||||
steamArch = if pkgs.stdenv.hostPlatform.system == "x86_64-linux" then "amd64"
|
||||
else if pkgs.stdenv.hostPlatform.system == "i686-linux" then "i386"
|
||||
else throw "Unsupported platform: ${pkgs.stdenv.hostPlatform.system}";
|
||||
|
||||
steam-runtime = callPackage ./runtime.nix { };
|
||||
steam-runtime-wrapped = callPackage ./runtime-wrapped.nix { };
|
||||
steam = callPackage ./steam.nix { };
|
||||
steam-fonts = callPackage ./fonts.nix { };
|
||||
steam-fhsenv = callPackage ./fhsenv.nix {
|
||||
glxinfo-i686 = pkgs.pkgsi686Linux.glxinfo;
|
||||
steam-runtime-wrapped-i686 =
|
||||
if steamArch == "amd64"
|
||||
then pkgs.pkgsi686Linux.steamPackages.steam-runtime-wrapped
|
||||
else null;
|
||||
inherit buildFHSUserEnv;
|
||||
};
|
||||
steamcmd = callPackage ./steamcmd.nix { };
|
||||
};
|
||||
|
||||
in self
|
360
packages/games/steam/fhsenv.nix
Normal file
360
packages/games/steam/fhsenv.nix
Normal file
@ -0,0 +1,360 @@
|
||||
{ config, lib, writeScript, buildFHSUserEnv, steam, glxinfo-i686
|
||||
, steam-runtime-wrapped, steam-runtime-wrapped-i686 ? null
|
||||
, extraPkgs ? pkgs: [ ] # extra packages to add to targetPkgs
|
||||
, extraLibraries ? pkgs: [ ] # extra packages to add to multiPkgs
|
||||
, extraProfile ? "" # string to append to profile
|
||||
, nativeOnly ? false
|
||||
, runtimeOnly ? false
|
||||
, runtimeShell
|
||||
, stdenv
|
||||
|
||||
# DEPRECATED
|
||||
, withJava ? config.steam.java or false
|
||||
, withPrimus ? config.steam.primus or false
|
||||
}:
|
||||
|
||||
let
|
||||
commonTargetPkgs = pkgs: with pkgs;
|
||||
[
|
||||
steamPackages.steam-fonts
|
||||
# Needed for operating system detection until
|
||||
# https://github.com/ValveSoftware/steam-for-linux/issues/5909 is resolved
|
||||
lsb-release
|
||||
# Errors in output without those
|
||||
pciutils
|
||||
python2
|
||||
# Games' dependencies
|
||||
xorg.xrandr
|
||||
which
|
||||
# Needed by gdialog, including in the steam-runtime
|
||||
perl
|
||||
# Open URLs
|
||||
xdg-utils
|
||||
iana-etc
|
||||
# Steam Play / Proton
|
||||
python3
|
||||
# Steam VR
|
||||
procps
|
||||
usbutils
|
||||
|
||||
# electron based launchers need newer versions of these libraries than what runtime provides
|
||||
mesa
|
||||
sqlite
|
||||
|
||||
# TODO: Remove
|
||||
gamemode
|
||||
] ++ lib.optional withJava jdk8 # TODO: upgrade https://github.com/NixOS/nixpkgs/pull/89731
|
||||
++ lib.optional withPrimus primus
|
||||
++ extraPkgs pkgs;
|
||||
|
||||
ldPath = lib.optionals stdenv.is64bit [ "/lib64" ]
|
||||
++ [ "/lib32" ]
|
||||
++ map (x: "/steamrt/${steam-runtime-wrapped.arch}/" + x) steam-runtime-wrapped.libs
|
||||
++ lib.optionals (steam-runtime-wrapped-i686 != null) (map (x: "/steamrt/${steam-runtime-wrapped-i686.arch}/" + x) steam-runtime-wrapped-i686.libs);
|
||||
|
||||
# Zachtronics and a few other studios expect STEAM_LD_LIBRARY_PATH to be present
|
||||
exportLDPath = ''
|
||||
export LD_LIBRARY_PATH=${lib.concatStringsSep ":" ldPath}''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
|
||||
export STEAM_LD_LIBRARY_PATH="$STEAM_LD_LIBRARY_PATH''${STEAM_LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
|
||||
'';
|
||||
|
||||
# bootstrap.tar.xz has 444 permissions, which means that simple deletes fail
|
||||
# and steam will not be able to start
|
||||
fixBootstrap = ''
|
||||
if [ -r $HOME/.local/share/Steam/bootstrap.tar.xz ]; then
|
||||
chmod +w $HOME/.local/share/Steam/bootstrap.tar.xz
|
||||
fi
|
||||
'';
|
||||
|
||||
setupSh = writeScript "setup.sh" ''
|
||||
#!${runtimeShell}
|
||||
'';
|
||||
|
||||
runSh = writeScript "run.sh" ''
|
||||
#!${runtimeShell}
|
||||
runtime_paths="${lib.concatStringsSep ":" ldPath}"
|
||||
if [ "$1" == "--print-steam-runtime-library-paths" ]; then
|
||||
echo "$runtime_paths''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
|
||||
exit 0
|
||||
fi
|
||||
export LD_LIBRARY_PATH="$runtime_paths''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
|
||||
export STEAM_LD_LIBRARY_PATH="$STEAM_LD_LIBRARY_PATH''${STEAM_LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
|
||||
exec "$@"
|
||||
'';
|
||||
|
||||
in buildFHSUserEnv rec {
|
||||
name = "steam";
|
||||
|
||||
targetPkgs = pkgs: with pkgs; [
|
||||
steamPackages.steam
|
||||
# License agreement
|
||||
gnome.zenity
|
||||
] ++ commonTargetPkgs pkgs;
|
||||
|
||||
multiPkgs = pkgs: with pkgs; [
|
||||
# These are required by steam with proper errors
|
||||
xorg.libXcomposite
|
||||
xorg.libXtst
|
||||
xorg.libXrandr
|
||||
xorg.libXext
|
||||
xorg.libX11
|
||||
xorg.libXfixes
|
||||
libGL
|
||||
libva
|
||||
pipewire.lib
|
||||
|
||||
# Not formally in runtime but needed by some games
|
||||
at-spi2-atk
|
||||
at-spi2-core # CrossCode
|
||||
gst_all_1.gstreamer
|
||||
gst_all_1.gst-plugins-ugly
|
||||
gst_all_1.gst-plugins-base
|
||||
json-glib # paradox launcher (Stellaris)
|
||||
libdrm
|
||||
libxkbcommon # paradox launcher
|
||||
mono
|
||||
xorg.xkeyboardconfig
|
||||
xorg.libpciaccess
|
||||
udev # shadow of the tomb raider
|
||||
|
||||
## screeps dependencies
|
||||
gtk3
|
||||
dbus
|
||||
zlib
|
||||
glib
|
||||
atk
|
||||
cairo
|
||||
freetype
|
||||
gdk-pixbuf
|
||||
pango
|
||||
fontconfig
|
||||
|
||||
# friends options won't display "Launch Game" without it
|
||||
lsof
|
||||
|
||||
# called by steam's setup.sh
|
||||
file
|
||||
|
||||
# Prison Architect
|
||||
libGLU
|
||||
libuuid
|
||||
libbsd
|
||||
#alsa-lib
|
||||
|
||||
# Loop Hero
|
||||
libidn2
|
||||
libpsl
|
||||
nghttp2.lib
|
||||
openssl_1_1
|
||||
rtmpdump
|
||||
|
||||
# needed by getcap for vr startup
|
||||
libcap
|
||||
|
||||
# dependencies for mesa drivers, needed inside pressure-vessel
|
||||
mesa.drivers
|
||||
mesa.llvmPackages.llvm.lib
|
||||
vulkan-loader
|
||||
expat
|
||||
wayland
|
||||
xorg.libxcb
|
||||
xorg.libXdamage
|
||||
xorg.libxshmfence
|
||||
xorg.libXxf86vm
|
||||
libelf
|
||||
] ++ (if (!nativeOnly) then [
|
||||
(steamPackages.steam-runtime-wrapped.override {
|
||||
inherit runtimeOnly;
|
||||
})
|
||||
] else [
|
||||
# Required
|
||||
glib
|
||||
gtk2
|
||||
bzip2
|
||||
zlib
|
||||
gdk-pixbuf
|
||||
|
||||
# Without these it silently fails
|
||||
xorg.libXinerama
|
||||
xorg.libXdamage
|
||||
xorg.libXcursor
|
||||
xorg.libXrender
|
||||
xorg.libXScrnSaver
|
||||
xorg.libXxf86vm
|
||||
xorg.libXi
|
||||
xorg.libSM
|
||||
xorg.libICE
|
||||
gnome2.GConf
|
||||
freetype
|
||||
(curl.override { gnutlsSupport = true; sslSupport = false; })
|
||||
nspr
|
||||
nss
|
||||
fontconfig
|
||||
cairo
|
||||
pango
|
||||
expat
|
||||
dbus
|
||||
cups
|
||||
libcap
|
||||
SDL2
|
||||
libusb1
|
||||
dbus-glib
|
||||
ffmpeg
|
||||
atk
|
||||
# Only libraries are needed from those two
|
||||
libudev0-shim
|
||||
networkmanager098
|
||||
|
||||
# Verified games requirements
|
||||
xorg.libXt
|
||||
xorg.libXmu
|
||||
xorg.libxcb
|
||||
libogg
|
||||
libvorbis
|
||||
SDL
|
||||
SDL2_image
|
||||
glew110
|
||||
libidn
|
||||
tbb
|
||||
wayland
|
||||
|
||||
# Other things from runtime
|
||||
flac
|
||||
freeglut
|
||||
libjpeg
|
||||
libpng12
|
||||
libsamplerate
|
||||
libmikmod
|
||||
libtheora
|
||||
libtiff
|
||||
pixman
|
||||
speex
|
||||
SDL_image
|
||||
SDL_ttf
|
||||
SDL_mixer
|
||||
SDL2_ttf
|
||||
SDL2_mixer
|
||||
libappindicator-gtk2
|
||||
libcaca
|
||||
libcanberra
|
||||
libgcrypt
|
||||
libvpx
|
||||
librsvg
|
||||
xorg.libXft
|
||||
libvdpau
|
||||
] ++ steamPackages.steam-runtime-wrapped.overridePkgs) ++ extraLibraries pkgs;
|
||||
|
||||
extraBuildCommands = ''
|
||||
if [ -f $out/usr/share/vulkan/icd.d/nvidia_icd.json ]; then
|
||||
cp $out/usr/share/vulkan/icd.d/nvidia_icd{,32}.json
|
||||
nvidia32Lib=$(realpath $out/lib32/libGLX_nvidia.so.0 | cut -d'/' -f-4)
|
||||
escapedNvidia32Lib="''${nvidia32Lib//\//\\\/}"
|
||||
sed -i "s/\/nix\/store\/.*\/lib\/libGLX_nvidia\.so\.0/$escapedNvidia32Lib\/lib\/libGLX_nvidia\.so\.0/g" $out/usr/share/vulkan/icd.d/nvidia_icd32.json
|
||||
fi
|
||||
'' + (if (!nativeOnly) then ''
|
||||
mkdir -p steamrt
|
||||
ln -s ../lib/steam-runtime steamrt/${steam-runtime-wrapped.arch}
|
||||
${lib.optionalString (steam-runtime-wrapped-i686 != null) ''
|
||||
ln -s ../lib32/steam-runtime steamrt/${steam-runtime-wrapped-i686.arch}
|
||||
''}
|
||||
ln -s ${runSh} steamrt/run.sh
|
||||
ln -s ${setupSh} steamrt/setup.sh
|
||||
'' else ''
|
||||
ln -s /usr/lib/libbz2.so usr/lib/libbz2.so.1.0
|
||||
${lib.optionalString (steam-runtime-wrapped-i686 != null) ''
|
||||
ln -s /usr/lib32/libbz2.so usr/lib32/libbz2.so.1.0
|
||||
''}
|
||||
'');
|
||||
|
||||
extraInstallCommands = ''
|
||||
mkdir -p $out/share/applications
|
||||
ln -s ${steam}/share/icons $out/share
|
||||
ln -s ${steam}/share/pixmaps $out/share
|
||||
ln -s ${steam}/share/applications/steam.desktop $out/share/applications/steam.desktop
|
||||
'';
|
||||
|
||||
profile = ''
|
||||
# Workaround for issue #44254 (Steam cannot connect to friends network)
|
||||
# https://github.com/NixOS/nixpkgs/issues/44254
|
||||
if [ -z ''${TZ+x} ]; then
|
||||
new_TZ="$(readlink -f /etc/localtime | grep -P -o '(?<=/zoneinfo/).*$')"
|
||||
if [ $? -eq 0 ]; then
|
||||
export TZ="$new_TZ"
|
||||
fi
|
||||
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" ''
|
||||
#!${runtimeShell}
|
||||
if [ -f /host/etc/NIXOS ]; then # Check only useful on NixOS
|
||||
${glxinfo-i686}/bin/glxinfo >/dev/null 2>&1
|
||||
# If there was an error running glxinfo, we know something is wrong with the configuration
|
||||
if [ $? -ne 0 ]; then
|
||||
cat <<EOF > /dev/stderr
|
||||
**
|
||||
WARNING: Steam is not set up. Add the following options to /etc/nixos/configuration.nix
|
||||
and then run \`sudo nixos-rebuild switch\`:
|
||||
{
|
||||
hardware.opengl.driSupport32Bit = true;
|
||||
hardware.pulseaudio.support32Bit = true;
|
||||
}
|
||||
**
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
${lib.optionalString (!nativeOnly) exportLDPath}
|
||||
${fixBootstrap}
|
||||
exec steam "$@"
|
||||
'';
|
||||
|
||||
meta = steam.meta // {
|
||||
broken = nativeOnly;
|
||||
};
|
||||
|
||||
# allows for some gui applications to share IPC
|
||||
# this fixes certain issues where they don't render correctly
|
||||
unshareIpc = false;
|
||||
|
||||
# Some applications such as Natron need access to MIT-SHM or other
|
||||
# shared memory mechanisms. Unsharing the pid namespace
|
||||
# breaks the ability for application to reference shared memory.
|
||||
unsharePid = false;
|
||||
|
||||
specifyHomeDirs = true;
|
||||
mountInHome = [
|
||||
".steam"
|
||||
".local/share/Steam"
|
||||
];
|
||||
chdirTo = "/home/$USER";
|
||||
additionalBlacklist = [ "/mnt" ];
|
||||
additionalMounts = [ "/mnt/Storage/Games/SteamLibrary" ];
|
||||
extraEnv = {
|
||||
DRI_PRIME = "1";
|
||||
};
|
||||
|
||||
passthru.run = buildFHSUserEnv {
|
||||
name = "steam-run";
|
||||
|
||||
targetPkgs = commonTargetPkgs;
|
||||
inherit multiPkgs extraBuildCommands;
|
||||
|
||||
inherit unshareIpc unsharePid;
|
||||
|
||||
runScript = writeScript "steam-run" ''
|
||||
#!${runtimeShell}
|
||||
run="$1"
|
||||
if [ "$run" = "" ]; then
|
||||
echo "Usage: steam-run command-to-run args..." >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
${lib.optionalString (!nativeOnly) exportLDPath}
|
||||
${fixBootstrap}
|
||||
exec -- "$run" "$@"
|
||||
'';
|
||||
};
|
||||
}
|
20
packages/games/steam/fonts.nix
Normal file
20
packages/games/steam/fonts.nix
Normal file
@ -0,0 +1,20 @@
|
||||
{ stdenv, fetchurl, unzip }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
pname = "steam-fonts";
|
||||
version = "1";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://support.steampowered.com/downloads/1974-YFKL-4947/SteamFonts.zip";
|
||||
sha256 = "1cgygmwich5f1jhhbmbkkpnzasjl8gy36xln76n6r2gjh6awqfx0";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ unzip ];
|
||||
|
||||
sourceRoot = ".";
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/fonts/truetype
|
||||
cp -r *.TTF *.ttf $out/share/fonts/truetype
|
||||
'';
|
||||
}
|
45
packages/games/steam/runtime-wrapped.nix
Normal file
45
packages/games/steam/runtime-wrapped.nix
Normal file
@ -0,0 +1,45 @@
|
||||
{ stdenv, steamArch, lib, perl, pkgs, steam-runtime
|
||||
, runtimeOnly ? false
|
||||
}:
|
||||
|
||||
let
|
||||
overridePkgs = lib.optionals (!runtimeOnly) (with pkgs; [
|
||||
libgpgerror
|
||||
libpulseaudio
|
||||
#alsa-lib
|
||||
openalSoft
|
||||
libva1
|
||||
libvdpau
|
||||
vulkan-loader
|
||||
gcc.cc.lib
|
||||
nss
|
||||
nspr
|
||||
xorg.libxcb
|
||||
]);
|
||||
|
||||
allPkgs = overridePkgs ++ [ steam-runtime ];
|
||||
|
||||
gnuArch = if steamArch == "amd64" then "x86_64-linux-gnu"
|
||||
else if steamArch == "i386" then "i386-linux-gnu"
|
||||
else abort "Unsupported architecture";
|
||||
|
||||
libs = [ "lib/${gnuArch}" "lib" "usr/lib/${gnuArch}" "usr/lib" ];
|
||||
bins = [ "bin" "usr/bin" ];
|
||||
|
||||
in stdenv.mkDerivation {
|
||||
name = "steam-runtime-wrapped";
|
||||
|
||||
nativeBuildInputs = [ perl ];
|
||||
|
||||
builder = ./build-wrapped.sh;
|
||||
|
||||
passthru = {
|
||||
inherit gnuArch libs bins overridePkgs;
|
||||
arch = steamArch;
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
buildDir "${toString libs}" "${toString (map lib.getLib allPkgs)}"
|
||||
buildDir "${toString bins}" "${toString (map lib.getBin allPkgs)}"
|
||||
'';
|
||||
}
|
37
packages/games/steam/runtime.nix
Normal file
37
packages/games/steam/runtime.nix
Normal file
@ -0,0 +1,37 @@
|
||||
{ lib, stdenv, fetchurl
|
||||
|
||||
# for update script
|
||||
, writeShellScript, curl, nix-update
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
|
||||
pname = "steam-runtime";
|
||||
# from https://repo.steampowered.com/steamrt-images-scout/snapshots/
|
||||
version = "0.20210630.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://repo.steampowered.com/steamrt-images-scout/snapshots/${version}/steam-runtime.tar.xz";
|
||||
sha256 = "sha256-vwSgk3hEaI/RO9uvehAx3+ZBynpqjwGDzuyeyGCnu18=";
|
||||
name = "scout-runtime-${version}.tar.gz";
|
||||
};
|
||||
|
||||
buildCommand = ''
|
||||
mkdir -p $out
|
||||
tar -C $out --strip=1 -x -f $src
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
updateScript = writeShellScript "update.sh" ''
|
||||
version=$(${curl}/bin/curl https://repo.steampowered.com/steamrt-images-scout/snapshots/latest-steam-client-general-availability/VERSION.txt)
|
||||
${nix-update}/bin/nix-update --version "$version" steamPackages.steam-runtime
|
||||
'';
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "The official runtime used by Steam";
|
||||
homepage = "https://github.com/ValveSoftware/steam-runtime";
|
||||
license = licenses.unfreeRedistributable; # Includes NVIDIA CG toolkit
|
||||
maintainers = with maintainers; [ hrdinka abbradar ];
|
||||
};
|
||||
}
|
47
packages/games/steam/steam.nix
Normal file
47
packages/games/steam/steam.nix
Normal file
@ -0,0 +1,47 @@
|
||||
{ lib, stdenv, fetchurl, runtimeShell, traceDeps ? false, bash }:
|
||||
|
||||
let
|
||||
traceLog = "/tmp/steam-trace-dependencies.log";
|
||||
version = "1.0.0.70";
|
||||
|
||||
in stdenv.mkDerivation {
|
||||
pname = "steam-original";
|
||||
inherit version;
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://repo.steampowered.com/steam/archive/stable/steam_${version}.tar.gz";
|
||||
sha256 = "sha256-n/iKV3jHsA77GPMk1M0MKC1fQ42tEgG8Ppgi4/9qLf8=";
|
||||
};
|
||||
|
||||
makeFlags = [ "DESTDIR=$(out)" "PREFIX=" ];
|
||||
|
||||
postInstall = ''
|
||||
rm $out/bin/steamdeps
|
||||
${lib.optionalString traceDeps ''
|
||||
cat > $out/bin/steamdeps <<EOF
|
||||
#!${runtimeShell}
|
||||
echo \$1 >> ${traceLog}
|
||||
cat \$1 >> ${traceLog}
|
||||
echo >> ${traceLog}
|
||||
EOF
|
||||
chmod +x $out/bin/steamdeps
|
||||
''}
|
||||
|
||||
# install udev rules
|
||||
mkdir -p $out/etc/udev/rules.d/
|
||||
cp ./subprojects/steam-devices/*.rules $out/etc/udev/rules.d/
|
||||
substituteInPlace $out/etc/udev/rules.d/60-steam-input.rules \
|
||||
--replace "/bin/sh" "${bash}/bin/bash"
|
||||
|
||||
# this just installs a link, "steam.desktop -> /lib/steam/steam.desktop"
|
||||
rm $out/share/applications/steam.desktop
|
||||
sed -e 's,/usr/bin/steam,steam,g' steam.desktop > $out/share/applications/steam.desktop
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "A digital distribution platform";
|
||||
homepage = "http://store.steampowered.com/";
|
||||
license = licenses.unfreeRedistributable;
|
||||
maintainers = with maintainers; [ jagajaga jonringer ];
|
||||
};
|
||||
}
|
46
packages/games/steam/steamcmd.nix
Normal file
46
packages/games/steam/steamcmd.nix
Normal file
@ -0,0 +1,46 @@
|
||||
{ lib, stdenv, fetchurl, steam-run, bash, coreutils
|
||||
, steamRoot ? "~/.local/share/Steam"
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
pname = "steamcmd";
|
||||
version = "20180104"; # According to steamcmd_linux.tar.gz mtime
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz";
|
||||
sha256 = "0z0y0zqvhydmfc9y9vg5am0vz7m3gbj4l2dwlrfz936hpx301gyf";
|
||||
};
|
||||
|
||||
# The source tarball does not have a single top-level directory.
|
||||
preUnpack = ''
|
||||
mkdir $name
|
||||
cd $name
|
||||
sourceRoot=.
|
||||
'';
|
||||
|
||||
buildInputs = [ bash steam-run ];
|
||||
|
||||
dontBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/steamcmd/linux32
|
||||
install -Dm755 steamcmd.sh $out/share/steamcmd/steamcmd.sh
|
||||
install -Dm755 linux32/* $out/share/steamcmd/linux32
|
||||
|
||||
mkdir -p $out/bin
|
||||
substitute ${./steamcmd.sh} $out/bin/steamcmd \
|
||||
--subst-var out \
|
||||
--subst-var-by coreutils ${coreutils} \
|
||||
--subst-var-by steamRoot "${steamRoot}" \
|
||||
--subst-var-by steamRun ${steam-run}
|
||||
chmod 0755 $out/bin/steamcmd
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Steam command-line tools";
|
||||
homepage = "https://developer.valvesoftware.com/wiki/SteamCMD";
|
||||
platforms = platforms.linux;
|
||||
license = licenses.unfreeRedistributable;
|
||||
maintainers = with maintainers; [ tadfisher ];
|
||||
};
|
||||
}
|
27
packages/games/steam/steamcmd.sh
Normal file
27
packages/games/steam/steamcmd.sh
Normal file
@ -0,0 +1,27 @@
|
||||
#!@bash@/bin/bash -e
|
||||
|
||||
# Always run steamcmd in the user's Steam root.
|
||||
STEAMROOT=@steamRoot@
|
||||
|
||||
# Add coreutils to PATH for mkdir, ln and cp used below
|
||||
PATH=$PATH${PATH:+:}@coreutils@/bin
|
||||
|
||||
# Create a facsimile Steam root if it doesn't exist.
|
||||
if [ ! -e "$STEAMROOT" ]; then
|
||||
mkdir -p "$STEAMROOT"/{appcache,config,logs,Steamapps/common}
|
||||
mkdir -p ~/.steam
|
||||
ln -sf "$STEAMROOT" ~/.steam/root
|
||||
ln -sf "$STEAMROOT" ~/.steam/steam
|
||||
fi
|
||||
|
||||
# Copy the system steamcmd install to the Steam root. If we don't do
|
||||
# this, steamcmd assumes the path to `steamcmd` is the Steam root.
|
||||
# Note that symlinks don't work here.
|
||||
if [ ! -e "$STEAMROOT/steamcmd.sh" ]; then
|
||||
mkdir -p "$STEAMROOT/linux32"
|
||||
# steamcmd.sh will replace these on first use
|
||||
cp @out@/share/steamcmd/steamcmd.sh "$STEAMROOT/."
|
||||
cp @out@/share/steamcmd/linux32/* "$STEAMROOT/linux32/."
|
||||
fi
|
||||
|
||||
@steamRun@/bin/steam-run "$STEAMROOT/steamcmd.sh" "$@"
|
Loading…
Reference in New Issue
Block a user