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.

827 lines
23 KiB

6 years ago
6 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #!/bin/env bash
  2. # Compile DXVK git on Debian/Ubuntu/Mint and variants
  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. # 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. # Divide input args into array indexes
  26. i=0
  27. for p in ${@:2}; do
  28. params[$i]=${p}
  29. let i++
  30. done
  31. ########################################################
  32. # Parse input git override hashes
  33. # This order is mandatory!
  34. # If you change the order or contents of 'githash_overrides'
  35. # array in ../updatewine.sh, make sure to update these
  36. # variables!
  37. #
  38. git_commithash_dxvk=${params[0]}
  39. git_commithash_glslang=${params[1]}
  40. git_commithash_meson=${params[2]}
  41. git_branch_dxvk=${params[3]}
  42. git_branch_glslang=${params[5]}
  43. git_branch_meson=${params[6]}
  44. git_source_dxvk=${params[8]}
  45. git_source_glslang=${params[9]}
  46. git_source_meson=${params[10]}
  47. ########################################################
  48. # Parse input arguments, filter user parameters
  49. # The range is defined in ../updatewine.sh
  50. # All input arguments are:
  51. # <datedir> 4*<githash_override> 4*<gitbranch_override> <args>
  52. # 0 1 2 3 4 5 6 7 8 9...
  53. # Filter all but <args>, i.e. the first 0-8 arguments
  54. i=0
  55. for arg in ${params[@]:8}; do
  56. args[$i]="${arg}"
  57. let i++
  58. done
  59. for check in ${args[@]}; do
  60. case ${check} in
  61. --no-install)
  62. NO_INSTALL=
  63. ;;
  64. --updateoverride)
  65. UPDATE_OVERRIDE=
  66. ;;
  67. --buildpkg-rm)
  68. BUILDPKG_RM=
  69. ;;
  70. --no-dxvk)
  71. NO_DXVK=
  72. ;;
  73. esac
  74. done
  75. ########################################################
  76. # Check presence of Wine. Some version of Wine should
  77. # be found in the system in order to install DXVK.
  78. known_wines=(
  79. 'wine'
  80. 'wine-stable'
  81. 'wine32'
  82. 'wine64'
  83. 'libwine:amd64'
  84. 'libwine:i386'
  85. 'wine-git'
  86. 'wine-staging-git'
  87. )
  88. # Alternative remote dependency packages for Debian distributions which offer too old packages for DXVK
  89. #
  90. # Left side: <package name in repositories>,<version_number>
  91. # Right side: package alternative source URL
  92. #
  93. # NOTE: Determine these packages in corresponding debdata files as runtime or buildtime dependencies
  94. #
  95. # As this seems to be a dependency for binutils-mingw packages
  96. function binutils_common_ver() {
  97. if [[ $(dpkg -s binutils-common &>/dev/null)$? -ne 0 ]]; then
  98. sudo apt -y install binutils-common
  99. fi
  100. if [[ $? -eq 0 ]]; then
  101. binutils_ver=$(dpkg -s binutils-common | sed -rn 's/^Version: ([0-9\.]+).*$/\1/p')
  102. fi
  103. }
  104. binutils_common_ver
  105. remotePackagesUrls=(
  106. "http://mirrors.edge.kernel.org/ubuntu/pool/universe/b/binutils-mingw-w64"
  107. "http://mirrors.edge.kernel.org/ubuntu/pool/universe/g/gcc-mingw-w64"
  108. "http://mirrors.edge.kernel.org/ubuntu/pool/universe/m/mingw-w64"
  109. )
  110. remotePackagesPool=(
  111. "gcc-mingw-w64-base"
  112. "mingw-w64-common"
  113. "binutils-mingw-w64-x86-64"
  114. "binutils-mingw-w64-i686"
  115. "mingw-w64-x86-64-dev"
  116. "gcc-mingw-w64-x86-64"
  117. "g++-mingw-w64-x86-64"
  118. "mingw-w64-i686-dev"
  119. "gcc-mingw-w64-i686"
  120. "g++-mingw-w64-i686"
  121. )
  122. typeset -A remotePackagesAlt
  123. for rpp in ${remotePackagesPool[@]}; do
  124. for URL in "${remotePackagesUrls[@]}"; do
  125. # Fetch exact package name and associated date
  126. pkg_data=$(curl -s "${URL}/" | sed -rn 's/.*href="(.*(amd64|all)\.deb)">.*([0-9]{2}\-[A-Za-z]{3}\-[0-9]{4}).*/\1 \3/p' | sed 's/%2B/+/g' | grep "${rpp}")
  127. if [[ ${pkg_data} = "" ]]; then
  128. continue
  129. fi
  130. # Associate Unix-formatted date with the exact package name
  131. IFS=$'\n'
  132. for ps in ${pkg_data[@]}; do
  133. ps_pkg=$(printf "%s" "${ps}" | awk '{print $1}')
  134. ps_date=$(date --date=$(printf "%s" "${ps}" | awk '{print $NF}') +%s)
  135. remotePackagesAltDate+=("${ps_date}|${ps_pkg}")
  136. done
  137. IFS=" "
  138. # Sort exact package names by date
  139. remotePackagesAltDateSorted=($(sort <<<"${remotePackagesAltDate[*]}"))
  140. # binutils packages depend on system binutils-common. Versions must match, even if not the newest package available.
  141. if [[ ${ps_pkg} =~ binutils ]] && [[ ${binutils_ver} != "" ]]; then
  142. for b in ${remotePackagesAltDateSorted[@]}; do
  143. if [[ ${b} =~ ${binutils_ver} ]]; then
  144. remotePackagesAltBinUtils+=(${b})
  145. fi
  146. done
  147. unset remotePackagesAltDateSorted
  148. remotePackagesAltDateSorted=(${remotePackagesAltBinUtils[@]})
  149. unset remotePackagesAltBinUtils
  150. fi
  151. # Get the newest exact package name
  152. pkg=$(printf "%s" ${remotePackagesAltDateSorted[-1]} | sed -r 's/^[0-9]+\|(.*)/\1/')
  153. unset remotePackagesAltDate
  154. unset remotePackagesAltDateSorted
  155. # Prepare and set a well-formatted value into remotePackagesAlt associative array
  156. if [ ! "${pkg}" == "" ]; then
  157. rpp_url=$(printf "%s/%s" "${URL}" "${pkg}")
  158. rpp_shortver=$(printf "%s" "${pkg}" | sed -r 's/.*_(.*[0-9]+)\-.*_(all|amd64).*/\1/g; s/[^0-9]//g')
  159. rpp_token=$(printf "%s,%d" "${rpp}" "${rpp_shortver}")
  160. remotePackagesAlt+=(["${rpp_token}"]="${rpp_url}")
  161. break 1
  162. fi
  163. done
  164. done
  165. # Posix-compliant MingW alternative executables
  166. #
  167. typeset -A alternatives
  168. alternatives=(
  169. [x86_64-w64-mingw32-gcc]="x86_64-w64-mingw32-gcc-posix"
  170. [x86_64-w64-mingw32-g++]="x86_64-w64-mingw32-g++-posix"
  171. [i686-w64-mingw32-gcc]="i686-w64-mingw32-gcc-posix"
  172. [i686-w64-mingw32-g++]="i686-w64-mingw32-g++-posix"
  173. )
  174. # Temporary symbolic links for DXVK compilation
  175. #
  176. typeset -A tempLinks
  177. tempLinks=(
  178. ['/usr/bin/i686-w64-mingw32-gcc']='/usr/bin/i686-w64-mingw32-gcc-posix'
  179. ['/usr/bin/i686-w64-mingw32-g++']='/usr/bin/i686-w64-mingw32-g++-posix'
  180. ['/usr/bin/x86_64-w64-mingw32-gcc']='x86_64-w64-mingw32-gcc-posix'
  181. ['/usr/bin/x86_64-w64-mingw32-g++']='x86_64-w64-mingw32-g++-posix'
  182. )
  183. ########################################################
  184. function runtimeCheck() {
  185. # Friendly name for this package
  186. local pkgreq_name=${1}
  187. # Known package names to check on Debian
  188. local known_pkgs=${2}
  189. # Check if any of these Wine packages are present on the system
  190. i=0
  191. for pkg in ${known_pkgs[@]}; do
  192. if [[ $(echo $(dpkg -s ${pkg} &>/dev/null)$?) -eq 0 ]]; then
  193. local pkglist[$i]=${pkg}
  194. let i++
  195. fi
  196. done
  197. if [[ -z ${pkglist[*]} ]]; then
  198. echo -e "\e[1mWARNING:\e[0m Not installing DXVK because \e[1m${pkgreq_name}\e[0m is missing on your system.\n\
  199. ${pkgreq_name} should be installed in order to use DXVK. Just compiling DXVK for later use.\n"
  200. # Do this check separately so we can warn about all missing runtime dependencies above
  201. if [[ ! -v NO_INSTALL ]]; then
  202. # Force --no-install switch
  203. NO_INSTALL=
  204. fi
  205. fi
  206. }
  207. ########################################################
  208. # If the script is interrupted (Ctrl+C/SIGINT), do the following
  209. function DXVK_intCleanup() {
  210. rm -rf ${DXVKROOT}/{dxvk-git,meson,glslang,*.deb}
  211. rm -rf ${DXVKROOT}/../compiled_deb/"${datedir}"
  212. exit 0
  213. }
  214. # Allow interruption of the script at any time (Ctrl + C)
  215. trap "DXVK_intCleanup" INT
  216. # Error event
  217. #trap "DXVK_intCleanup" ERR
  218. ########################################################
  219. # http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal
  220. function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; }
  221. ########################################################
  222. # Update all packages if UPDATE_OVERRIDE given
  223. if [[ -v UPDATE_OVERRIDE ]]; then
  224. echo -en "Updating all packages" && \
  225. if [[ $(printf $(sudo -n uptime &>/dev/null)$?) -ne 0 ]]; then printf " Please provide your sudo password.\n"; else printf "\n\n"; fi
  226. sudo apt update && sudo apt upgrade -y
  227. fi
  228. ########################################################
  229. # Check do we need to compile the package
  230. # given as input for this function
  231. function pkgcompilecheck() {
  232. local install_function=${1}
  233. local pkg=${2}
  234. local pkg_data=${3}
  235. if [[ $(echo $(dpkg -s ${pkg} &>/dev/null)$?) -ne 0 ]] || [[ -v UPDATE_OVERRIDE ]]; then
  236. ${install_function} ${pkg_data}
  237. fi
  238. }
  239. ########################################################
  240. # DXVK CUSTOM INSTALLATION HOOKS
  241. # These are custom installation instructions for DXVK
  242. # They are not used independently.
  243. function dxvk_install_custom() {
  244. local PATCHDIR="${1}"
  245. # Use posix alternates for MinGW binaries
  246. function dxvk_posixpkgs() {
  247. for alt in ${!alternatives[@]}; do
  248. echo "Linking MingW executable ${alt} to ${alternatives[$alt]}"
  249. sudo rm -rf /etc/alternatives/"${alt}" 2>/dev/null
  250. sudo ln -sf /usr/bin/"${alternatives[$alt]}" /etc/alternatives/"${alt}"
  251. if [[ $? -ne 0 ]]; then
  252. echo -e "\e[1mERROR:\e[0m Error occured while linking executable ${alt} to ${alternatives[$alt]}. Aborting\n"
  253. exit 1
  254. fi
  255. done
  256. for link in ${!tempLinks[@]}; do
  257. if [[ ! -f ${link} ]]; then
  258. echo "Creating temporary links for MingW executable ${link}"
  259. sudo ln -sf ${tempLinks["${link}"]} "${link}"
  260. if [[ $? -ne 0 ]]; then
  261. echo -e "\e[1mERROR:\e[0m Error occured while linking executable ${link}. Aborting\n"
  262. exit 1
  263. fi
  264. fi
  265. done
  266. }
  267. ############################
  268. # DXVK - CUSTOM PATCHES
  269. # Add and apply custom DXVK patches
  270. function dxvk_custompatches() {
  271. # Get our current directory, since we will change it during patching process below
  272. # We want to go back here after having applied the patches
  273. local CURDIR="${PWD}"
  274. # Check if the following folder exists, and proceed.
  275. if [[ -d "${DXVKROOT}/../../${PATCHDIR}" ]]; then
  276. cp -r "${DXVKROOT}/../../${PATCHDIR}/"*.{patch,diff} "${DXVKROOT}/${pkg_name}/" 2>/dev/null
  277. local dxvk_builddir_name=$(ls -l "${DXVKROOT}/${pkg_name}" | grep ^d | awk '{print $NF}')
  278. # TODO Expecting just one folder here. This method doesn't work with multiple dirs present
  279. if [[ $(echo ${dxvk_builddir_name} | wc -l) -gt 1 ]]; then
  280. echo -e "\e[1mERROR:\e[0m Multiple entries in dxvk build directory detected. Can't decide which one to use. Aborting\n"
  281. exit 1
  282. fi
  283. local dxvk_builddir_path="${DXVKROOT}/${pkg_name}/${dxvk_builddir_name}"
  284. cd "${dxvk_builddir_path}"
  285. for pfile in ../*.{patch,diff}; do
  286. if [[ -f ${pfile} ]]; then
  287. echo -e "Applying DXVK patch: ${pfile}\n"
  288. patch -Np1 < ${pfile}
  289. fi
  290. if [[ $? -ne 0 ]]; then
  291. echo -e "\e[1mERROR:\e[0m Error occured while applying DXVK patch '${pfile}'. Aborting\n"
  292. cd ${CURDIR}
  293. exit 1
  294. fi
  295. done
  296. cd "${CURDIR}"
  297. fi
  298. }
  299. ############################
  300. # DXVK - CUSTOM HOOKS EXECUTION
  301. dxvk_custompatches && \
  302. dxvk_posixpkgs
  303. }
  304. ########################################################
  305. # COMMON - COMPILE AND INSTALL DEB PACKAGE
  306. # Instructions to compile and install a deb package
  307. # on Debian system
  308. # Global variable to track buildtime dependencies
  309. z=0
  310. function compile_and_install_deb() {
  311. ############################
  312. # Set local variables
  313. local _pkg_name="${1}"
  314. local _pkg_license="${2}"
  315. local _pkg_giturl="${3}"
  316. local _pkg_gitbranch="${4}"
  317. local _git_commithash="${5}"
  318. local _pkg_gitver="${6}"
  319. local _pkg_debinstall="${7}"
  320. local _pkg_debcontrol="${8}"
  321. local _pkg_debrules="${9}"
  322. local _pkg_installfile="${10}"
  323. local _pkg_controlfile="${11}"
  324. local _pkg_rulesfile="${12}"
  325. local _pkg_deps_build="${13}"
  326. local _pkg_deps_runtime="${14}"
  327. local _pkg_debbuilder="${15}"
  328. local _pkg_debcompat="${16}"
  329. local _pkg_compatfile="${17}"
  330. ############################
  331. # COMMON - ARRAY PARAMETER FIX
  332. # Separate array indexes correctly
  333. # We have streamed all array indexes, separated
  334. # by | symbol. We reconstruct the arrays here.
  335. function arrayparser_reverse() {
  336. local arrays=(
  337. '_pkg_deps_build'
  338. '_pkg_deps_runtime'
  339. )
  340. for w in ${arrays[@]}; do
  341. local s=\${${w}}
  342. local IFS='|'
  343. local y=0
  344. for t in $(eval printf '%s\|' ${s}); do
  345. eval ${w}[$y]=\"${t}\"
  346. let y++
  347. done
  348. unset IFS
  349. done
  350. }
  351. arrayparser_reverse
  352. ############################
  353. function pkg_installcheck() {
  354. return $(echo $(dpkg -s "${1}" &>/dev/null)$?)
  355. }
  356. ############################
  357. echo -e "Starting compilation$(if [[ ! -v NO_INSTALL ]] || [[ ${_pkg_name} =~ ^meson|glslang$ ]]; then printf " & installation"; fi) of ${_pkg_name}\n"
  358. ############################
  359. # COMMON - PACKAGE DEPENDENCIES CHECK
  360. # Check and install package related dependencies if they are missing
  361. function pkg_dependencies() {
  362. local _pkg_list="${1}"
  363. local _pkg_type="${2}"
  364. local IFS=$'\n'
  365. _pkg_list=$(echo "${_pkg_list}" | sed 's/([^)]*)//g')
  366. unset IFS
  367. case ${_pkg_type} in
  368. buildtime)
  369. local _pkg_type_str="build time"
  370. ;;
  371. runtime)
  372. local _pkg_type_str="runtime"
  373. ;;
  374. esac
  375. if [[ ${_pkg_list[0]} == "empty" ]]; then
  376. return 0
  377. fi
  378. # Generate a list of missing dependencies
  379. local a=0
  380. for p in ${_pkg_list[@]}; do
  381. if [[ $(pkg_installcheck ${p})$? -eq 0 ]]; then
  382. local _validlist[$a]=${p}
  383. let a++
  384. # Global array to track installed build dependencies
  385. if [[ ${_pkg_type} == "buildtime" ]]; then
  386. _buildpkglist[$z]="${p}"
  387. let z++
  388. fi
  389. fi
  390. done
  391. function pkg_remoteinstall() {
  392. sudo apt install -y ${1} &> /dev/null
  393. }
  394. function pkg_localinstall() {
  395. wget ${1} -O ${DXVKROOT}/"${2}".deb
  396. sudo dpkg -i --force-all ${DXVKROOT}/"${2}".deb
  397. }
  398. function pkg_configure() {
  399. if [[ $(sudo dpkg-reconfigure ${1} | grep "is broken or not fully installed") ]]; then
  400. if [[ -v ${2} ]]; then
  401. pkg_localinstall ${2} ${1}
  402. else
  403. pkg_remoteinstall ${1}
  404. fi
  405. fi
  406. }
  407. # Install missing dependencies, be informative
  408. local b=0
  409. for _pkg_dep in ${_validlist[@]}; do
  410. echo -e "$(( $b + 1 ))/$(( ${#_validlist[*]} )) - Installing ${_pkg_name} ${_pkg_type_str} dependency ${_pkg_dep}"
  411. if [[ ${#remotePackagesAlt[@]} -gt 0 ]]; then
  412. for altRemote in ${!remotePackagesAlt[@]}; do
  413. altRemotepkg=$(echo ${altRemote} | awk -F ',' '{print $1}')
  414. altRemotever=$(echo ${altRemote} | awk -F ',' '{print $2}')
  415. if [[ "${_pkg_dep}" == "${altRemotepkg}" ]]; then
  416. if [[ $(pkg_installcheck ${altRemotepkg})$? -ne 0 ]]; then
  417. # TODO remove duplicate functionality
  418. if [[ $(apt-cache show "${altRemotepkg}" | grep -m1 -oP "(?<=^Version: )[0-9|\.]*" | sed 's/\.//g') < ${altRemotever} ]]; then
  419. pkg_localinstall ${remotePackagesAlt["${altRemote}"]} "${altRemotepkg}"
  420. pkg_configure "${altRemotepkg}" ${remotePackagesAlt["${altRemote}"]}
  421. else
  422. pkg_remoteinstall "${altRemotepkg}"
  423. pkg_configure "${altRemotepkg}"
  424. fi
  425. else
  426. if [[ $(dpkg -s "${altRemotepkg}" | grep -m1 -oP "(?<=^Version: )[0-9|\.]*" | sed 's/\.//g') < ${altRemotever} ]]; then
  427. pkg_localinstall ${remotePackagesAlt["${altRemote}"]} "${altRemotepkg}"
  428. pkg_configure "${altRemotepkg}" ${remotePackagesAlt["${altRemote}"]}
  429. else
  430. pkg_remoteinstall "${altRemotepkg}"
  431. pkg_configure "${altRemotepkg}"
  432. fi
  433. fi
  434. fi
  435. done
  436. fi
  437. if [[ $(pkg_installcheck ${_pkg_dep})$? -ne 0 ]]; then
  438. pkg_remoteinstall "${_pkg_dep}"
  439. pkg_configure "${_pkg_dep}"
  440. fi
  441. if [[ $? -eq 0 ]]; then
  442. let b++
  443. else
  444. echo -e "\n\e[1mERROR:\e[0m Error occured while installing ${_pkg_dep}. Aborting.\n"
  445. exit 1
  446. fi
  447. done
  448. if [[ -n ${_validlist[*]} ]]; then
  449. # Add empty newline
  450. echo ""
  451. fi
  452. }
  453. ############################
  454. # COMMON - RETRIEVE PACKAGE
  455. # GIT VERSION TAG
  456. # Get git-based version in order to rename the package main folder
  457. # This is required by deb builder. It retrieves the version number
  458. # from that folder name
  459. function pkg_gitversion() {
  460. if [[ -n "${_pkg_gitver}" ]] && [[ "${_pkg_gitver}" =~ ^git ]]; then
  461. cd ${_pkg_name}
  462. git checkout ${_pkg_gitbranch}
  463. git reset --hard ${_git_commithash}
  464. if [[ $? -ne 0 ]]; then
  465. echo -e "\e[1mERROR:\e[0m Couldn't find commit ${_git_commithash} for ${_pkg_name}. Aborting\n"
  466. exit 1
  467. fi
  468. _pkg_gitver=$(eval "${_pkg_gitver}")
  469. cd ..
  470. fi
  471. }
  472. ############################
  473. # COMMON - OVERWRITE
  474. # DEBIAN BUILD ENV FILES
  475. # Overwrite a file which is given as user input
  476. # The contents are supplied as input, too.
  477. function pkg_override_debianfile() {
  478. local contents=${1}
  479. local targetfile=${2}
  480. if [[ ${contents} != "empty" ]]; then
  481. echo "${contents}" > "${targetfile}"
  482. if [[ $? -ne 0 ]]; then
  483. echo -e "\e[1mERROR:\e[0m Couldn't create Debian file '${targetfile}' for ${_pkg_name}. Aborting\n"
  484. exit 1
  485. fi
  486. fi
  487. }
  488. ############################
  489. # COMMON - GET SOURCE AND
  490. # PREPARE SOURCE FOLDER
  491. function pkg_folderprepare() {
  492. # Remove old build directory, if present
  493. rm -rf ${_pkg_name}
  494. # Create a new build directory, access it and download git sources there
  495. mkdir ${_pkg_name}
  496. cd ${_pkg_name}
  497. echo -e "Retrieving source code of ${_pkg_name} from $(printf ${_pkg_giturl} | sed 's/^.*\/\///; s/\/.*//')\n"
  498. git clone ${_pkg_giturl} ${_pkg_name}
  499. # If sources could be downloaded, rename the folder properly for deb builder
  500. # Access the folder after which package specific debianbuild function will be run
  501. # That function is defined inside package specific install_main function below
  502. if [[ $? -eq 0 ]]; then
  503. pkg_gitversion && \
  504. mv ${_pkg_name} ${_pkg_name}-${_pkg_gitver}
  505. cd ${_pkg_name}-${_pkg_gitver}
  506. dh_make --createorig -s -y -c ${_pkg_license} && \
  507. pkg_override_debianfile "${_pkg_debinstall}" "${_pkg_installfile}"
  508. pkg_override_debianfile "${_pkg_debcontrol}" "${_pkg_controlfile}"
  509. pkg_override_debianfile "${_pkg_debrules}" "${_pkg_rulesfile}"
  510. pkg_override_debianfile "${_pkg_debcompat}" "${_pkg_compatfile}"
  511. else
  512. echo -e "\e[1mERROR:\e[0m Error while downloading source of ${_pkg_name} package. Aborting\n"
  513. exit 1
  514. fi
  515. }
  516. ############################
  517. # COMMON - COMPILE, INSTALL
  518. # AND STORE DEB PACKAGE
  519. function pkg_debianbuild() {
  520. # Start deb builder
  521. bash -c "${_pkg_debbuilder}"
  522. # Once our deb package is compiled, install and store it
  523. # We do not make installation optional for deps because they are required by DXVK
  524. if [[ $? -eq 0 ]]; then
  525. rm -rf ../*.{changes,buildinfo,tar.xz}
  526. if [[ "${_pkg_name}" == *"dxvk"* ]] && [[ ! -v NO_INSTALL ]]; then
  527. sudo dpkg -i ../${_pkg_name}*.deb
  528. elif [[ "${_pkg_name}" != *"dxvk"* ]]; then
  529. sudo dpkg -i ../${_pkg_name}*.deb
  530. fi
  531. mv ../${_pkg_name}*.deb ../../../compiled_deb/"${datedir}" && \
  532. echo -e "Compiled ${_pkg_name} is stored at '$(readlink -f ../../../compiled_deb/"${datedir}")/'\n"
  533. cd ../..
  534. rm -rf {${_pkg_name},*.deb}
  535. else
  536. buildpkg_removal
  537. exit 1
  538. fi
  539. }
  540. ############################
  541. # COMMON - EXECUTION HOOKS
  542. pkg_dependencies "${_pkg_deps_build[*]}" buildtime
  543. if [[ ${_pkg_deps_runtime[0]} != "empty" ]] && [[ ! -v NO_INSTALL ]]; then
  544. pkg_dependencies "${_pkg_deps_runtime[*]}" runtime
  545. fi
  546. pkg_folderprepare
  547. # TODO use package name or separate override switch here?
  548. if [[ "${_pkg_name}" == *"dxvk"* ]]; then
  549. dxvk_install_custom "dxvk_custom_patches"
  550. fi
  551. pkg_debianbuild
  552. unset _pkg_gitver
  553. }
  554. ########################################################
  555. # BUILD DEPENDENCIES REMOVAL
  556. function buildpkg_removal() {
  557. _buildpkglist=($(echo ${_buildpkglist[@]} | tr ' ' '\n' |sort -u | tr '\n' ' '))
  558. for link in ${!tempLinks[@]}; do
  559. if [[ $(file ${link}) == *"symbolic link"* ]]; then
  560. sudo rm -f "${link}"
  561. fi
  562. done
  563. # Build time dependencies which were installed but no longer needed
  564. if [[ -v _buildpkglist ]]; then
  565. if [[ -v BUILDPKG_RM ]]; then
  566. sudo apt purge --remove -y ${_buildpkglist[*]}
  567. # In some cases, glslang or meson may still be present on the system. Remove them
  568. for _extrapkg in glslang meson; do
  569. if [[ $(echo $(dpkg -s ${_extrapkg} &>/dev/null)$?) -eq 0 ]]; then
  570. sudo dpkg --remove --force-remove-reinstreq ${_extrapkg}
  571. fi
  572. done
  573. # Manually obtained deb packages are expected to break system configuration, thus we need to fix it.
  574. sudo apt --fix-broken -y install
  575. else
  576. echo -e "The following build time dependencies were installed and no longer needed:\n\n$(for l in ${_buildpkglist[*]}; do echo -e ${l}; done)\n"
  577. fi
  578. fi
  579. }
  580. ########################################################
  581. # Package installation instructions
  582. function pkg_install_main() {
  583. # Read necessary variables from debdata file
  584. local pkg_datafile=${1}
  585. if [[ -f ${pkg_datafile} ]]; then
  586. source ${pkg_datafile}
  587. else
  588. echo -e "\e[1mERROR:\e[0m Couldn't read datafile '${pkg_datafile}'. Check the file path and try again.\n"
  589. exit 1
  590. fi
  591. ############################
  592. # Prepare these arrays for 'compile_and_install_deb' input
  593. # Separate each array index with | in these arrays
  594. function pkg_arrayparser() {
  595. local pkg_arrays=(
  596. 'pkg_deps_build'
  597. 'pkg_deps_runtime'
  598. )
  599. local IFS=$'\n'
  600. for w in ${pkg_arrays[@]}; do
  601. local s=\${${w}[@]}
  602. local t=$(eval printf '%s\|' ${s})
  603. unset ${w}
  604. eval ${w}=\"${t}\"
  605. done
  606. }
  607. ############################
  608. # Execute package installation procedure
  609. pkg_arrayparser && \
  610. compile_and_install_deb \
  611. "${pkg_name}" \
  612. "${pkg_license}" \
  613. "${pkg_giturl}" \
  614. "${pkg_gitbranch}" \
  615. "${git_commithash}" \
  616. "${pkg_gitver}" \
  617. "${pkg_debinstall}" \
  618. "${pkg_debcontrol}" \
  619. "${pkg_debrules}" \
  620. "${pkg_installfile}" \
  621. "${pkg_controlfile}" \
  622. "${pkg_rulesfile}" \
  623. "${pkg_deps_build}" \
  624. "${pkg_deps_runtime}" \
  625. "${pkg_debbuilder}" \
  626. "${pkg_debcompat}" \
  627. "${pkg_compatfile}"
  628. }
  629. ########################################################
  630. # Check existence of known Wine packages
  631. runtimeCheck Wine "${known_wines[*]}"
  632. # Meson - compile (& install)
  633. pkgcompilecheck pkg_install_main meson "${DXVKROOT}/meson.debdata"
  634. # Glslang - compile (& install)
  635. pkgcompilecheck pkg_install_main glslang "${DXVKROOT}/glslang.debdata"
  636. if [[ ! -v NO_DXVK ]]; then
  637. # DXVK - compile (& install)
  638. pkg_install_main "${DXVKROOT}/dxvk.debdata"
  639. fi
  640. # Clean buildtime dependencies
  641. buildpkg_removal