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.

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