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.

528 lines
16 KiB

6 years ago
6 years ago
  1. #!/bin/env bash
  2. # Compile DXVK git on Debian/Ubuntu/Mint and variants
  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. DXVKROOT="${PWD}"
  22. # datedir variable supplied by ../updatewine_debian.sh script file
  23. datedir="${1}"
  24. ###########################################################
  25. # Parse input arguments
  26. i=0
  27. for arg in ${@:2}; do
  28. args[$i]="${arg}"
  29. let i++
  30. done
  31. # Must be a true array as defined above, not a single index list!
  32. #args="${@:2}"
  33. for check in ${args[@]}; do
  34. case ${check} in
  35. --no-install)
  36. NO_INSTALL=
  37. ;;
  38. --updateoverride)
  39. updateoverride=
  40. ;;
  41. esac
  42. done
  43. ###########################################################
  44. # Some version of Wine must be found in the system
  45. # Warn the user
  46. function wineCheck() {
  47. if [[ ! $(which wine 2>/dev/null) ]]; then
  48. echo -e "Warning: You must have Wine installed before DXVK can be compiled.\n"
  49. fi
  50. }
  51. wineCheck
  52. ###########################################################
  53. # If the script is interrupted (Ctrl+C/SIGINT), do the following
  54. function DXVK_intCleanup() {
  55. rm -rf ${DXVKROOT}/{dxvk-git,meson,glslang}
  56. rm -rf ${DXVKROOT}/../compiled_deb/"${datedir}"
  57. exit 0
  58. }
  59. # Allow interruption of the script at any time (Ctrl + C)
  60. trap "DXVK_intCleanup" INT
  61. ########################################################
  62. # http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal
  63. function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; }
  64. ##################################
  65. # Update all packages if updateoverride given
  66. if [[ -v updateoverride ]]; then
  67. echo -en "Updating all packages" && \
  68. if [[ $(printf $(sudo -n uptime &>/dev/null)$?) -ne 0 ]]; then printf " Please provide your sudo password.\n"; else printf "\n\n"; fi
  69. sudo apt update && sudo apt upgrade -y
  70. fi
  71. ##################################
  72. # Check do we need to compile the package
  73. # given as input for this function
  74. function pkgcompilecheck() {
  75. local pkg=${1}
  76. local install_function=${2}
  77. if [[ $(echo $(dpkg -s ${coredep} &>/dev/null)$?) -ne 0 ]] || [[ -v updateoverride ]]; then
  78. ${install_function}
  79. fi
  80. }
  81. ###################################################
  82. function preparepackage() {
  83. echo -e "Starting compilation (& installation) of ${1}\n"
  84. # Set local variables
  85. local _pkgname=${1}
  86. local _pkgdeps=${2}
  87. local _pkgurl=${3}
  88. local _pkgver=${4}
  89. # Optional variable for runtime dependencies array
  90. if [[ -n ${5} ]]; then local _pkgdeps_runtime=${5}; fi
  91. # Check and install package related dependencies if they are missing
  92. function pkgdependencies() {
  93. # Generate a list of missing dependencies
  94. local a=0
  95. for p in ${@}; do
  96. if [[ $(echo $(dpkg -s ${p} &>/dev/null)$?) -ne 0 ]]; then
  97. local list[$a]=${p}
  98. let a++
  99. fi
  100. done
  101. # Install missing dependencies, be informative
  102. local b=0
  103. for pkgdep in ${list[@]}; do
  104. echo -e "$(( $b + 1 ))/$(( ${#list[*]} )) - Installing ${_pkgname} dependency ${pkgdep}"
  105. sudo apt install -y ${pkgdep} &> /dev/null
  106. if [[ $? -eq 0 ]]; then
  107. let b++
  108. else
  109. echo -e "\nError occured while installing ${pkgdep}. Aborting.\n"
  110. exit 1
  111. fi
  112. done
  113. }
  114. # Get git-based version in order to rename the package main folder
  115. # This is required by deb builder. It retrieves the version number
  116. # from that folder name
  117. function pkgversion() {
  118. if [[ -n "${_pkgver}" ]] && [[ "${_pkgver}" =~ ^git ]]; then
  119. cd ${_pkgname}
  120. _pkgver=$(eval "${_pkgver}")
  121. cd ..
  122. fi
  123. }
  124. function pkgfoldername() {
  125. # Remove old build directory, if present
  126. rm -rf ${_pkgname}
  127. # Create a new build directory, access it and download git sources there
  128. mkdir ${_pkgname}
  129. cd ${_pkgname}
  130. echo -e "Retrieving source code of ${_pkgname} from $(printf ${_pkgurl} | sed 's/^.*\/\///; s/\/.*//')\n"
  131. git clone ${_pkgurl} ${_pkgname}
  132. # If sources could be downloaded, rename the folder properly for deb builder
  133. # Access the folder after which package specific debianbuild function will be run
  134. # That function is defined inside package specific install_main function below
  135. if [[ $? -eq 0 ]]; then
  136. pkgversion && \
  137. mv ${_pkgname} ${_pkgname}-${_pkgver}
  138. cd ${_pkgname}-${_pkgver}
  139. else
  140. echo -e "Error while downloading source of ${_pkgname} package. Aborting\n"
  141. exit 1
  142. fi
  143. }
  144. # Execute above functions
  145. pkgdependencies ${_pkgdeps[*]} && \
  146. if [[ -v _pkgdeps_runtime ]]; then pkgdependencies ${_pkgdeps_runtime[*]}; fi
  147. pkgfoldername
  148. unset _pkgver
  149. }
  150. ###################################################
  151. # MESON COMPILATION & INSTALLATION
  152. # Required by DXVK package
  153. function meson_install_main() {
  154. # Package name
  155. local pkgname="meson"
  156. # Build time dependencies
  157. local pkgdeps_build=(
  158. 'python3'
  159. 'dh-python'
  160. 'python3-setuptools'
  161. 'ninja-build'
  162. )
  163. # Git source location
  164. local pkgurl="https://github.com/mesonbuild/meson"
  165. # Parsed version number from git source files
  166. local pkgver_git="git describe --long | sed 's/\-[a-z].*//; s/\-/\./; s/[a-z]//g'"
  167. # Location of Debian compilation instructions archive
  168. local pkgurl_debian="http://archive.ubuntu.com/ubuntu/pool/universe/m/meson/meson_0.45.1-2.debian.tar.xz"
  169. function meson_debianbuild() {
  170. # Download predefined Meson debian rules archive
  171. # Extract it, and finally delete the archive
  172. wget ${pkgurl_debian} -O debian.tar.xz
  173. tar xf debian.tar.xz && rm debian.tar.xz
  174. # Get sed compatible Meson version string
  175. local meson_version=$(printf '%s' $(pwd | sed -e 's/.*\-//' -e 's/\./\\\./g'))
  176. # Do not perform any tests or checks during compilation process
  177. sed -ir '/nocheck/d' debian/control
  178. sed -ir '/\.\/run_tests\.py/d' debian/rules
  179. # Downgrade debhelper version requirement for Debian compatilibity
  180. sed -ir 's/debhelper (>= 11)/debhelper (>= 10)/' debian/control
  181. # Correct & update package version number + debian rules
  182. sed -ir "s/0\.45\.1-2/${meson_version}/" debian/changelog
  183. # Delete the following strings from debian/rules file
  184. # They are deprecated
  185. sed -ir '/rm \$\$(pwd)\/debian\/meson\/usr\/bin\/mesontest/d' debian/rules
  186. sed -ir '/rm \$\$(pwd)\/debian\/meson\/usr\/bin\/mesonconf/d' debian/rules
  187. sed -ir '/rm \$\$(pwd)\/debian\/meson\/usr\/bin\/mesonintrospect/d' debian/rules
  188. sed -ir '/rm \$\$(pwd)\/debian\/meson\/usr\/bin\/wraptool/d' debian/rules
  189. sed -ir '/rm \-rf \$\$(pwd)\/debian\/meson\/usr\/lib\/python3/d' debian/rules
  190. # Remove deprecated, downloaded patch files
  191. rm -r debian/patches
  192. # Remove irrelevant sample files
  193. rm -r debian/*.{ex,EX}
  194. # Start deb builder. Do not build either debug symbols or doc files
  195. DEB_BUILD_OPTIONS="strip nodocs noddebs nocheck" dpkg-buildpackage -rfakeroot -b -us -uc
  196. # Once compiled, install and store the compiled deb archive
  197. # We do not make installation optional because this is a core dependency for DXVK
  198. if [[ $? -eq 0 ]]; then
  199. rm -rf ../*.{changes,buildinfo,tar.xz} && \
  200. sudo dpkg -i ../${pkgname}*.deb && \
  201. mv ../${pkgname}*.deb ../../../compiled_deb/"${datedir}" && \
  202. echo -e "Compiled ${pkgname} is stored at '$(readlink -f ../../../compiled_deb/"${datedir}")/'\n"
  203. cd ../..
  204. rm -rf ${pkgname}
  205. else
  206. exit 1
  207. fi
  208. }
  209. # Execute above functions
  210. preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" && \
  211. meson_debianbuild
  212. }
  213. ###################################################
  214. # GLSLANG COMPILATION & INSTALLATION
  215. # Required by DXVK package
  216. function glslang_install_main() {
  217. # Package name
  218. local pkgname="glslang"
  219. # Build time dependencies
  220. local pkgdeps_build=('cmake' 'python2.7')
  221. # Git source location
  222. local pkgurl="https://github.com/KhronosGroup/glslang"
  223. # Parsed version number from git source files
  224. local pkgver_git="git describe --long | sed 's/\-[a-z].*//; s/\-/\./; s/[a-z]//g'"
  225. function glslang_debianbuild() {
  226. # Create debian subdirectory
  227. dh_make --createorig -s -y -c bsd
  228. # Set Build dependencies into debian/control file
  229. sed -ie "s/^Build-Depends:.*$/Build-Depends: debhelper (>=10), $(echo ${_coredeps[*]} | \
  230. sed 's/\s/, /g'), $(echo ${pkgdeps_build[*]} | sed 's/\s/, /g')/g" debian/control
  231. # Skip running override_dh_usrlocal while executing deb builder
  232. printf 'override_dh_usrlocal:' | tee -a debian/rules
  233. # Remove irrelevant sample files
  234. rm -r debian/*.{ex,EX}
  235. # Start deb builder. Do not build either debug symbols or doc files
  236. DEB_BUILD_OPTIONS="strip nodocs noddebs" dpkg-buildpackage -rfakeroot -b -us -uc
  237. # Once compiled, install and store the compiled deb archive
  238. # We do not make installation optional because this is a core dependency for DXVK
  239. if [[ $? -eq 0 ]]; then
  240. rm -rf ../*.{changes,buildinfo,tar.xz} && \
  241. sudo dpkg -i ../${pkgname}*.deb && \
  242. mv ../${pkgname}*.deb ../../../compiled_deb/"${datedir}" && \
  243. echo -e "Compiled ${pkgname} is stored at '$(readlink -f ../../../compiled_deb/"${datedir}")/'\n"
  244. cd ../..
  245. rm -rf ${pkgname}
  246. else
  247. exit 1
  248. fi
  249. }
  250. # Execute above functions
  251. preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" && \
  252. glslang_debianbuild
  253. }
  254. ###################################################
  255. # DXVK COMPILATION & INSTALLATION
  256. function dxvk_install_main() {
  257. # Package name
  258. local pkgname="dxvk-git"
  259. # Build time dependencies
  260. local pkgdeps_build=(
  261. 'meson'
  262. 'glslang'
  263. 'gcc-mingw-w64-x86-64'
  264. 'gcc-mingw-w64-i686'
  265. 'g++-mingw-w64-x86-64'
  266. 'g++-mingw-w64-i686'
  267. 'mingw-w64-x86-64-dev'
  268. 'mingw-w64-i686-dev'
  269. )
  270. # Runtime dependencies
  271. local pkgdeps_runtime=('wine' 'winetricks')
  272. # Git source location
  273. local pkgurl="https://github.com/doitsujin/dxvk"
  274. # Parsed version number from git source files
  275. local pkgver_git="git describe --long | sed 's/\-[a-z].*//; s/\-/\./; s/[a-z]//g'"
  276. # Use posix alternates for MinGW binaries
  277. function dxvk_posixpkgs() {
  278. local packages=(
  279. 'i686-w64-mingw32-g++'
  280. 'i686-w64-mingw32-gcc'
  281. 'x86_64-w64-mingw32-g++'
  282. 'x86_64-w64-mingw32-gcc'
  283. )
  284. for package in "${packages[@]}"; do
  285. local option=$(echo "" | sudo update-alternatives --config "${package}" | grep posix | sed 's@^[^0-9]*\([0-9]\+\).*@\1@')
  286. echo "${option}" | sudo update-alternatives --config "${package}" &> /dev/null
  287. if [[ $? -ne 0 ]]; then
  288. echo -e "Error occured while running 'update-alternatives' for '${package}'. Aborting\n"
  289. exit 1
  290. fi
  291. done
  292. }
  293. function dxvk_custompatches() {
  294. # Get our current directory, since we will change it during patching process below
  295. # We want to go back here after having applied the patches
  296. local CURDIR=${PWD}
  297. # Check if the following folder exists, and proceed.
  298. if [[ -d ${DXVKROOT}/../../dxvk_custom_patches ]]; then
  299. cp -r ${DXVKROOT}/../../dxvk_custom_patches/*.{patch,diff} ${DXVKROOT}/${pkgname}/
  300. local dxvk_builddir=$(ls ${DXVKROOT}/${pkgname}/)
  301. # Expecting just one folder here. This method doesn't work with multiple dirs present
  302. if [[ $(echo ${dxvk_builddir} | wc -l) -gt 1 ]]; then
  303. echo "Error: Multiple dxvk build directories detected. Can't decide which one to use. Aborting\n"
  304. exit 1
  305. fi
  306. local dxvk_buildpath=$(readlink -f ${dxvk_builddir})
  307. cd ${dxvk_buildpath}
  308. for pfile in ../*.{patch,diff}; do
  309. if [[ -f ${pfile} ]]; then
  310. echo -e "Applying DXVK patch: ${pfile}\n"
  311. patch -Np1 < ${pfile}
  312. fi
  313. if [[ $? -ne 0 ]]; then
  314. echo -e "Error occured while applying DXVK patch '${pfile}'. Aborting\n"
  315. cd ${CURDIR}
  316. exit 1
  317. fi
  318. done
  319. cd ${CURDIR}
  320. fi
  321. }
  322. # Debian-specific compilation & installation rules
  323. function dxvk_debianbuild() {
  324. local dxvx_relative_builddir="debian/source/dxvk-master"
  325. # Create debian subdirectory, add supplied LICENSE file
  326. dh_make --createorig -s -y -c custom --copyrightfile ../LICENSE
  327. # Set Build dependencies into debian/control file
  328. sed -ie "s/^Build-Depends:.*$/Build-Depends: debhelper (>=10), $(echo ${_coredeps[*]} | \
  329. sed 's/\s/, /g'), $(echo ${pkgdeps_build[*]} | sed 's/\s/, /g')/g" debian/control
  330. # Set Runtime dependencies into debian/control file
  331. sed -ie "s/^Depends:.*$/Depends: $(echo ${pkgdeps_runtime} | sed 's/\s/, /g')/g" debian/control
  332. # Tell deb builder to bundle these files
  333. printf "${dxvx_relative_builddir}/setup_dxvk.verb usr/share/dxvk/" > debian/install
  334. printf "\n${dxvx_relative_builddir}/bin/* usr/bin/" >> debian/install
  335. # Remove irrelevant sample files
  336. rm -r debian/*.{ex,EX}
  337. # Overwrite debian/rules file with the following contents
  338. cat << 'DXVK-DEBIANRULES' > debian/rules
  339. #!/usr/bin/make -f
  340. %:
  341. dh $@
  342. override_dh_auto_configure:
  343. override_dh_usrlocal:
  344. DXVK-DEBIANRULES
  345. # Start DXVK compilation
  346. bash ./package-release.sh master debian/source/ --no-package
  347. if [[ $? -ne 0 ]]; then
  348. echo "Error while compiling ${pkgname}. Check messages above. Aborting\n"
  349. exit 1
  350. fi
  351. # Make a proper executable script for setup_dxvk.verb file
  352. mkdir -p ${dxvx_relative_builddir}/bin
  353. echo -e "#!/bin/sh\nwinetricks --force /usr/share/dxvk/setup_dxvk.verb" \
  354. > "${dxvx_relative_builddir}/bin/setup_dxvk"
  355. chmod +x "${dxvx_relative_builddir}/bin/setup_dxvk"
  356. # Tell deb builder to install DXVK x32 & x64 subfolders
  357. for arch in 64 32; do
  358. mkdir -p ${dxvx_relative_builddir}/x${arch}
  359. printf "\n${dxvx_relative_builddir}/x${arch}/* usr/share/dxvk/x${arch}/" >> debian/install
  360. done
  361. # Start deb builder. Do not build either debug symbols or doc files
  362. DEB_BUILD_OPTIONS="strip nodocs noddebs" dpkg-buildpackage -us -uc -b --source-option=--include-binaries
  363. # Once compiled, possibly install and store the compiled deb archive
  364. if [[ $? -eq 0 ]]; then
  365. if [[ ! -v NO_INSTALL ]]; then
  366. sudo dpkg -i ../${pkgname}*.deb
  367. fi
  368. rm -rf ../*.{changes,buildinfo,tar.xz}
  369. mv ../${pkgname}*.deb ../../../compiled_deb/"${datedir}" && \
  370. echo -e "Compiled ${pkgname} is stored at '$(readlink -f ../../../compiled_deb/"${datedir}")/'\n"
  371. cd ../..
  372. rm -rf ${pkgname}
  373. else
  374. exit 1
  375. fi
  376. }
  377. # Execute above functions
  378. # Do not check runtime dependencies as our check method expects exact package name in
  379. # function 'preparepackage'. This does not apply to runtime dependency 'wine', which
  380. # may be 'wine', 'wine-git', 'wine-staging-git' etc. in truth
  381. #
  382. preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" && \
  383. dxvk_posixpkgs && \
  384. dxvk_custompatches && \
  385. dxvk_debianbuild
  386. }
  387. ####################################################################
  388. pkgcompilecheck meson meson_install_main
  389. pkgcompilecheck glslang glslang_install_main
  390. dxvk_install_main