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.

397 lines
11 KiB

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