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.

490 lines
15 KiB

6 years ago
6 years ago
  1. #!/bin/env bash
  2. # Wrapper for DXVK & Wine compilation scripts
  3. # Copyright (C) 2018 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. # DO NOT RUN INDIVIDUALLY, ONLY VIA ../updatewine.sh PARENT SCRIPT!
  19. ########################################################
  20. # Root directory of this script file
  21. ROOTDIR="${PWD}"
  22. # datedir variable supplied by ../updatewine.sh script file
  23. datedir="${1}"
  24. ########################################################
  25. # http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal
  26. function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; }
  27. ########################################################
  28. # Divide input args into array indexes
  29. # These are passed to the subscripts (array b)
  30. i=0
  31. for p in ${@:2}; do
  32. params[$i]=${p}
  33. let i++
  34. done
  35. ########################################################
  36. # Parse input arguments, filter user parameters
  37. # The range is defined in ../updatewine.sh
  38. # All input arguments are:
  39. # <datedir> 4*<githash_override> 4*<gitbranch_override> <args>
  40. # 0 1 2 3 4 5 6 7 8 9...
  41. # Filter all but <args>, i.e. the first 0-8 arguments
  42. i=0
  43. for arg in ${params[@]:8}; do
  44. args[$i]="${arg}"
  45. let i++
  46. done
  47. # All valid arguments given in ../updatewine.sh are handled...
  48. # All valid arguments are passed to subscripts...
  49. # ...but these are specifically used in this script
  50. #
  51. for check in ${args[@]}; do
  52. case ${check} in
  53. --no-wine)
  54. NO_WINE=
  55. ;;
  56. --no-staging)
  57. NO_STAGING=
  58. ;;
  59. --no-dxvk)
  60. NO_DXVK=
  61. ;;
  62. --no-pol)
  63. NO_POL=
  64. ;;
  65. --no-winetricks)
  66. NO_WINETRICKS=
  67. ;;
  68. --no-install)
  69. NO_INSTALL=
  70. # If this option is given, do not check PoL wineprefixes
  71. NO_POL=
  72. ;;
  73. esac
  74. done
  75. ########################################################
  76. # Create identifiable directory for this build
  77. mkdir -p ${ROOTDIR}/compiled_deb/${datedir}
  78. ########################################################
  79. # If the script is interrupted (Ctrl+C/SIGINT), do the following
  80. function Deb_intCleanup() {
  81. cd ${ROOTDIR}
  82. rm -rf compiled_deb/${datedir}
  83. exit 0
  84. }
  85. # Allow interruption of the script at any time (Ctrl + C)
  86. trap "Deb_intCleanup" INT
  87. ########################################################
  88. # Check existence of ccache package
  89. function ccacheCheck() {
  90. if [[ $(echo $(dpkg -s ccache &>/dev/null)$?) -ne 0 ]]; then
  91. echo -e "\e[1mNOTE:\e[0m Please consider installation of 'ccache' for faster compilation times if you compile repetitively.\nInstall it by typing 'sudo apt install ccache'\n"
  92. fi
  93. }
  94. ccacheCheck
  95. ########################################################
  96. # Call Wine compilation & installation subscript in the following function
  97. function wine_install_main() {
  98. echo -e "Starting compilation & installation of Wine$(if [[ ! -v NO_STAGING ]]; then printf " Staging"; fi)\n\n\
  99. This can take up to 0.5-2 hours depending on the available CPU cores.\n\n\
  100. Using $(nproc --ignore 1) of $(nproc) available CPU cores for Wine source code compilation.
  101. "
  102. bash -c "cd ${ROOTDIR}/wineroot/ && bash ./winebuild.sh \"${datedir}\" \"${params[*]}\""
  103. }
  104. ########################################################
  105. # Call Winetricks compilation & installation subscript in the following function
  106. function winetricks_install_main() {
  107. local pkg="winetricks"
  108. # Location of expected Winetricks deb archive from
  109. # the point of view of this script file
  110. local pkgdebdir=".."
  111. # Winetricks availability check
  112. function winetricks_availcheck() {
  113. local apt_searchcheck=$(apt-cache search ^${pkg}$ | wc -l)
  114. if [[ $(echo $(dpkg -s ${pkg} &>/dev/null)$?) -ne 0 ]]; then
  115. # TODO expecting only 1 match from apt-cache output
  116. if [[ ${apt_searchcheck} -eq 1 ]]; then
  117. sudo apt install -y ${pkg}
  118. if [[ $? -eq 0 ]]; then
  119. # Winetricks already installed by the previous command
  120. return 0
  121. else
  122. echo -e "\e[1mWARNING:\e[0m Can't install Winetricks from repositories. Trying to compile from source.\n"
  123. # TODO Force Winetricks compilation from source. Is this a good practice?
  124. return 1
  125. fi
  126. else
  127. # Multiple or no entries from apt-cache output. Can't decide which package to use, so force winetricks compilation.
  128. echo -e "\e[1mWARNING:\e[0m Can't install Winetricks from repositories. Trying to compile from source.\n"
  129. # TODO Force Winetricks compilation from source. Is this a good practice?
  130. return 1
  131. fi
  132. else
  133. # Winetricks already installed on the system
  134. echo -e "Winetricks is installed on your system. Use your package manager or 'debian_install_winetricks.sh' script to update it.\n"
  135. return 0
  136. fi
  137. }
  138. # Winetricks installation from local deb package
  139. function winetricks_localdeb() {
  140. # Check that Wine exists on the system. If yes, then
  141. # install other required winetricks dependencies
  142. # so that Winetricks install script won't complain about
  143. # missing them.
  144. #
  145. local known_wines=(
  146. 'wine'
  147. 'wine-stable'
  148. 'wine32'
  149. 'wine64'
  150. 'libwine:amd64'
  151. 'libwine:i386'
  152. 'wine-git'
  153. 'wine-staging-git'
  154. )
  155. # Other winetricks dependencies
  156. local winetricks_deps=('cabextract' 'unzip' 'x11-utils')
  157. # If known wine is found, then check winetricks_deps and install them if needed.
  158. for winepkg in ${known_wines[@]}; do
  159. if [[ $(echo $(dpkg -s ${winepkg} &>/dev/null)$?) -eq 0 ]]; then
  160. for tricksdep in ${winetricks_deps[@]}; do
  161. if [[ $(echo $(dpkg -s ${tricksdep} &>/dev/null)$?) -ne 0 ]]; then
  162. sudo apt install -y ${tricksdep}
  163. if [[ $? -ne 0 ]]; then
  164. echo -e "\e[1mERROR:\e[0m Couldn't install Winetricks dependency ${tricksdep}. Skipping Winetricks installation.\n"
  165. # TODO revert installation of any installed 'tricksdep' installed on previous loop cycle
  166. if [[ ! -v NO_INSTALL ]];then
  167. echo -e "DXVK won't be installed\n"
  168. # We can set this value because winetricks function is intented to be called
  169. # after Wine compilation & installation BUT before DXVK install function
  170. # DXVK runtime (not build time) depends on Winetricks
  171. params+=('--no-install')
  172. fi
  173. # Special variable only to inform user about errors in Winetricks installation
  174. WINETRICKS_ERROR=
  175. return 1
  176. fi
  177. fi
  178. done
  179. # If known wine has already been found, do not iterate through other candidates
  180. break
  181. fi
  182. done
  183. # Check for existing winetricks deb archives in the previous folder
  184. local localdeb=$(find ${pkgdebdir} -type f -name "${pkg}*.deb" | wc -l)
  185. case ${localdeb} in
  186. 0)
  187. # No old winetricks archives
  188. # Just fall through
  189. ;;
  190. 1)
  191. # One old winetricks archive found
  192. echo -e "Found already compiled Winetricks archive, installing it.\n"
  193. # TODO ask user? Note that asking this limits the automation process of this script
  194. # unless a solution will be implemented (e.g. parameter switch)
  195. sudo dpkg -i ${pkgdebdir}/${pkg}*.deb
  196. return 0
  197. ;;
  198. *)
  199. # Multiple old winetricks archives found
  200. # Move them and compile a new one
  201. if [[ ! -d ${pkgdebdir}/winetricks_old ]]; then
  202. mkdir -p ${pkgdebdir}/winetricks_old
  203. fi
  204. mv ${pkgdebdir}/${pkg}*.deb ${pkgdebdir}/winetricks_old/
  205. if [[ $? -ne 0 ]]; then
  206. echo -e "\e[1mWARNING:\e[0m Couldn't move old Winetricks archives. Not installing Winetricks.\n"
  207. if [[ ! -v NO_INSTALL ]];then
  208. echo -e "DXVK won't be installed\n"
  209. # We can set this value because winetricks function is intented to be called
  210. # after Wine compilation & installation BUT before DXVK install function
  211. # DXVK runtime (not build time) depends on Winetricks
  212. params+=('--no-install')
  213. fi
  214. fi
  215. ;;
  216. esac
  217. echo -e "Starting compilation & installation of Winetricks\n"
  218. bash -c "cd .. && bash ./debian_install_winetricks.sh"
  219. if [[ $? -eq 0 ]]; then
  220. # The compiled Winetricks deb package is found in the previous folder
  221. sudo dpkg -i ${pkgdebdir}/${pkg}*.deb
  222. if [[ $? -ne 0 ]]; then
  223. echo -e "\e[1mWARNING:\e[0m Couldn't install Winetricks.\n"
  224. if [[ ! -v NO_INSTALL ]];then
  225. echo -e "DXVK won't be installed\n"
  226. # We can set this value because winetricks function is intented to be called
  227. # after Wine compilation & installation BUT before DXVK install function
  228. # DXVK runtime (not build time) depends on Winetricks
  229. params+=('--no-install')
  230. fi
  231. # Special variable only to inform user about errors in Winetricks installation
  232. WINETRICKS_ERROR=
  233. return 1
  234. fi
  235. else
  236. echo -e "\e[1mWARNING:\e[0m Couldn't compile Winetricks.\n"
  237. if [[ ! -v NO_INSTALL ]];then
  238. echo -e "DXVK won't be installed\n"
  239. # We can set this value because winetricks function is intented to be called
  240. # after Wine compilation & installation BUT before DXVK install function
  241. # DXVK runtime (not build time) depends on Winetricks
  242. params+=('--no-install')
  243. fi
  244. # Special variable only to inform user about errors in Winetricks compilation
  245. WINETRICKS_ERROR=
  246. return 1
  247. fi
  248. }
  249. winetricks_availcheck
  250. if [[ $? -ne 0 ]]; then
  251. winetricks_localdeb
  252. fi
  253. }
  254. ########################################################
  255. # Call DXVK compilation & installation subscript in the following function
  256. function dxvk_install_main() {
  257. echo -e "Starting compilation & installation of DXVK\n\n\
  258. This can take up to 10-20 minutes depending on how many dependencies we need to build for it.\n"
  259. bash -c "cd ${ROOTDIR}/dxvkroot && bash dxvkbuild.sh \"${datedir}\" \"${params[*]}\""
  260. }
  261. ########################################################
  262. function mainQuestions() {
  263. # General function for question responses
  264. function questionresponse() {
  265. local response=${1}
  266. read -r -p "" response
  267. if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  268. echo ""
  269. return 0
  270. else
  271. return 1
  272. fi
  273. }
  274. ##################################
  275. INFO_SEP
  276. echo -e "\e[1mINFO:\e[0m About installation\n\nThe installation may take long time because many development dependencies may be \
  277. installed and the following packages may be compiled from source (depending on your choises):\n\n\
  278. \t- Wine/Wine Staging (latest git version)\n\
  279. \t- DXVK (latest git version)\n\
  280. \t- meson & glslang (latest git versions; these are build time dependencies for DXVK)\n\n\
  281. Do you want to continue? [Y/n]"
  282. questionresponse
  283. if [[ $? -ne 0 ]]; then
  284. echo -e "Cancelling.\n"
  285. exit 1
  286. fi
  287. ####################
  288. INFO_SEP
  289. echo -e "\e[1mQUESTION:\e[0m Do you want to remove unneeded build time dependencies after package build process? [Y/n]"
  290. questionresponse
  291. if [[ $? -eq 0 ]]; then
  292. params+=('--buildpkg-rm')
  293. fi
  294. ####################
  295. AVAIL_SPACE=$(df -h -B MB --output=avail . | sed '1d; s/[A-Z]*//g')
  296. REC_SPACE=8000
  297. if [[ ${AVAIL_SPACE} -lt ${REC_SPACE} ]] && [[ ! -v NO_WINE ]]; then
  298. INFO_SEP
  299. echo -e "\e[1mWARNING:\e[0m Not sufficient storage space\n\nYou will possibly run out of space while compiling software.\n\
  300. The script strongly recommends ~\e[1m$((${REC_SPACE} / 1000)) GB\e[0m at least to compile software successfully but you have only\n\
  301. \e[1m${AVAIL_SPACE} MB\e[0m left on the filesystem the script is currently placed at.\n\n\
  302. Be aware that the script process may fail because of this, especially while compiling Wine Staging.\n\n\
  303. Do you really want to continue? [Y/n]"
  304. questionresponse
  305. if [[ $? -ne 0 ]]; then
  306. echo -e "Cancelling.\n"
  307. exit 1
  308. fi
  309. unset AVAIL_SPACE REC_SPACE
  310. fi
  311. ####################
  312. # This question is relevant only if DXVK stuff is compiled
  313. if [[ ! -v NO_DXVK ]]; then
  314. INFO_SEP
  315. echo -e "\e[1mQUESTION:\e[0m Update existing dependencies?\n\nIn a case you have old build time dependencies on your system, do you want to update them?\n\
  316. If you answer 'yes', then those dependencies are updated if needed. Otherwise, already installed\n\
  317. build time dependencies are not updated. If you don't have 'meson' or 'glslang' installed on your system, they will be compiled, anyway.\n\
  318. Be aware, that updating these packages may increase total run time used by this script.\n\n\
  319. Update dependency packages & other system packages? [Y/n]"
  320. questionresponse
  321. if [[ $? -eq 0 ]]; then
  322. params+=('--updateoverride')
  323. fi
  324. INFO_SEP
  325. fi
  326. }
  327. ########################################################
  328. function coredeps_check() {
  329. # Universal core dependencies for package compilation
  330. _coredeps=('dh-make' 'make' 'gcc' 'build-essential' 'fakeroot')
  331. for coredep in ${_coredeps[@]}; do
  332. if [[ $(echo $(dpkg -s ${coredep} &>/dev/null)$?) -ne 0 ]]; then
  333. echo -e "Installing core dependency ${coredep}.\n"
  334. sudo apt install -y ${coredep}
  335. if [[ $? -ne 0 ]]; then
  336. echo -e "Could not install ${coredep}. Aborting.\n"
  337. exit 1
  338. fi
  339. fi
  340. done
  341. }
  342. ########################################################
  343. # If either Wine or DXVK is to be compiled
  344. if [[ ! -v NO_WINE ]] || [[ ! -v NO_DXVK ]]; then
  345. mainQuestions
  346. coredeps_check
  347. fi
  348. ####################
  349. # If Wine is going to be compiled, then
  350. if [[ ! -v NO_WINE ]]; then
  351. wine_install_main
  352. else
  353. echo -e "Skipping Wine build$(if [[ ! -v NO_INSTALL ]]; then printf " & installation"; fi) process.\n"
  354. fi
  355. ####################
  356. # Run winetricks installation, if needed
  357. if [[ ! -v NO_DXVK ]] && [[ ! -v NO_INSTALL ]]; then
  358. if [[ ! -v NO_WINETRICKS ]]; then
  359. winetricks_install_main
  360. else
  361. echo -e "Skipping Winetricks build & installation process.\n \
  362. DXVK will not be installed, unless Winetricks is already installed on your system.\n"
  363. fi
  364. fi
  365. ####################
  366. # If DXVK is going to be installed, then
  367. if [[ ! -v NO_DXVK ]]; then
  368. dxvk_install_main
  369. else
  370. echo -e "Skipping DXVK build$(if [[ ! -v NO_INSTALL ]]; then printf " & installation"; fi) process.\n"
  371. fi
  372. ####################
  373. # If PlayOnLinux Wine prefixes are going to be updated, then
  374. if [[ ! -v NO_POL ]]; then
  375. echo -e "\e[1mINFO:\e[0m Updating your PlayOnLinux Wine prefixes.\n"
  376. bash -c "cd ${ROOTDIR} && bash playonlinux_prefixupdate.sh"
  377. fi
  378. # If error occured during Winetricks script runtime, then
  379. if [[ -v WINETRICKS_ERROR ]]; then
  380. echo -e "\e[1mWARNING:\e[0m Couldn't compile or install Winetricks.\
  381. $(if [[ ! -v NO_DXVK ]]; then printf " DXVK installation may have failed, too."; fi)\n"
  382. fi