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.

571 lines
15 KiB

  1. #!/bin/env bash
  2. # Compile latest Nvidia drivers on a Debian-based Linux
  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. # 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. BUILD_MAINDIR=${PWD}/debian_nvidia
  29. ########################################################
  30. _pkgname="nvidia"
  31. arch="x86_64"
  32. pkgver=396.54
  33. files=(
  34. "http://archive.ubuntu.com/ubuntu/pool/restricted/n/nvidia-graphics-drivers-390/nvidia-graphics-drivers-390_390.48-0ubuntu3.debian.tar.xz"
  35. "http://us.download.nvidia.com/XFree86/Linux-${arch}/${pkgver}/NVIDIA-Linux-${arch}-${pkgver}.run"
  36. )
  37. ###################
  38. pkgver_major=$(printf '%s' ${pkgver} | grep -oE "^[0-9]+[^.]")
  39. pkgdir="nvidia-graphics-drivers-${pkgver_major}_${pkgver}"
  40. typeset -A library_fixes
  41. ###################
  42. # From time to time, bundled library version numbers change
  43. # in Nvidia driver packages. Update library version if needed
  44. #
  45. # Left side: old library version
  46. # Right side: new library version
  47. #
  48. library_fixes=(
  49. [libnvidia-egl-wayland.so.1.0.2]="libnvidia-egl-wayland.so.1.0.3"
  50. )
  51. ###################
  52. # These are defined build dependencies in debian/control file
  53. nvidia_builddeps=(
  54. 'dpkg-dev'
  55. 'xz-utils'
  56. 'dkms'
  57. 'libwayland-client0'
  58. 'libwayland-server0'
  59. 'libxext6'
  60. 'quilt'
  61. 'po-debconf'
  62. 'execstack'
  63. 'dh-modaliases'
  64. 'xserver-xorg-dev'
  65. 'libglvnd-dev'
  66. )
  67. ###################
  68. # These packages are required by the compiled Nvidia packages
  69. nvidia_required_packages=(
  70. # Required by libnvidia-gl
  71. "libwayland-client0"
  72. "libwayland-server0"
  73. # Required by libnvidia, libnvidia-decode & libnvidia-fbc1
  74. "libx11-6"
  75. # Required by libnvidia, libnvidia-decode, libnvidia-fbc1 & libnvidia-ifr1
  76. "libxext6"
  77. # Required by libnvidia-fbc1 & libnvidia-ifr1
  78. "libgl1"
  79. # Required by xserver-xorg-video-nvidia
  80. "xserver-xorg-core"
  81. "xorg-video-abi-23"
  82. # Required by nvidia-compute-utils
  83. "adduser"
  84. )
  85. ###################
  86. # Nvidia packages. THIS ORDER IS MANDATORY, DO NOT CHANGE!
  87. nvidia_install_packages=(
  88. # Similar than 'nvidia-dkms' package on Arch Linux
  89. "nvidia-kernel-source-${pkgver_major}"
  90. # Nvidia DKMS
  91. "nvidia-kernel-common-${pkgver_major}"
  92. "nvidia-dkms-${pkgver_major}"
  93. # Similar than 'nvidia-utils' package on Arch Linux
  94. "libnvidia-common-${pkgver_major}"
  95. "libnvidia-gl-${pkgver_major}"
  96. "libnvidia-cfg1-${pkgver_major}"
  97. "xserver-xorg-video-nvidia-${pkgver_major}"
  98. "libnvidia-compute-${pkgver_major}"
  99. "libnvidia-decode-${pkgver_major}"
  100. "libnvidia-encode-${pkgver_major}"
  101. "libnvidia-fbc1-${pkgver_major}"
  102. "libnvidia-ifr1-${pkgver_major}"
  103. "nvidia-compute-utils-${pkgver_major}"
  104. "nvidia-utils-${pkgver_major}"
  105. )
  106. ########################################################
  107. pkgver_sed=$(printf '%s' ${pkgver} | sed 's/\./\\\./')
  108. i=0
  109. for f in ${files[@]}; do
  110. file_basename=$(printf '%s' ${f} | awk -F / '{print $NF}')
  111. filebases[$i]=${file_basename}
  112. let i++
  113. done
  114. oldver=$(printf '%s' ${filebases[0]} | grep -oE "[0-9]{3}\.[0-9]{2}" | head -1)
  115. oldver_major=$(printf '%s' ${filebases[0]} | grep -oE "[0-9]{3}" | head -1)
  116. oldver_sed=$(printf '%s' ${oldver} | sed 's/\./\\\./')
  117. ########################################################
  118. # http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal
  119. function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; }
  120. ###########################################################
  121. # Just a title & author for this script, used in initialization and help page
  122. SCRIPT_TITLE="\e[1mNvidia drivers package builder & installer\e[0m"
  123. SCRIPT_AUTHOR="Pekka Helenius (~Fincer), 2018"
  124. echo -e "\n${SCRIPT_TITLE}\n"
  125. ########################################################
  126. echo -e "Selected driver version:\t${pkgver}\n"
  127. INFO_SEP
  128. ########################################################
  129. mkdir -p ${BUILD_MAINDIR}
  130. if [[ $? -eq 0 ]]; then
  131. cd ${BUILD_MAINDIR}
  132. WORKDIR=${PWD}
  133. else
  134. echo -e "Error: couldn't create Nvidia build directory. Aborting\n"
  135. exit 1
  136. fi
  137. ########################################################
  138. # If the script is interrupted (Ctrl+C/SIGINT), do the following
  139. function Nvidia_intCleanup() {
  140. rm -rf ${WORKDIR}/{${pkgdir}/{debian,NVIDIA-Linux,NVIDIA-Linux-amd64,NVIDIA-Linux-x86_64-${pkgver},LICENSE.txt,unpack-stamp},compiled_deb,compiled_other}
  141. exit 0
  142. }
  143. # Allow interruption of the script at any time (Ctrl + C)
  144. trap "Nvidia_intCleanup" INT
  145. ###########################################################
  146. # Remove old build files
  147. rm -rf ${WORKDIR}/{${pkgdir}/{debian,NVIDIA-Linux,NVIDIA-Linux-amd64,NVIDIA-Linux-x86_64-${pkgver},LICENSE.txt,unpack-stamp},compiled_deb,compiled_other}
  148. ###########################################################
  149. COMMANDS=(
  150. sudo
  151. wget
  152. apt
  153. grep
  154. wc
  155. )
  156. function checkCommands() {
  157. if [[ $(which --help 2>/dev/null) ]] && [[ $(echo --help 2>/dev/null) ]]; then
  158. local a=0
  159. for command in ${@}; do
  160. if [[ ! $(which $command 2>/dev/null) ]]; then
  161. local COMMANDS_NOTFOUND[$a]=${command}
  162. let a++
  163. fi
  164. done
  165. if [[ -n $COMMANDS_NOTFOUND ]]; then
  166. echo -e "\nError! The following commands could not be found: ${COMMANDS_NOTFOUND[*]}\nAborting\n"
  167. exit 1
  168. fi
  169. else
  170. exit 1
  171. fi
  172. }
  173. checkCommands "${COMMANDS[*]}"
  174. ########################################################
  175. # General function for question responses
  176. function questionresponse() {
  177. local response=${1}
  178. read -r -p "" response
  179. if [[ $(echo $response | sed 's/ //g') =~ ^([yY][eE][sS]|[yY])$ ]]; then
  180. echo ""
  181. return 0
  182. else
  183. return 1
  184. fi
  185. }
  186. ########################################################
  187. # Premilinary check for already compiled packages
  188. if [[ $(ls ${WORKDIR}/*.deb 2>/dev/null | wc -l) -ne 0 ]]; then
  189. echo -e "\nWarning: previously compiled deb archives found on the main build directory '${WORKDIR}'.\nDelete them and continue? [Y/n]"
  190. questionresponse
  191. fi
  192. if [[ $? -ne 0 ]]; then
  193. echo -e "Cancelling.\n"
  194. exit 1
  195. else
  196. rm -rv ${WORKDIR}/*.{deb,buildinfo,changes} 2>/dev/null
  197. fi
  198. ########################################################
  199. # Premilinary check to see whether Nvidia card is present
  200. if [[ ! $(lspci | grep -oiE "vga.*nvidia") ]]; then
  201. echo -e "\nWarning: Nvidia card could not be detected on your system. Continue anyway? [Y/n]"
  202. questionresponse
  203. fi
  204. if [[ $? -ne 0 ]]; then
  205. echo -e "Cancelling.\n"
  206. exit 1
  207. fi
  208. ########################################################
  209. # Premilinary check to see whether Nvidia card is present
  210. echo -e "\nAuto-install Nvidia drivers after compilation? [Y/n]"
  211. questionresponse
  212. if [[ $? -eq 0 ]]; then
  213. if [[ ${UID} -ne 0 ]]; then
  214. if [[ $(echo $(sudo -vn &>/dev/null)$?) -ne 0 ]]; then
  215. echo -e "Installation requires root permissions. Please provide your sudo password now.\n"
  216. sudo -v
  217. fi
  218. if [[ $? -eq 0 ]]; then
  219. AUTOINSTALL=
  220. else
  221. exit 1
  222. fi
  223. else
  224. AUTOINSTALL=
  225. fi
  226. fi
  227. ########################################################
  228. # Check and install package related dependencies if they are missing
  229. function pkgdependencies() {
  230. # Generate a list of missing dependencies
  231. local a=0
  232. for p in ${@}; do
  233. if [[ $(apt version ${p} | wc -w) -eq 0 ]]; then
  234. list[$a]=${p}
  235. let a++
  236. fi
  237. done
  238. if [[ -n ${list[*]} ]]; then
  239. echo -e "Some build time dependencies are missing. In order to continue, you must install them."
  240. if [[ ${UID} -ne 0 ]] && [[ $(echo $(sudo -vn &>/dev/null)$?) -ne 0 ]]; then
  241. echo -e "For that, sudo password is required. Please provide it now.\n"
  242. sudo -v
  243. if [[ $? -ne 0 ]]; then
  244. echo -e "Error: couldn't continue due to lacking permissions. Aborting\n"
  245. exit 1
  246. fi
  247. fi
  248. fi
  249. # Install missing dependencies, be informative
  250. local b=0
  251. for pkgdep in ${list[@]}; do
  252. echo -e "Installing ${_pkgname} dependency ${pkgdep} ($(( $b + 1 )) / $(( ${#list[*]} ))).\n"
  253. sudo apt install -y ${pkgdep} &> /dev/null
  254. if [[ $? -eq 0 ]]; then
  255. let b++
  256. else
  257. echo -e "\nError occured while installing ${pkgdep}. Aborting.\n"
  258. exit 1
  259. fi
  260. done
  261. }
  262. ########################################################
  263. function download_files() {
  264. mkdir -p ${WORKDIR}/${pkgdir}
  265. i=0
  266. for f in ${files[@]}; do
  267. if [[ ! -f ${WORKDIR}/${pkgdir}/${filebases[$i]} ]]; then
  268. echo -e "\nDownloading ${filebases[$i]}"
  269. wget ${f} -o /dev/null --show-progress -O "${WORKDIR}/${pkgdir}/${filebases[$i]}"
  270. if [[ $? -ne 0 ]];then
  271. echo -e "Error: couldn't retrieve file ${filebases[$i]}. Aborting\n"
  272. exit 1
  273. fi
  274. fi
  275. let i++
  276. done
  277. }
  278. ########################################################
  279. function prepare_deb_sources() {
  280. # Extract debian control files
  281. cd ${WORKDIR}/${pkgdir}/
  282. tar xf ${filebases[0]}
  283. if [[ $? -eq 0 ]]; then
  284. function fix_library_versions() {
  285. for oldlib in ${!library_fixes[@]}; do
  286. # sed-friendly name
  287. local oldlib_sed=$(printf '%s' ${oldlib} | sed 's/\./\\\./g')
  288. for lib in ${library_fixes[$oldlib]}; do
  289. # sed-friendly name
  290. local lib_sed=$(printf '%s' ${lib} | sed 's/\./\\\./g')
  291. # Files which have old library files mentioned
  292. local i=0
  293. for oldlib_file in $(grep -rl "${oldlib}" debian/ | tr '\n' ' '); do
  294. local oldlib_files[$i]=${oldlib_file}
  295. let i++
  296. done
  297. for targetfile in ${oldlib_files[@]}; do
  298. sed -i "s/${oldlib_sed}/${lib_sed}/g" ${targetfile}
  299. done
  300. done
  301. done
  302. }
  303. function rename_deb_files() {
  304. # Remove this suffix
  305. sed -i 's/\-no\-compat32//' debian/rules.defs
  306. # Tell that Nvidia .run file is at our build root, not in amd64 subfolder
  307. sed -i 's|sh \$\*\/\${NVIDIA_FILENAME_\$\*}|sh \${NVIDIA_FILENAME_\$\*}|' debian/rules
  308. ############
  309. # TODO Individual fix for strange version number present in debian control files
  310. # Remove when not needed!
  311. sed -i "s/384/${pkgver_major}/g" debian/control
  312. sed -i "s/384/${pkgver_major}/g" debian/templates/control.in
  313. ############
  314. local IFS=$'\n'
  315. for n in $(ls debian/ -w 1); do
  316. # IMPORTANT! KEEP THIS IF STATEMENT ORDER BELOW!!
  317. # Do this for every file in debian subfolder regardless of their name
  318. if [[ -f debian/${n} ]]; then
  319. # Keep this order. It is important!
  320. sed -i "s/${oldver_sed}/${pkgver_sed}/g" debian/${n}
  321. sed -i "s/${oldver_major}/${pkgver_major}/g" debian/${n}
  322. fi
  323. if [[ $(printf '%s' ${n} | grep ${oldver_major}) ]]; then
  324. local n_new=$(printf '%s' ${n} | sed "s/${oldver_major}/${pkgver_major}/")
  325. mv debian/${n} debian/${n_new}
  326. if [[ $? -ne 0 ]]; then
  327. echo -e "Error: couldn't rename file debian/${n}. Aborting\n"
  328. exit 1
  329. fi
  330. fi
  331. done
  332. unset IFS
  333. }
  334. fix_library_versions
  335. rename_deb_files
  336. else
  337. echo -e "Error: couldn't extract Nvidia Debian archive. Aborting\n"
  338. exit 1
  339. fi
  340. }
  341. ########################################################
  342. function compile_nvidia() {
  343. cd ${WORKDIR}/${pkgdir}/
  344. DEB_BUILD_OPTIONS="strip noddebs" dpkg-buildpackage -rfakeroot -b -us -uc
  345. if [[ $? -eq 0 ]]; then
  346. mkdir -p ${WORKDIR}/compiled_deb
  347. for p in ${nvidia_install_packages[*]}; do
  348. mv ${WORKDIR}/${p}*.deb ${WORKDIR}/compiled_deb/
  349. done
  350. if [[ $? -eq 0 ]]; then
  351. echo -e "Compiled deb packages moved into '${WORKDIR}/compiled_deb/'. Install these to enable Nvidia support.\nAdditionally, you may need Vulkan loader package 'libvulkan1', too.\n"
  352. else
  353. echo -e "Error: couldn't move deb packages into '${WORKDIR}/compiled_deb/'. Aborting\n"
  354. exit 1
  355. fi
  356. mkdir -p ${WORKDIR}/compiled_other
  357. for a in ${WORKDIR}/*; do
  358. if [[ -f ${a} ]]; then
  359. mv ${a} ${WORKDIR}/compiled_other/
  360. fi
  361. done
  362. if [[ $? -eq 0 ]]; then
  363. echo -e "Other files moved into '${WORKDIR}/compiled_other/' \n"
  364. else
  365. echo -e "Error: couldn't move other files into '${WORKDIR}/compiled_other/'. Aborting\n"
  366. exit 1
  367. fi
  368. else
  369. echo -e "Error: couldn't compile Nvidia package bundle. Aborting\n"
  370. exit 1
  371. fi
  372. }
  373. ########################################################
  374. function install_nvidia() {
  375. for syspkg in ${nvidia_required_packages[@]}; do
  376. if [[ $(apt version ${syspkg} | wc -w) -eq 0 ]]; then
  377. echo -e "Installing missing dependency ${syspkg}\n"
  378. sudo apt install -y ${syspkg}
  379. if [[ $? -ne 0 ]]; then
  380. echo -e "Error: couldn't install dependency ${syspkg}. Aborting\n"
  381. exit 1
  382. fi
  383. fi
  384. done
  385. cd ${WORKDIR}/compiled_deb
  386. for pkg in ${nvidia_install_packages[@]}; do
  387. local oldpkg=$(printf '%s' ${pkg} | sed 's/\-[0-9]*$//')
  388. local oldpkg_check=$(dpkg --get-selections | grep ${oldpkg} | awk '{print $1}')
  389. if [[ $(echo ${oldpkg_check} | wc -w) -eq 1 ]]; then
  390. if [[ ! ${oldpkg_check} =~ ^*${pkgver_major}$ ]]; then
  391. echo -e "Removing old ${oldpkg}\n"
  392. sudo apt purge --remove -y "${oldpkg}*"
  393. if [[ $? -ne 0 ]]; then
  394. echo -e "Error: couldn't uninstall ${oldpkg}. Aborting\n"
  395. exit 1
  396. fi
  397. fi
  398. fi
  399. echo -e "Installing ${pkg}\n"
  400. sudo dpkg -i ${pkg}*.deb
  401. if [[ $? -ne 0 ]]; then
  402. echo -e "Warning: couldn't install ${pkg}\n"
  403. fi
  404. done
  405. }
  406. function install_vulkan() {
  407. # Vulkan loader
  408. if [[ $? -eq 0 ]]; then
  409. local syspkg=libvulkan1
  410. if [[ $(apt version ${syspkg} | wc -w) -eq 0 ]]; then
  411. sudo apt update && sudo apt install -y ${syspkg}
  412. fi
  413. fi
  414. }
  415. ########################################################
  416. download_files && \
  417. pkgdependencies ${nvidia_builddeps[*]}
  418. prepare_deb_sources && \
  419. compile_nvidia
  420. if [[ $? -eq 0 ]] && [[ -v AUTOINSTALL ]]; then
  421. install_nvidia && \
  422. install_vulkan
  423. fi
  424. # If any buildtime deps were installed, inform the user
  425. if [[ -n ${list[*]} ]]; then
  426. echo -e "The following buildtime dependencies were installed, and they may not be required anymore:\n\n\
  427. $(for h in ${list[*]}; do echo ${h}; done)\n"
  428. fi