Automate installation of DXVK, D9VK + Wine/Wine Staging & update GPU drivers + PlayonLinux wineprefixes (Debian/Ubuntu/Mint/Arch Linux/Manjaro)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

430 lines
12 KiB

5 years ago
5 years ago
2 years ago
2 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. #!/bin/env bash
  2. # DXVK/Wine-Staging scripts dispatcher for various Linux distributions
  3. # Copyright (C) 2019 Pekka Helenius
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. ##############################################################################
  18. source options.conf
  19. ###########################################################
  20. # Check if we're using bash or sh to run the script. If bash, OK.
  21. # If another one, ask user to run the script with bash.
  22. BASH_CHECK=$(ps | grep `echo $$` | awk '{ print $4 }')
  23. if [ $BASH_CHECK != "bash" ]; then
  24. echo "
  25. Please run this script using bash (/usr/bin/bash).
  26. "
  27. exit 1
  28. fi
  29. ###########################################################
  30. # Just a title & author for this script, used in initialization and help page
  31. SCRIPT_TITLE="\e[1mWine/Wine Staging, DXVK, DXVK NVAPI, VKD3D Proton package bundle builder & auto-installer\e[0m"
  32. SCRIPT_AUTHOR="Pekka Helenius (~Fincer), 2019-2022"
  33. ###########################################################
  34. # Allow interruption of the script at any time (Ctrl + C)
  35. trap "exit" INT
  36. ###########################################################
  37. COMMANDS=(
  38. curl
  39. date
  40. df
  41. find
  42. git
  43. grep
  44. groups
  45. nproc
  46. patch
  47. readlink
  48. sudo
  49. tar
  50. uname
  51. wc
  52. wget
  53. )
  54. SUDO_GROUPS=(
  55. sudo
  56. wheel
  57. )
  58. function checkCommands() {
  59. local COMMANDS_NOTFOUND
  60. local a
  61. if [[ $(which --help 2>/dev/null) ]] && [[ $(echo --help 2>/dev/null) ]]; then
  62. a=0
  63. for command in ${@}; do
  64. if [[ ! $(which $command 2>/dev/null) ]]; then
  65. COMMANDS_NOTFOUND[$a]=${command}
  66. let a++
  67. fi
  68. done
  69. if [[ -n $COMMANDS_NOTFOUND ]]; then
  70. echo -e "\nError! The following commands could not be found: ${COMMANDS_NOTFOUND[*]}\nAborting\n"
  71. exit 1
  72. fi
  73. else
  74. exit 1
  75. fi
  76. }
  77. checkCommands "${COMMANDS[*]}"
  78. ###########################################################
  79. # http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal
  80. function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; }
  81. ###########################################################
  82. if [[ $(uname -a | grep -c x86_64) -eq 0 ]]; then
  83. echo "This script supports 64-bit architectures only."
  84. exit 1
  85. fi
  86. if [[ $(groups | grep -cE $(echo ${SUDO_GROUPS[*]} | sed 's/ /|/g')) -eq 0 ]]; then
  87. echo "You must belong to a sudo group (checked groups: ${SUDO_GROUPS[*]})."
  88. exit 1
  89. fi
  90. unset sudogrp
  91. if [[ $UID -eq 0 ]]; then
  92. echo "Run as a regular user."
  93. exit 1
  94. fi
  95. ###########################################################
  96. # User-passed arguments for the script
  97. # We check the values of this array
  98. # and pass them to the subscripts if supported
  99. i=0
  100. for arg in ${@}; do
  101. case ${arg} in
  102. --no-staging)
  103. # Do not build Wine staging version, just Wine
  104. NO_STAGING=
  105. ;;
  106. --no-install)
  107. # Just build, do not install DXVK or Wine-Staging
  108. # Note that some version of Wine is required for DXVK compilation, though!
  109. NO_INSTALL=
  110. ;;
  111. --no-wine)
  112. # Skip Wine build & installation process all together
  113. NO_WINE=
  114. ;;
  115. --no-dxvk)
  116. # Skip DXVK build & installation process all together
  117. NO_DXVK=
  118. ;;
  119. --no-vkd3d)
  120. # Skip VKD3D Proton build & installation process all together
  121. NO_VKD3D=
  122. ;;
  123. --no-nvapi)
  124. # Skip DXVK NVAPI build & installation process all together
  125. NO_NVAPI=
  126. ;;
  127. --no-pol)
  128. # Skip PlayOnLinux Wine prefixes update process
  129. NO_POL=
  130. ;;
  131. *)
  132. echo -e "\n\
  133. \
  134. ${SCRIPT_TITLE} by ${SCRIPT_AUTHOR}\n\n\
  135. Usage:\n\nbash updatewine.sh\n\nArguments:\n\n\
  136. --no-install\tDo not install Wine or DXVK. Just compile them. Wine, meson & glslang must be installed for DXVK compilation.\n\
  137. --no-dxvk\tDo not compile or install DXVK\n\
  138. --no-vkd3d\tDo not compile or install VKD3D Proton\n\
  139. --no-nvapi\tDo not compile or install DXVK NVAPI\n\
  140. --no-pol\tDo not update PlayOnLinux Wine prefixes\n\n\
  141. --no-staging\tCompile Wine instead of Wine Staging\n\
  142. --no-wine\tDo not compile or install Wine/Wine Staging\n\n\
  143. Compiled packages are installed by default, unless '--no-install' argument is given.\n\
  144. If '--no-install' argument is given, the script doesn't check or update your PlayOnLinux Wine prefixes.\n"
  145. exit 0
  146. ;;
  147. esac
  148. args[$i]="${arg}"
  149. let i++
  150. done
  151. ###########################################################
  152. # Date timestamp and random number identifier for compiled
  153. # DXVK & Wine Staging builds
  154. # This variable is known as 'datedir' in other script files
  155. datesuffix=$(echo $(date '+%Y-%m-%d-%H%M%S'))
  156. ###########################################################
  157. # Add git commit hash overrides to argument list
  158. # Pass them to subscripts, as well.
  159. githash_overrides=(
  160. "${git_commithash_dxvknvapi}" # 0
  161. "${git_commithash_vkd3dproton}" # 1
  162. "${git_commithash_dxvk}" # 2
  163. "${git_commithash_glslang}" # 3
  164. "${git_commithash_meson}" # 4
  165. "${git_commithash_wine}" # 5
  166. )
  167. # Add git branches to argument list
  168. # Pass them to subscripts, as well.
  169. gitbranch_overrides=(
  170. "${git_branch_dxvknvapi}" # 6
  171. "${git_branch_vkd3dproton}" # 7
  172. "${git_branch_dxvk}" # 8
  173. "${git_branch_glslang}" # 9
  174. "${git_branch_meson}" # 10
  175. "${git_branch_wine}" # 11
  176. )
  177. # Add git sources to argument list
  178. # Pass them to subscripts, as well.
  179. gitsources=(
  180. "${git_source_dxvknvapi}" # 12
  181. "${git_source_vkd3dproton}" # 13
  182. "${git_source_dxvk}" # 14
  183. "${git_source_glslang_debian}" # 15
  184. "${git_source_meson_debian}" # 16
  185. "${git_source_wine}" # 17
  186. "${git_source_winestaging}" # 18
  187. # Debian
  188. "${git_source_dxvknvapi_debian}" # 19
  189. "${git_source_vkd3dproton_debian}" # 20
  190. "${git_source_dxvk_debian}" # 21
  191. "${git_source_wine_debian}" # 22
  192. "${git_source_winestaging_debian}" # 23
  193. )
  194. #############################
  195. # Commit syntax validity check
  196. for githash in ${githash_overrides[@]}; do
  197. if [[ ! $(printf ${githash} | wc -c) -eq 40 ]] && \
  198. [[ ! ${githash} == HEAD ]]; then
  199. echo -e "\nError: badly formatted commit hash '${githash}' in the script file 'updatewine.sh'. Aborting\n"
  200. exit 1
  201. fi
  202. done
  203. ###########################################################
  204. params=(${datesuffix} ${githash_overrides[@]} ${gitbranch_overrides[@]} ${gitsources[@]} ${args[@]})
  205. ###########################################################
  206. # General function for question responses
  207. function questionresponse() {
  208. local response=${1}
  209. read -r -p "" response
  210. if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  211. echo ""
  212. return 0
  213. else
  214. return 1
  215. fi
  216. }
  217. ###########################################################
  218. function reqsCheck() {
  219. local AVAIL_SPACE
  220. local REC_SPACE
  221. local MSG_SPACE
  222. local AVAIL_RAM
  223. local REC_RAM
  224. local MSG_RAM
  225. AVAIL_SPACE=$(df -h -B MB --output=avail . | sed '1d; s/[A-Z]*//g')
  226. REC_SPACE=8000
  227. MSG_SPACE="\e[1mWARNING:\e[0m Not sufficient storage space\n\nYou will possibly run out of space while compiling software.\n\
  228. The script strongly recommends ~\e[1m$((${REC_SPACE} / 1000)) GB\e[0m at least to compile software successfully but you have only\n\
  229. \e[1m${AVAIL_SPACE} MB\e[0m left on the filesystem the script is currently placed at.\n\n\
  230. Be aware that the script process may fail because of this, especially while compiling Wine Staging.\n\n\
  231. Do you really want to continue? [Y/n]"
  232. AVAIL_RAM=$(( $(grep -oP "(?<=^MemFree:).*[0-9]" /proc/meminfo | sed 's/ //g') / 1024 ))
  233. REC_RAM=4096
  234. MSG_RAM="\e[1mWARNING:\e[0m Not sufficient RAM available\n\nCompilation processes will likely fail.\n\
  235. The script strongly recommends ~\e[1m${REC_RAM} MB\e[0m at least to compile software successfully but you have only\n\
  236. \e[1m${AVAIL_RAM} MB\e[0m left on the computer the script is currently placed at.\n\n\
  237. Be aware that the script process may fail because of this, especially while compiling DXVK.\n\n\
  238. Do you really want to continue? [Y/n]"
  239. function reqs_property() {
  240. local avail_prop
  241. local req_prop
  242. local req_message
  243. local req_installtargets
  244. local req_targetconditions
  245. local fullcondition
  246. local i
  247. avail_prop="${1}"
  248. req_prop="${2}"
  249. req_message="${3}"
  250. req_installtargets="${4}"
  251. i=0
  252. for req_installtarget in ${req_installtargets}; do
  253. req_targetconditions[$i]=$(echo "[[ ! -v ${req_installtarget} ]] ||")
  254. let i++
  255. done
  256. req_targetconditions=($(echo ${req_targetconditions[@]} | sed 's/\(.*\) ||/\1 /'))
  257. fullcondition="[[ "${avail_prop}" -lt "${req_prop}" ]] && ($(echo ${req_targetconditions[@]}))"
  258. if $(eval ${fullcondition}); then
  259. INFO_SEP
  260. echo -e "${req_message}"
  261. questionresponse
  262. if [[ $? -ne 0 ]]; then
  263. echo -e "Cancelling.\n"
  264. exit 1
  265. fi
  266. unset avail_prop req_prop req_installtarget req_targetconditions fullcondition
  267. fi
  268. }
  269. reqs_property "${AVAIL_SPACE}" "${REC_SPACE}" "${MSG_SPACE}" "NO_WINE"
  270. reqs_property "${AVAIL_RAM}" "${REC_RAM}" "${MSG_RAM}" "NO_DXVK"
  271. }
  272. ###########################################################
  273. function sudoQuestion() {
  274. sudo -k
  275. echo -e "\e[1mINFO:\e[0m sudo password required\n\nThis script requires elevated permissions for package updates & installations. Please provide your sudo password for these script commands. Sudo permissions are not used for any other purposes.\n"
  276. sudo -v
  277. if [[ $? -ne 0 ]]; then
  278. echo -e "Invalid sudo password.\n"
  279. exit 1
  280. fi
  281. # PID of the current main process
  282. PIDOF=$$
  283. # Run sudo timestamp update on the background and continue the script execution
  284. # Refresh sudo timestamp while the main process is running
  285. function sudo_refresh() {
  286. while [[ $(printf $(ps ax -o pid --no-headers | grep -o ${PIDOF} &> /dev/null)$?) -eq 0 ]]; do
  287. sudo -nv && sleep 2
  288. done
  289. }
  290. sudo_refresh &
  291. }
  292. ###########################################################
  293. function checkInternet() {
  294. if [[ $(echo $(wget --delete-after -q -T 5 github.com -o -)$?) -ne 0 ]]; then
  295. echo -e "\nDNS name resolution failed (GitHub). Please check your network connection settings and try again.\n"
  296. exit 1
  297. fi
  298. rm -f ./index.html.tmp
  299. }
  300. checkInternet
  301. ###########################################################
  302. # Only Debian & Arch based Linux distributions are currently supported
  303. function determineDistroFamily() {
  304. # These are default package managers used by the supported Linux distributions
  305. pkgmgrs=('dpkg' 'pacman')
  306. for pkgmgr in ${pkgmgrs[@]}; do
  307. if [[ $(printf $(which ${pkgmgr} &> /dev/null)$?) -eq 0 ]]; then
  308. pkgmgr_valid=${pkgmgr}
  309. fi
  310. done
  311. case ${pkgmgr_valid} in
  312. dpkg)
  313. distro="debian"
  314. ;;
  315. pacman)
  316. distro="arch"
  317. ;;
  318. default|*)
  319. echo -e "Your Linux distribution is not supported. Aborting.\n"
  320. exit 1
  321. ;;
  322. esac
  323. }
  324. if [[ ! -v NO_WINE ]] || [[ ! -v NO_DXVK ]] || [[ ! -v NO_VKD3D ]] || [[ ! -v NO_NVAPI ]]; then
  325. echo -e "\n${SCRIPT_TITLE}\n\nBuild identifier:\t${datesuffix}\n"
  326. else
  327. echo ""
  328. fi
  329. if [[ -n ${args[*]} ]]; then
  330. echo -e "Using arguments:\t${args[*]}\n"
  331. fi
  332. determineDistroFamily
  333. INFO_SEP
  334. echo -e "\e[1mNOTE: \e[0mDXVK requires very latest Nvidia/AMD drivers to work.\nMake sure these drivers are available on your Linux distribution.\n\
  335. This script comes with GPU driver installation scripts for Debian-based Linux distributions.\n"
  336. INFO_SEP
  337. if [[ ! -v NO_WINE ]] || [[ ! -v NO_DXVK ]] || [[ ! -v NO_VKD3D ]] || [[ ! -v NO_NVAPI ]]; then
  338. reqsCheck
  339. sudoQuestion
  340. echo ""
  341. fi
  342. bash -c "cd ${distro} && bash ./updatewine_${distro}.sh ${params[*]}"