From 9617f0e8d3d04d1e6de210f772ba6d3a23c12730 Mon Sep 17 00:00:00 2001 From: Fincer Date: Sat, 17 Nov 2018 13:13:39 +0200 Subject: [PATCH] Add commit freeze option; implement Winetricks (Debian); other major improvements --- README.md | 86 +++++++-- arch/0-dxvk-git/PKGBUILD | 2 +- arch/0-wine-staging-git/PKGBUILD | 16 +- arch/updatewine_arch.sh | 191 +++++++++++++++++-- debian/dxvkroot/dxvkbuild.sh | 86 ++++++--- debian/updatewine_debian.sh | 232 +++++++++++++++++++++-- debian/wineroot/winebuild.sh | 225 ++++++++++++++++++---- debian_install_nvidia.sh | 2 +- debian_install_winetricks.sh | 313 +++++++++++++++++++++++++++++++ updatewine.sh | 85 +++++++-- 10 files changed, 1116 insertions(+), 122 deletions(-) mode change 100644 => 100755 README.md create mode 100755 debian_install_winetricks.sh diff --git a/README.md b/README.md old mode 100644 new mode 100755 index e349776..ad0c095 --- a/README.md +++ b/README.md @@ -4,15 +4,19 @@ Boost up your Wine experience with a taste of DXVK and automate installation of [DXVK](https://github.com/doitsujin/dxvk) + [Wine](https://www.winehq.org/)/[Wine Staging](https://github.com/wine-staging/wine-staging/) on Debian/Ubuntu/Mint/Arch Linux/Manjaro. Additionally, update your GPU drivers + PlayonLinux wineprefixes to use the latest Wine & DXVK combination available. +![](https://i.imgur.com/Tqqi7pm.png) + +_Wine Staging 3.20, DXVK and winetricks on Debian 9. Normally, winetricks & DXVK are not available, and Wine is set to very old version 1.8.7 on Debian - leaving all the sweet candies out. Not anymore - let's end this misery and give user finally a choice._ + ## About -One-click solution for accessing bleeding-edge Wine/Wine Staging & DXVK packages _system-widely_ on Debian/Ubuntu/Mint and on Arch Linux/Manjaro. +One-click solution for accessing bleeding-edge Wine/Wine Staging & DXVK packages _system-widely_ on Debian/Ubuntu/Mint and on Arch Linux/Manjaro. Alternatively, you can pick any version of Wine/Wine Staging & DXVK to be used. ## Motivation -**Accessibility, lower the barrier.** Help people to get their hands on the latest bleeding-edge Wine/Wine Staging & DXVK software on major Linux distribution platforms without hassle or headaches. +**Accessibility, lower the barrier.** Help people to get their hands on the latest (bleeding-edge) Wine/Wine Staging & DXVK software on major Linux distribution platforms without hassle or headaches. -There is not an easy way to auto-install bleeding-edge Wine/Wine Staging & DXVK, especially on Debian/Ubuntu/Mint. The newest Wine/Wine Staging is not easily accessible on Debian-based Linux distributions, and DXVK is practically bundled to Lutris or Steam gaming platform as a form of Proton. However, not all Windows programs, like MS Office or Adobe Photoshop, could run under Linux Steam client: Many Windows programs actually rely on system-wide Wine installation which is why system-wide Wine/Wine Staging & DXVK auto-installation this script offers becomes quite handy. +There is not an easy way to auto-install the latest Wine/Wine Staging & DXVK, especially on Debian/Ubuntu/Mint. The newest Wine/Wine Staging is not easily accessible on Debian-based Linux distributions, and DXVK is practically bundled to Lutris or Steam gaming platform as a form of Proton. However, not all Windows programs, like MS Office or Adobe Photoshop, could run under Linux Steam client: Many Windows programs actually rely on system-wide Wine installation which is why system-wide Wine/Wine Staging & DXVK auto-installation this script offers becomes quite handy. The solution provided here _is independent from Steam client or any other Wine management platform_. The latest Wine/Wine Staging & DXVK bundle will be accessible system-widely, not just via Steam, Lutris or PlayOnLinux. Provided PlayOnLinux prefix update is optional, as well. @@ -28,9 +32,11 @@ With the helper script, you can set launch options for a single game/selected gr ## Contents -- **Wine/Wine Staging & DXVK:** Install script for supported Linux distributions +- **Wine/Wine Staging & DXVK:** Installation script for supported Linux distributions + +- **Nvidia drivers:** Installation script for supported Debian-based distributions. Independent script. -- **Nvidia drivers:** Install script for supported Debian-based distributions +- **Winetricks install** Installation script for supported Debian-based distributions. Can be run independently. - **Patches:** Possibility to use your custom patches with Wine & DXVK @@ -98,6 +104,48 @@ All supported arguments are: - `--no-pol` = Do not update current user's PlayOnLinux Wine prefixes +- `--no-winetricks` = [Debian only] Do not compile or install Winetricks. No DXVK installation unless Winetricks already installed. + +### Force/Lock package versions + +You can force/lock specific Wine, Wine Staging, DXVK, meson & glslang versions. + +This is handy if you encounter issues during package compilation (DXVK/glslang or meson, for instance). yYou should consider forcing package versions by defining a the latest git commit which still works for you. You can do this by specifying the following variables in `updatewine.sh`: + +- `git_commithash_dxvk`, `git_commithash_wine`, `git_commithash_glslang`, `git_commithash_meson` + +**These settings apply only on Debian/Ubuntu/Mint:** + +- git_commithash_glslang + +- git_commithash_meson + +### Force/Lock package versions: How-to + +Take a look on `updatewine.sh`. You can find above variables listed there. + +Each variable applies values which must be match package git commit tree. The value format is as follows: + +- A) 40 characters long commit hash. Use this if you want this commit to be the latest to be used in package compilation, not anything after it. + + - defined in git commit tree: [DXVK commit tree](https://github.com/doitsujin/dxvk/commits/master), [Wine commit tree](https://source.winehq.org/git/wine.git/) (or [GitHub mirror](https://github.com/wine-mirror/wine)), [glslang commit tree](https://github.com/KhronosGroup/glslang/commits/master), [meson commit tree](https://github.com/mesonbuild/meson/commits/master) + + - You can obtain proper hash by opening the commit. Hash syntax is: `654544e96bfcd1bbaf4a0fc639ef655299276a39` etc... + +- B) keyword `HEAD`. This defined the specific package to use the latest commit available on repository (read: this is bleeding-edge version of the package) + +Version freezing can be used on all supported platforms (Debian/Ubuntu/Mint/Arch Linux/Manjaro). + +#### Force/Lock package versions: Wine Staging + +When you install Wine Staging and you define specific vanilla Wine commit in `git_commithash_wine` (not `HEAD`) variable, _the latest available Wine Staging version compared to that vanilla Wine commit is used_. Practically, this usually means even slightly older package version since the last matching Wine Staging commit usually doesn't match the commit you define for vanilla Wine. In most cases, this shouldn't be a problem. + +### Debian users: Winetricks installation + +**NOTE:** This section doesn't concern Ubuntu or Mint users. + +Since Debian doesn't provide winetricks package on official repositories, it is strongly recommended that you use provided `debian_install_winetricks.sh` to install Winetricks. Winetricks is required for successful DXVK installation. You can run `debian_install_winetricks.sh` either independently or as a part of `updatewine.sh` main script. + ---------------- ## Custom patches for Wine & DXVK @@ -232,30 +280,44 @@ The following section contains important notes about the script usage. Validation test done for the script to ensure it works as expected. Occasional test-runs are mandatory due to rapid development of the packages (Wine/DXVK) it handles. -**Latest test-run:** 15th November, 2018 +**Latest test-run:** 17th November, 2018 **Linux Distributions:** -- Success: Arch Linux 64-bit, Linux Mint 19 64-bit, Ubuntu 18.04 64-bit +- Success: Arch Linux 64-bit, Linux Mint 19 64-bit, Ubuntu 18.04 64-bit, Debian 9 64-bit -- Partial failure: Debian 9 64-bit (DXVK) +- Failure: N/A #### Failure reasons: -Debian: +N/A + +#### Notes: -- DXVK uninstallable: no winetricks package available +Git commit freezing used for DXVK & meson. Reasons: + +- DXVK: can't compile DXVK - DXGI 1.4 headers are missing. See [doitsujin/dxvk - Build issue](https://github.com/doitsujin/dxvk/issues/766) for more info. Commit which break the compilation: [doitsujin/dxvk - [dxgi] Include DXGI 1.4 headers](https://github.com/doitsujin/dxvk/commit/f7b2194e0b1d152c8001d406c41efe0a093b1aa2) + + - Latest commit used: [1af96347e1c6f1f2eb11aeb11009f380fd5761ec](https://github.com/doitsujin/dxvk/commit/1af96347e1c6f1f2eb11aeb11009f380fd5761ec) + + - Provide newer mingw packages? Requires own subscripts for that process (on Debian, at least) + +- Debian - Meson: can't compile DXVK - changes to Meson path functionality breaks it (suspected commit: [mesonbuild/meson - Store unexpanded library directory paths. Closes #4392.](https://github.com/mesonbuild/meson/commit/6a2dc7576e00e849510f7bc1f939d66d0b2f6f80)) --------------------------- ### TODO -- winetricks package for pure Debian users (DXVK runtime dependency) - - Add compilation/installation script for the latest AMDGPU on Debian/Ubuntu/Mint - Remove temp folders in case of failure (meson/glslang/dxvk-git/wine... temp build folders) +- Unify error & warning messages layout, unify internal variable & function names + +- Common script clean-up + +- Separate glslang and meson build process from dxvk on Debian? + - Better handling for sudo validation loop function - may cause the terminal output to get nuts diff --git a/arch/0-dxvk-git/PKGBUILD b/arch/0-dxvk-git/PKGBUILD index 9ca683b..f8c095e 100755 --- a/arch/0-dxvk-git/PKGBUILD +++ b/arch/0-dxvk-git/PKGBUILD @@ -19,7 +19,7 @@ url="https://github.com/doitsujin/dxvk" license=('custom:zlib/libpng') makedepends=('ninja' 'meson>=0.43' 'glslang' 'mingw-w64-gcc' 'git' 'wine') options=(!strip !buildflags staticlibs) -source=(${pkgname}::"git+https://github.com/doitsujin/dxvk.git") +source=(${pkgname}::"git+https://github.com/doitsujin/dxvk.git#commit=HEAD") sha256sums=('SKIP') ############################## diff --git a/arch/0-wine-staging-git/PKGBUILD b/arch/0-wine-staging-git/PKGBUILD index e6af7a1..d32c10e 100755 --- a/arch/0-wine-staging-git/PKGBUILD +++ b/arch/0-wine-staging-git/PKGBUILD @@ -29,6 +29,8 @@ else fi pkgver=stg.3.19.r9.g566cd55d+wine.wine.3.19.r220.g5e0d1c89ed +_wine_commit=HEAD +_staging_commit=HEAD pkgrel=1 arch=('i686' 'x86_64') @@ -114,7 +116,7 @@ optdepends=( options=('staticlibs') source=( - wine-git::'git://source.winehq.org/git/wine.git' + wine-git::'git://source.winehq.org/git/wine.git#commit=HEAD' '30-win32-aliases.conf' ) @@ -130,7 +132,7 @@ if [[ $(find ./wine-patches -mindepth 1 -maxdepth 1 -regex ".*\.\(patch\|diff\)$ fi if [[ enable_staging -eq 1 ]]; then - stagingsrc=wine-staging-git::'git://github.com/wine-staging/wine-staging.git' + stagingsrc=wine-staging-git::'git://github.com/wine-staging/wine-staging.git#commit=HEAD' source+=($stagingsrc) fi @@ -175,11 +177,13 @@ prepare() { # Restore the wine tree to its git origin state, without wine-staging patches #+(necessary for reapllying wine-staging patches in succedent builds, #+otherwise the patches will fail to be reapplied) - git reset --hard HEAD # Restore tracked files + git reset --hard ${_wine_commit} # Restore tracked files git clean -d -x -f # Delete untracked files - # Change back to the wine upstream commit that this version of wine-staging is based on - git checkout $(../"$pkgname"/patches/patchinstall.sh --upstream-commit) + if [[ ${_wine_commit} == HEAD ]]; then + # Change back to the wine upstream commit that this version of wine-staging is based on + git checkout $(../"$pkgname"/patches/patchinstall.sh --upstream-commit) + fi fi } @@ -197,7 +201,7 @@ build() { ${staging_patchsets[*]} fi - if [[ $(ls "${srcdir}"/*.{patch,diff} | wc -w) -ne 0 ]]; then + if [[ $(ls "${srcdir}"/*.{patch,diff} 2>/dev/null | wc -w) -ne 0 ]]; then cd "${srcdir}"/wine-git # Apply all custom patches diff --git a/arch/updatewine_arch.sh b/arch/updatewine_arch.sh index 8481494..7f488f3 100755 --- a/arch/updatewine_arch.sh +++ b/arch/updatewine_arch.sh @@ -30,20 +30,38 @@ datedir="${1}" ######################################################## -# http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal -function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; } +# Divide input args into array indexes +i=0 +for p in ${@:2}; do + params[$i]=${p} + let i++ +done ######################################################## -# Parse input arguments +# Parse input git override hashes +# This order is mandatory! +# If you change the order or contents of 'githash_overrides' +# array in ../updatewine.sh, make sure to update these +# variables! +# +git_commithash_dxvk=${params[0]} +git_commithash_wine=${params[3]} + +######################################################## + +# Parse input arguments, filter user parameters +# The range is defined in ../updatewine.sh +# All input arguments are: +# 4* +# 0 1 2 3 4 5 ... +# Filter all but , i.e. the first 0-4 arguments i=0 -for arg in ${@:2}; do +for arg in ${params[@]:4}; do args[$i]="${arg}" let i++ done -# Must be a true array as defined above, not a single index list! -#args="${@:2}" for check in ${args[@]}; do @@ -69,6 +87,11 @@ for check in ${args[@]}; do done +######################################################## + +# http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal +function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; } + ########################################################### # If the script is interrupted (Ctrl+C/SIGINT), do the following @@ -226,6 +249,124 @@ function prepare_env() { } +######################################################## + +# Parse Wine hash override if Staging is set to be installed + +function check_gitOverride_wine() { + + # If staging is to be installed and Wine git is frozen to a specific commit + # We need to determine exact commit to use for Wine Staging + # to avoid any mismatches + # + # Basically, when user has defined 'git_commithash_wine' variable (commit), we + # iterate through Wine commits and try to determine previously set + # Wine Staging commit. We use that Wine Staging commit instead of + # the one user has defined in 'git_commithash_wine' variable + # + if [[ ! -v NO_STAGING ]] && [[ "${git_commithash_wine}" != HEAD ]]; then + + function form_commit_array() { + + cd "${commit_dir}" + + if [[ $? -ne 0 ]]; then + echo -e "Error: couldn't access Wine folder ${commit_dir} to check commits. Aborting\n" + exit 1 + fi + + local array_name=${1} + local commits_raw=$(eval ${2}) + + local i=0 + for commit in ${commits_raw[*]}; do + eval ${array_name}[$i]="${commit}" + let i++ + done + + if [[ $? -ne 0 ]]; then + echo -e "Error: couldn't parse Wine commits in ${commit_dir}. Aborting\n" + exit 1 + fi + + cd "${ARCH_BUILDROOT}/0-wine-staging-git/" + + } + + function staging_change_freeze_commit() { + + local wine_commits_raw="git log --pretty=oneline | awk '{print \$1}' | tr '\n' ' '" + + # TODO this check may break quite easily + # It depends on the exact comment syntax Wine Staging developers are using (Rebase against ...) + # Length and order of these two "array" variables MUST MATCH! + local staging_refcommits_raw="git log --pretty=oneline | awk '{ if ((length(\$NF)==40 || length(\$NF)==41) && \$(NF-1)==\"against\") print \$1; }'" + local staging_rebasecommits_raw="git log --pretty=oneline | awk '{ if ((length(\$NF)==40 || length(\$NF)==41) && \$(NF-1)==\"against\") print substr(\$NF,1,40); }' | tr '\n' ' '" + + # Syntax: + commit_dir="${ARCH_BUILDROOT}/0-wine-staging-git/wine-git" + form_commit_array wine_commits "${wine_commits_raw}" + + commit_dir="${ARCH_BUILDROOT}/0-wine-staging-git/wine-staging-git" + form_commit_array staging_refcommits "${staging_refcommits_raw}" + form_commit_array staging_rebasecommits "${staging_rebasecommits_raw}" + + # User has selected vanilla Wine commit to freeze to + # We must get the previous Staging commit from rebase_commits array, and + # change git_commithash_wine value to that + + # Get all vanilla Wine commits + # Filter all newer than defined in 'git_commithash_wine' + # + echo -e "Determining valid Wine Staging git commit. This takes a while.\n" + local i=0 + for dropcommit in ${wine_commits[@]}; do + if [[ "${dropcommit}" == "${git_commithash_wine}" ]]; then + break + else + local wine_dropcommits[$i]="${dropcommit}" + let i++ + fi + done + wine_commits=("${wine_commits[@]:${#wine_dropcommits[*]}}") + + # For the filtered array list, iterate through 'staging_rebasecommits' array list until + # we get a match + for vanilla_commit in ${wine_commits[@]}; do + local k=0 + for rebase_commit in ${staging_rebasecommits[@]}; do + if [[ "${vanilla_commit}" == "${rebase_commit}" ]]; then + # This is the commit we use for vanilla Wine + git_commithash_wine="${vanilla_commit}" + # This is equal commit we use for Wine Staging + git_commithash_winestaging="${staging_refcommits[$k]}" + break 2 + fi + let k++ + done + done + + } + elif [[ ! -v NO_STAGING ]] && [[ "${git_commithash_wine}" == HEAD ]]; then + git_commithash_winestaging=HEAD + fi + staging_change_freeze_commit +} + +########################################################### + +function set_gitOverride() { + local git_name=${1} + local git_commithash=${2} + local pkgbuild_file=${3} + + # Match string ${git_name}#commit= + # where replace , but exclude ' " and ) after that + # + # TODO consider when there is nothing/no string after = symbol + sed -i "s!\(${git_name}#commit=\)\(.*[^'|^\"|^\)]\)!\1${git_commithash}!" "${pkgbuild_file}" +} + ########################################################### # Remove any existing pkg,src or tar.xz packages left by previous pacman commands @@ -248,11 +389,38 @@ function build_pkg() { local cleanlist=${4} # Create package and install it to the system + # We need to download git sources beforehand in order + # to determine git commit hashes cd "${ARCH_BUILDROOT}"/${pkgdir} - bash -c "updpkgsums && makepkg" + bash -c "updpkgsums && makepkg -o" + + # Check git commit hashes + if [[ $? -eq 0 ]] && \ + [[ ${5} == gitcheck ]]; then + if [[ ${pkgname} == wine ]]; then + check_gitOverride_wine + + local pkgbuild_file="${ARCH_BUILDROOT}/${pkgdir}/PKGBUILD" + + set_gitOverride "wine.git" "${git_commithash_wine}" ${pkgbuild_file} + sed -i "s/\(^_wine_commit=\).*/\1${git_commithash_wine}/" ${pkgbuild_file} + + if [[ ! -v NO_STAGING ]]; then + set_gitOverride "wine-staging.git" "${git_commithash_winestaging}" ${pkgbuild_file} + sed -i "s/\(^_staging_commit=\).*/\1${git_commithash_winestaging}/" ${pkgbuild_file} + fi + + elif [[ ${pkgname} == dxvk ]]; then + local pkgbuild_file="${ARCH_BUILDROOT}/${pkgdir}/PKGBUILD" + set_gitOverride "dxvk.git" "${git_commithash_dxvk}" ${pkgbuild_file} + fi + + fi + + if [[ $? -eq 0 ]]; then bash -c "updpkgsums && makepkg"; else exit 1; fi # After successful compilation... - if [[ $(ls ${pkgname}-*tar.xz | wc -l) -ne 0 ]]; then + if [[ $(ls ./${pkgname}-*tar.xz 2>/dev/null | wc -l) -ne 0 ]]; then if [[ ! -v NO_INSTALL ]]; then yes | sudo pacman -U ${pkgname}-*.tar.xz @@ -265,7 +433,7 @@ function build_pkg() { done else - echo -e "Error occured while compliling ${pkgname} from source.\n" + echo -e "Error occured during ${pkgname} compilation.\n" for rml in ${cleanlist[*]}; do rm -rf "${ARCH_BUILDROOT}/${pkgdir}/${rml}" done @@ -362,12 +530,13 @@ check_alldeps # Compile Wine & DXVK, depending on whether these packages # are to be built +# Although the folder name is '0-wine-staging-git', we can still build vanilla Wine if [[ ! -v NO_WINE ]]; then - build_pkg wine "${wine_name}" "0-wine-staging-git" "${dxvk_wine_cleanlist[*]}" + build_pkg wine "${wine_name}" "0-wine-staging-git" "${dxvk_wine_cleanlist[*]}" gitcheck fi if [[ ! -v NO_DXVK ]]; then - build_pkg dxvk DXVK "0-dxvk-git" "${dxvk_wine_cleanlist[*]}" + build_pkg dxvk DXVK "0-dxvk-git" "${dxvk_wine_cleanlist[*]}" gitcheck fi ######################### diff --git a/debian/dxvkroot/dxvkbuild.sh b/debian/dxvkroot/dxvkbuild.sh index a1cf28a..c6bfcf5 100755 --- a/debian/dxvkroot/dxvkbuild.sh +++ b/debian/dxvkroot/dxvkbuild.sh @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -########################################################### +######################################################## # DO NOT RUN INDIVIDUALLY, ONLY VIA ../../updatewine.sh PARENT SCRIPT! @@ -28,17 +28,41 @@ DXVKROOT="${PWD}" # datedir variable supplied by ../updatewine_debian.sh script file datedir="${1}" -########################################################### +######################################################## + +# Divide input args into array indexes +i=0 +for p in ${@:2}; do + params[$i]=${p} + let i++ +done + +######################################################## + +# Parse input git override hashes +# This order is mandatory! +# If you change the order or contents of 'githash_overrides' +# array in ../updatewine.sh, make sure to update these +# variables! +# +git_commithash_dxvk=${params[0]} +git_commithash_glslang=${params[1]} +git_commithash_meson=${params[2]} -# Parse input arguments +######################################################## + +# Parse input arguments, filter user parameters +# The range is defined in ../updatewine.sh +# All input arguments are: +# 4* +# 0 1 2 3 4 5 ... +# Filter all but , i.e. the first 0-4 arguments i=0 -for arg in ${@:2}; do +for arg in ${params[@]:4}; do args[$i]="${arg}" let i++ done -# Must be a true array as defined above, not a single index list! -#args="${@:2}" for check in ${args[@]}; do @@ -46,6 +70,9 @@ for check in ${args[@]}; do --no-install) NO_INSTALL= ;; +# --no-winetricks) +# NO_WINETRICKS= +# ;; --updateoverride) UPDATE_OVERRIDE= ;; @@ -56,7 +83,7 @@ for check in ${args[@]}; do done -########################################################### +######################################################## # Check presence of Wine. Some version of Wine should # be found in the system in order to install DXVK. @@ -112,7 +139,7 @@ runtimeCheck Wine "${known_wines[*]}" # Check existence of known Winetricks packages runtimeCheck Winetricks "${known_winetricks[*]}" -########################################################### +######################################################## # If the script is interrupted (Ctrl+C/SIGINT), do the following @@ -130,7 +157,7 @@ trap "DXVK_intCleanup" INT # http://wiki.bash-hackers.org/snipplets/print_horizontal_line#a_line_across_the_entire_width_of_the_terminal function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; } -################################## +######################################################## # Update all packages if UPDATE_OVERRIDE given @@ -140,7 +167,7 @@ if [[ -v UPDATE_OVERRIDE ]]; then sudo apt update && sudo apt upgrade -y fi -################################## +######################################################## # Check do we need to compile the package # given as input for this function @@ -156,7 +183,7 @@ function pkgcompilecheck() { } -################################################### +######################################################## # Global variable to track buildtime dependencies z=0 @@ -168,11 +195,12 @@ function preparepackage() { local _pkgdeps_build=${2} local _pkgurl=${3} local _pkgver=${4} + local _git_commithash=${5} echo -e "Starting compilation$(if [[ ! -v NO_INSTALL ]] || [[ ${_pkgname} =~ ^meson|glslang$ ]]; then printf " & installation"; fi) of ${1}\n" # Optional variable for runtime dependencies array - if [[ -n ${5} ]]; then local _pkgdeps_runtime=${5}; fi + if [[ -n ${6} ]]; then local _pkgdeps_runtime=${6}; fi # Check and install package related dependencies if they are missing function pkgdependencies() { @@ -199,7 +227,7 @@ function preparepackage() { # Install missing dependencies, be informative local b=0 for pkgdep in ${validlist[@]}; do - echo -e "$(( $b + 1 ))/$(( ${#validlist[*]} )) - Installing ${_pkgname} dependency ${pkgdep}" + echo -e "$(( $b + 1 ))/$(( ${#validlist[*]} )) - Installing ${_pkgname} build time dependency ${pkgdep}" sudo apt install -y ${pkgdep} &> /dev/null if [[ $? -eq 0 ]]; then let b++ @@ -221,6 +249,11 @@ function preparepackage() { if [[ -n "${_pkgver}" ]] && [[ "${_pkgver}" =~ ^git ]]; then cd ${_pkgname} + git reset --hard ${_git_commithash} + if [[ $? -ne 0 ]]; then + echo -e "Error: couldn't find commit ${_git_commithash} for ${_pkgname}. Aborting\n" + exit 1 + fi _pkgver=$(eval "${_pkgver}") cd .. fi @@ -261,7 +294,7 @@ function preparepackage() { } -################################################### +######################################################## # BUILD DEPENDENCIES REMOVAL @@ -270,7 +303,7 @@ function buildpkg_removal() { # Build time dependencies which were installed but no longer needed if [[ -v buildpkglist ]]; then if [[ -v BUILDPKG_RM ]]; then - sudo apt purge --remove -y "${buildpkglist[*]}" + sudo apt purge --remove -y ${buildpkglist[*]} # In some cases, glslang or meson may still be present on the system. Remove them for extrapkg in glslang meson; do @@ -285,7 +318,7 @@ function buildpkg_removal() { fi } -################################################### +######################################################## # MESON COMPILATION & INSTALLATION # Required by DXVK package @@ -306,6 +339,9 @@ function meson_install_main() { # Git source location local pkgurl="https://github.com/mesonbuild/meson" + # Git commit hash variable + local git_commithash=${git_commithash_meson} + # Parsed version number from git source files local pkgver_git="git describe --long | sed 's/\-[a-z].*//; s/\-/\./; s/[a-z]//g'" @@ -365,12 +401,12 @@ function meson_install_main() { } # Execute above functions - preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" && \ + preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" "${git_commithash}" && \ meson_debianbuild } -################################################### +######################################################## # GLSLANG COMPILATION & INSTALLATION # Required by DXVK package @@ -386,6 +422,9 @@ function glslang_install_main() { # Git source location local pkgurl="https://github.com/KhronosGroup/glslang" + # Git commit hash variable + local git_commithash=${git_commithash_glslang} + # Parsed version number from git source files local pkgver_git="git describe --long | sed 's/\-[a-z].*//; s/\-/\./; s/[a-z]//g'" @@ -425,12 +464,12 @@ function glslang_install_main() { } # Execute above functions - preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" && \ + preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" "${git_commithash}" && \ glslang_debianbuild } -################################################### +######################################################## # DXVK COMPILATION & INSTALLATION @@ -457,6 +496,9 @@ function dxvk_install_main() { # Git source location local pkgurl="https://github.com/doitsujin/dxvk" + # Git commit hash variable + local git_commithash=${git_commithash_dxvk} + # Parsed version number from git source files local pkgver_git="git describe --long | sed 's/\-[a-z].*//; s/\-/\./; s/[a-z]//g'" @@ -604,14 +646,14 @@ DXVK-DEBIANRULES # function 'preparepackage'. This does not apply to runtime dependency 'wine', which # may be 'wine', 'wine-git', 'wine-staging-git' etc. in truth # - preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" && \ + preparepackage "${pkgname}" "${pkgdeps_build[*]}" "${pkgurl}" "${pkgver_git}" "${git_commithash}" && \ dxvk_posixpkgs && \ dxvk_custompatches && \ dxvk_debianbuild } -#################################################################### +######################################################## pkgcompilecheck meson meson_install_main pkgcompilecheck glslang glslang_install_main diff --git a/debian/updatewine_debian.sh b/debian/updatewine_debian.sh index e90b331..0b0c666 100755 --- a/debian/updatewine_debian.sh +++ b/debian/updatewine_debian.sh @@ -35,15 +35,28 @@ function INFO_SEP() { printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - ; ######################################################## -# Parse input arguments +# Divide input args into array indexes +# These are passed to the subscripts (array b) +i=0 +for p in ${@:2}; do + params[$i]=${p} + let i++ +done + +######################################################## + +# Parse input arguments, filter user parameters +# The range is defined in ../updatewine.sh +# All input arguments are: +# 4* +# 0 1 2 3 4 5 ... +# Filter all but , i.e. the first 0-4 arguments i=0 -for arg in ${@:2}; do +for arg in ${params[@]:4}; do args[$i]="${arg}" let i++ done -# Must be a true array as defined above, not a single index list! -#args="${@:2}" # All valid arguments given in ../updatewine.sh are handled... # All valid arguments are passed to subscripts... @@ -64,6 +77,9 @@ for check in ${args[@]}; do --no-pol) NO_POL= ;; + --no-winetricks) + NO_WINETRICKS= + ;; --no-install) NO_INSTALL= # If this option is given, do not check PoL wineprefixes @@ -115,7 +131,179 @@ This can take up to 0.5-2 hours depending on the available CPU cores.\n\n\ Using $(nproc --ignore 1) of $(nproc) available CPU cores for Wine source code compilation. " - bash -c "cd ${ROOTDIR}/wineroot/ && bash ./winebuild.sh \"${datedir}\" \"${args[*]}\"" + bash -c "cd ${ROOTDIR}/wineroot/ && bash ./winebuild.sh \"${datedir}\" \"${params[*]}\"" + +} + +######################################################## + +# Call Winetricks compilation & installation subscript in the following function + +function winetricks_install_main() { + + local pkg="winetricks" + + # Location of expected Winetricks deb archive from + # the point of view of this script file + local pkgdebdir=".." + + # Winetricks availability check + function winetricks_availcheck() { + + local apt_searchcheck=$(apt-cache search ^${pkg}$ | wc -l) + + if [[ $(echo $(dpkg -s ${pkg} &>/dev/null)$?) -ne 0 ]]; then + + # TODO expecting only 1 match from apt-cache output + if [[ ${apt_searchcheck} -eq 1 ]]; then + sudo apt install -y ${pkg} + if [[ $? -eq 0 ]]; then + # Winetricks already installed by the previous command + return 0 + else + echo -e "Warning: can't install Winetricks from repositories. Trying to compile from source.\n" + # TODO Force Winetricks compilation from source. Is this a good practice? + return 1 + fi + else + # Multiple or no entries from apt-cache output. Can't decide which package to use, so force winetricks compilation. + echo -e "Warning: can't install Winetricks from repositories. Trying to compile from source.\n" + # TODO Force Winetricks compilation from source. Is this a good practice? + return 1 + fi + else + # Winetricks already installed on the system + echo -e "Winetricks is installed on your system. Use your package manager or 'debian_install_winetricks.sh' script to update it.\n" + return 0 + fi + } + + # Winetricks installation from local deb package + function winetricks_localdeb() { + + # Check that Wine exists on the system. If yes, then + # install other required winetricks dependencies + # so that Winetricks install script won't complain about + # missing them. + # + local known_wines=( + 'wine' + 'wine-stable' + 'wine32' + 'wine64' + 'libwine:amd64' + 'libwine:i386' + 'wine-git' + 'wine-staging-git' + ) + + # Other winetricks dependencies + local winetricks_deps=('cabextract' 'unzip' 'x11-utils') + + # If known wine is found, then check winetricks_deps and install them if needed. + for winepkg in ${known_wines[@]}; do + if [[ $(echo $(dpkg -s ${winepkg} &>/dev/null)$?) -eq 0 ]]; then + for tricksdep in ${winetricks_deps[@]}; do + if [[ $(echo $(dpkg -s ${tricksdep} &>/dev/null)$?) -ne 0 ]]; then + sudo apt install -y ${tricksdep} + if [[ $? -ne 0 ]]; then + echo -e "Error: couldn't install Winetricks dependency ${tricksdep}. Skipping Winetricks installation.\n" + # TODO revert installation of any installed 'tricksdep' installed on previous loop cycle + if [[ ! -v NO_INSTALL ]];then + echo -e "DXVK won't be installed\n" + # We can set this value because winetricks function is intented to be called + # after Wine compilation & installation BUT before DXVK install function + # DXVK runtime (not build time) depends on Winetricks + params+=('--no-install') + fi + # Special variable only to inform user about errors in Winetricks installation + WINETRICKS_ERROR= + return 1 + fi + fi + done + # If known wine has already been found, do not iterate through other candidates + break + fi + done + + # Check for existing winetricks deb archives in the previous folder + local localdeb=$(find ${pkgdebdir} -type f -name "${pkg}*.deb" | wc -l) + + case ${localdeb} in + 0) + # No old winetricks archives + # Just fall through + ;; + 1) + # One old winetricks archive found + echo -e "Found already compiled Winetricks archive, installing it.\n" + # TODO ask user? Note that asking this limits the automation process of this script + # unless a solution will be implemented (e.g. parameter switch) + sudo dpkg -i ${pkgdebdir}/${pkg}*.deb + return 0 + ;; + *) + # Multiple old winetricks archives found + # Move them and compile a new one + if [[ ! -d ${pkgdebdir}/winetricks_old ]]; then + mkdir -p ${pkgdebdir}/winetricks_old + fi + mv ${pkgdebdir}/${pkg}*.deb ${pkgdebdir}/winetricks_old/ + if [[ $? -ne 0 ]]; then + echo -e "Warning: couldn't move old Winetricks archives. Not installing Winetricks.\n" + if [[ ! -v NO_INSTALL ]];then + echo -e "DXVK won't be installed\n" + # We can set this value because winetricks function is intented to be called + # after Wine compilation & installation BUT before DXVK install function + # DXVK runtime (not build time) depends on Winetricks + params+=('--no-install') + fi + fi + ;; + esac + + echo -e "Starting compilation & installation of Winetricks\n" + bash -c "cd .. && bash ./debian_install_winetricks.sh" + + if [[ $? -eq 0 ]]; then + # The compiled Winetricks deb package is found in the previous folder + sudo dpkg -i ${pkgdebdir}/${pkg}*.deb + + if [[ $? -ne 0 ]]; then + echo -e "Warning: couldn't install Winetricks.\n" + + if [[ ! -v NO_INSTALL ]];then + echo -e "DXVK won't be installed\n" + # We can set this value because winetricks function is intented to be called + # after Wine compilation & installation BUT before DXVK install function + # DXVK runtime (not build time) depends on Winetricks + params+=('--no-install') + fi + # Special variable only to inform user about errors in Winetricks installation + WINETRICKS_ERROR= + return 1 + fi + else + echo -e "Warning: couldn't compile Winetricks.\n" + if [[ ! -v NO_INSTALL ]];then + echo -e "DXVK won't be installed\n" + # We can set this value because winetricks function is intented to be called + # after Wine compilation & installation BUT before DXVK install function + # DXVK runtime (not build time) depends on Winetricks + params+=('--no-install') + fi + # Special variable only to inform user about errors in Winetricks compilation + WINETRICKS_ERROR= + return 1 + fi + + } + + winetricks_availcheck + if [[ $? -ne 0 ]]; then + winetricks_localdeb + fi } @@ -126,12 +314,9 @@ Using $(nproc --ignore 1) of $(nproc) available CPU cores for Wine source code c function dxvk_install_main() { echo -e "Starting compilation & installation of DXVK\n\n\ -This can take up to 10-20 minutes depending on the available CPU cores\n\ -& how many dependencies we need to build.\n\n\ -Using $(nproc --ignore 1) of $(nproc) available CPU cores for Wine source code compilation. -" +This can take up to 10-20 minutes depending on how many dependencies we need to build for it.\n" - bash -c "cd ${ROOTDIR}/dxvkroot && bash dxvkbuild.sh \"${datedir}\" \"${args[*]}\"" + bash -c "cd ${ROOTDIR}/dxvkroot && bash dxvkbuild.sh \"${datedir}\" \"${params[*]}\"" } @@ -181,7 +366,7 @@ Do you want to continue? [Y/n]" questionresponse if [[ $? -eq 0 ]]; then - args+=('--buildpkg-rm') + params+=('--buildpkg-rm') fi #################### @@ -189,7 +374,7 @@ Do you want to continue? [Y/n]" AVAIL_SPACE=$(df -h -B MB --output=avail . | sed '1d; s/[A-Z]*//g') REC_SPACE=8000 - if [[ ${AVAIL_SPACE} -lt ${REC_SPACE} ]]; then + if [[ ${AVAIL_SPACE} -lt ${REC_SPACE} ]] && [[ ! -v NO_WINE ]]; then INFO_SEP echo -e "\e[1mWARNING:\e[0m Not sufficient storage space\n\nYou will possibly run out of space while compiling software.\n\ @@ -223,7 +408,7 @@ Update dependency packages & other system packages? [Y/n]" questionresponse if [[ $? -eq 0 ]]; then - args+=('--updateoverride') + params+=('--updateoverride') fi INFO_SEP @@ -269,7 +454,19 @@ else echo -e "Skipping Wine build$(if [[ ! -v NO_INSTALL ]]; then printf " & installation"; fi) process.\n" fi -########## +#################### + +# Run winetricks installation, if needed +if [[ ! -v NO_DXVK ]] && [[ ! -v NO_INSTALL ]]; then + if [[ ! -v NO_WINETRICKS ]]; then + winetricks_install_main + else + echo -e "Skipping Winetricks build & installation process.\n \ + DXVK will not be installed, unless Winetricks is already installed on your system.\n" + fi +fi + +#################### # If DXVK is going to be installed, then if [[ ! -v NO_DXVK ]]; then @@ -278,10 +475,15 @@ else echo -e "Skipping DXVK build$(if [[ ! -v NO_INSTALL ]]; then printf " & installation"; fi) process.\n" fi -########## +#################### # If PlayOnLinux Wine prefixes are going to be updated, then if [[ ! -v NO_POL ]]; then bash -c "cd ${ROOTDIR} && bash playonlinux_prefixupdate.sh" fi +# If error occured during Winetricks script runtime, then +if [[ -v WINETRICKS_ERROR ]]; then + echo -e "Warning: couldn't compile or install Winetricks.\ + $(if [[ ! -v NO_DXVK ]]; then printf " DXVK installation may have failed, too."; fi)\n" +fi diff --git a/debian/wineroot/winebuild.sh b/debian/wineroot/winebuild.sh index 09313b0..61e6f63 100755 --- a/debian/wineroot/winebuild.sh +++ b/debian/wineroot/winebuild.sh @@ -27,6 +27,12 @@ datedir="${1}" ######################################################## +# The directory this script is running at + +BUILDROOT="${PWD}" + +######################################################## + # Staging patchsets. Default: all patchsets. # Applies only if Wine Staging is set to be compiled # Please see Wine Staging patchinstall.sh file for individual patchset names. @@ -163,7 +169,7 @@ wine_deps_build_i386=( 'libtiff-dev:i386' 'libcups2-dev:i386' 'libgnutls28-dev:i386' -'gir1.2-gstreamer-1.0:i386' #required by libgstreamer1.0-dev:i386 (Mint) +'gir1.2-gstreamer-1.0:i386' #required by libgstreamer1.0-dev:i386 'libgstreamer1.0-dev:i386' 'libgstreamer-plugins-base1.0-dev:i386' ) @@ -288,15 +294,37 @@ fi ######################################################## -# Parse input arguments +# Divide input args into array indexes +i=0 +for p in ${@:2}; do + params[$i]=${p} + let i++ +done + +######################################################## + +# Parse input git override hashes +# This order is mandatory! +# If you change the order or contents of 'githash_overrides' +# array in ../updatewine.sh, make sure to update these +# variables! +# +git_commithash_wine=${params[3]} + +######################################################## + +# Parse input arguments, filter user parameters +# The range is defined in ../updatewine.sh +# All input arguments are: +# 4* +# 0 1 2 3 4 5 ... +# Filter all but , i.e. the first 0-4 arguments i=0 -for arg in ${@:2}; do +for arg in ${params[@]:4}; do args[$i]="${arg}" let i++ done -# Must be a true array as defined above, not a single index list! -#args="${@:2}" for check in ${args[@]}; do @@ -319,8 +347,8 @@ done # If the script is interrupted (Ctrl+C/SIGINT), do the following function Wine_intCleanup() { - cd .. - rm -rf winebuild_${datedir} + cd "${BUILDROOT}" + rm -rf "winebuild_${datedir}" exit 0 } @@ -359,16 +387,16 @@ function getWine() { local winestaging_url="git://github.com/wine-staging/wine-staging.git" function cleanOldBuilds() { - if [[ $(find . -type d -name "winebuild_*" | wc -l) -ne 0 ]]; then + if [[ $(find "${BUILDROOT}" -type d -name "winebuild_*" | wc -l) -ne 0 ]]; then echo -e "Removing old Wine build folders. This can take a while.\n" - rm -rf ./winebuild_* + rm -rf "${BUILDROOT}"/winebuild_* fi } cleanOldBuilds - mkdir winebuild_${datedir} - cd winebuild_${datedir} + mkdir "${BUILDROOT}/winebuild_${datedir}" + cd "${BUILDROOT}/winebuild_${datedir}" WINEROOT="${PWD}" @@ -410,6 +438,110 @@ function getDebianFiles() { ######################################################## +# Parse Wine hash override if Staging is set to be installed + +function check_gitOverride() { + + # If staging is to be installed and Wine git is frozen to a specific commit + # We need to determine exact commit to use for Wine Staging + # to avoid any mismatches + # + # Basically, when user has defined 'git_commithash_wine' variable (commit), we + # iterate through Wine commits and try to determine previously set + # Wine Staging commit. We use that Wine Staging commit instead of + # the one user has defined in 'git_commithash_wine' variable + # + if [[ ! -v NO_STAGING ]] && [[ "${git_commithash_wine}" != HEAD ]]; then + + function form_commit_array() { + + cd "${commit_dir}" + + if [[ $? -ne 0 ]]; then + echo -e "Error: couldn't access Wine folder ${commit_dir} to check commits. Aborting\n" + exit 1 + fi + + local array_name=${1} + local commits_raw=$(eval ${2}) + + local i=0 + for commit in ${commits_raw[*]}; do + eval ${array_name}[$i]="${commit}" + let i++ + done + + if [[ $? -ne 0 ]]; then + echo -e "Error: couldn't parse Wine commits in ${commit_dir}. Aborting\n" + exit 1 + fi + + cd "${WINEROOT}" + + } + + function staging_change_freeze_commit() { + + local wine_commits_raw="git log --pretty=oneline | awk '{print \$1}' | tr '\n' ' '" + + # TODO this check may break quite easily + # It depends on the exact comment syntax Wine Staging developers are using (Rebase against ...) + # Length and order of these two "array" variables MUST MATCH! + local staging_refcommits_raw="git log --pretty=oneline | awk '{ if ((length(\$NF)==40 || length(\$NF)==41) && \$(NF-1)==\"against\") print \$1; }'" + local staging_rebasecommits_raw="git log --pretty=oneline | awk '{ if ((length(\$NF)==40 || length(\$NF)==41) && \$(NF-1)==\"against\") print substr(\$NF,1,40); }' | tr '\n' ' '" + + # Syntax: + commit_dir="${WINEDIR}" + form_commit_array wine_commits "${wine_commits_raw}" + + commit_dir="${WINEDIR_STAGING}" + form_commit_array staging_refcommits "${staging_refcommits_raw}" + form_commit_array staging_rebasecommits "${staging_rebasecommits_raw}" + + # User has selected vanilla Wine commit to freeze to + # We must get the previous Staging commit from rebase_commits array, and + # change git_commithash_wine value to that + + # Get all vanilla Wine commits + # Filter all newer than defined in 'git_commithash_wine' + # + echo -e "Determining valid Wine Staging git commit. This takes a while.\n" + local i=0 + for dropcommit in ${wine_commits[@]}; do + if [[ "${dropcommit}" == "${git_commithash_wine}" ]]; then + break + else + local wine_dropcommits[$i]="${dropcommit}" + let i++ + fi + done + wine_commits=("${wine_commits[@]:${#wine_dropcommits[*]}}") + + # For the filtered array list, iterate through 'staging_rebasecommits' array list until + # we get a match + for vanilla_commit in ${wine_commits[@]}; do + local k=0 + for rebase_commit in ${staging_rebasecommits[@]}; do + if [[ "${vanilla_commit}" == "${rebase_commit}" ]]; then + # This is the commit we use for vanilla Wine + git_commithash_wine="${vanilla_commit}" + # This is equal commit we use for Wine Staging + git_commithash_winestaging="${staging_refcommits[$k]}" + break 2 + fi + let k++ + done + done + + } + elif [[ ! -v NO_STAGING ]] && [[ "${git_commithash_wine}" == HEAD ]]; then + git_commithash_winestaging=HEAD + fi + staging_change_freeze_commit +} + +######################################################## + # Wine dependencies removal/installation # Global variable to track buildtime dependencies @@ -483,7 +615,7 @@ function WineDeps() { exit 1 fi done - if [[ -n ${validlist[*]} ]]; then + if [[ -n ${validlist[*]} ]]; then # Add empty newline echo "" fi @@ -530,12 +662,27 @@ function refreshWineGIT() { # (necessary for reapllying wine-staging patches in succedent builds, # otherwise the patches will fail to be reapplied) cd "${WINEDIR}" - git reset --hard HEAD # Restore tracked files - git clean -d -x -f # Delete untracked files + git reset --hard ${git_commithash_wine} # Get Wine commit + if [[ $? -ne 0 ]]; then + echo "Error: couldn't find git commit '${git_commithash_wine}' for Wine. Aborting\n" + exit 1 + fi + git clean -d -x -f # Delete untracked files if [[ ! -v NO_STAGING ]]; then - # Change back to the wine upstream commit that this version of wine-staging is based on - git checkout $(bash "${WINEDIR_STAGING}"/patches/patchinstall.sh --upstream-commit) + + if [[ ${git_commithash_wine} == HEAD ]]; then + # Change back to the wine upstream commit that this version of wine-staging is based on + git checkout $(bash "${WINEDIR_STAGING}"/patches/patchinstall.sh --upstream-commit) + + else + cd "${WINEDIR_STAGING}" + git reset --hard ${git_commithash_winestaging} + if [[ $? -ne 0 ]]; then + echo "Error: couldn't find git commit '${git_commithash_winestaging}' for Wine Staging. Aborting\n" + exit 1 + fi + fi fi } @@ -543,9 +690,9 @@ function refreshWineGIT() { # Get Wine version tag -function getWineVersion() { +function wine_version() { cd "${WINEDIR}" - wine_version=$(git describe | sed 's/^[a-z]*-//; s/-[0-9]*-[a-z0-9]*$//') + git describe | sed 's/^[a-z]*-//; s/-[0-9]*-[a-z0-9]*$//' } ######################################################## @@ -555,15 +702,14 @@ function getWineVersion() { function patchWineSource() { if [[ ! -v NO_STAGING ]]; then - cd "${WINEDIR_STAGING}/patches" - bash ./patchinstall.sh DESTDIR="${WINEDIR}" ${staging_patchsets[*]} + bash "${WINEDIR_STAGING}/patches/patchinstall.sh" DESTDIR="${WINEDIR}" ${staging_patchsets[*]} fi cp -r ${WINEROOT}/../../../wine_custom_patches/* "${WINEDIR_PATCHES}/" if [[ $(find "${WINEDIR_PATCHES}" -mindepth 1 -maxdepth 1 -regex ".*\.\(patch\|diff\)$") ]]; then cd "${WINEDIR}" - for i in "${WINEDIR_PATCHES}"/*.patch; do + for i in "${WINEDIR_PATCHES}"/*.{patch,diff}; do patch -Np1 < $i done fi @@ -598,8 +744,6 @@ function wine64Build() { function wine32Build() { -# Gstreamer amd64 & i386 dev packages conflict on Ubuntu - cd "${WINEDIR_BUILD_32}" "${WINEDIR}"/configure \ --with-x \ @@ -607,7 +751,6 @@ function wine32Build() { --with-xattr \ --disable-mscoree \ --with-vulkan \ - --without-gstreamer \ --libdir=/usr/lib/i386-linux-gnu/ \ --with-wine64="${WINEDIR_BUILD_64}" \ --prefix=/usr @@ -634,8 +777,8 @@ function mergeWineBuilds() { function buildDebianArchive() { cd "${WINEROOT}" - mv "${WINEDIR_PACKAGE}" "${WINEROOT}/${PKGNAME}-${wine_version}" - cd "${WINEROOT}/${PKGNAME}-${wine_version}" + mv "${WINEDIR_PACKAGE}" "${WINEROOT}/${PKGNAME}-$(wine_version)" + cd "${WINEROOT}/${PKGNAME}-$(wine_version)" dh_make --createorig -s -y -c lgpl rm debian/*.{ex,EX} printf "usr/* /usr" > debian/install @@ -674,13 +817,13 @@ DEBIANCONTROL function installDebianArchive() { cd "${WINEROOT}" # TODO Although the package name ends with 'amd64', this contains both 32 and 64 bit Wine versions - echo -e "\nInstalling Wine$(if [[ -v ! NO_STAGING ]]; then printf " Staging"; fi).\n" - sudo dpkg -i ${PKGNAME}_${wine_version}-1_amd64.deb + echo -e "\nInstalling Wine$(if [[ ! -v NO_STAGING ]]; then printf " Staging"; fi).\n" + sudo dpkg -i ${PKGNAME}_$(wine_version)-1_amd64.deb } function storeDebianArchive() { cd "${WINEROOT}" - mv ${PKGNAME}_${wine_version}-1_amd64.deb ../../compiled_deb/"${datedir}" && \ + mv ${PKGNAME}_$(wine_version)-1_amd64.deb ../../compiled_deb/"${datedir}" && \ echo -e "Compiled ${PKGNAME} is stored at '$(readlink -f ../../compiled_deb/"${datedir}")/'\n" rm -rf winebuild_${datedir} } @@ -689,7 +832,7 @@ function cleanTree() { rm -rf "${WINEROOT}" } -########################################################### +######################################################## # Check presence of Wine if compiled deb is going to be installed # This function is not relevant if --no-install switch is used @@ -722,12 +865,17 @@ function wineCheck() { # Check existence of gstreamer girl package before further operations girl_check -########################## +############################ # Get Wine (& Wine-Staging) sources getWine -########################## +############################ + +# Check whether we need to update possible hash override +check_gitOverride + +############################ # Refresh & sync Wine (+ Wine Staging) git sources refreshWineGIT @@ -783,12 +931,12 @@ WineDeps install "${wine_deps_build_i386[*]}" "Wine build time (32-bit)" buildti wine32Build && echo -e "\nWine 32-bit build process finished.\n" -########################## +############################ # Remove i386 buildtime dependencies after successful compilation process WineDeps remove "${wine_deps_build_i386[*]}" "Wine build time (32-bit)" buildtime -########################## +############################ # i386/amd64 runtime dependencies have been tested and they are able to co-exist on Debian system @@ -806,18 +954,18 @@ if [[ ! -v NO_INSTALL ]]; then fi -########################## +############################ # Build time dependencies which were installed but no longer needed if [[ -v buildpkglist ]]; then if [[ -v BUILDPKG_RM ]]; then - sudo apt purge --remove -y "${buildpkglist[*]}" + sudo apt purge --remove -y ${buildpkglist[*]} else - 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" + echo -e "The following build time dependencies were installed and no longer required:\n\n$(for l in ${buildpkglist[*]}; do echo -e ${l}; done)\n" fi fi -########################## +############################ if [[ -v GIRL_CHECK ]]; then sudo apt install -y ${girlpkg} @@ -839,4 +987,3 @@ storeDebianArchive # Clean all temporary files cleanTree - diff --git a/debian_install_nvidia.sh b/debian_install_nvidia.sh index 2c8a29b..d1542f4 100755 --- a/debian_install_nvidia.sh +++ b/debian_install_nvidia.sh @@ -32,7 +32,7 @@ fi ######################################################## -# Just a title & author for this script, used in initialization and help page +# Just a title & author for this script, used in initialization SCRIPT_TITLE="\e[1mNvidia drivers package builder & installer\e[0m" SCRIPT_AUTHOR="Pekka Helenius (~Fincer), 2018" diff --git a/debian_install_winetricks.sh b/debian_install_winetricks.sh new file mode 100755 index 0000000..dd99a6c --- /dev/null +++ b/debian_install_winetricks.sh @@ -0,0 +1,313 @@ +#!/bin/env bash + +# Winetricks package builder for Debian +# Copyright (C) 2018 Pekka Helenius +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +############################################################################## + +# Check if we're using bash or sh to run the script. If bash, OK. +# If another one, ask user to run the script with bash. + +BASH_CHECK=$(ps | grep `echo $$` | awk '{ print $4 }') + +if [ $BASH_CHECK != "bash" ]; then + echo " +Please run this script using bash (/usr/bin/bash). + " + exit 1 +fi + +######################################################## + +# Just a title & author for this script, used in initialization + +SCRIPT_TITLE="\e[1mWinetricks package builder & installer\e[0m" +SCRIPT_AUTHOR="Pekka Helenius (~Fincer), 2018" + +######################################################## + +pkgname="winetricks" +pkgsrc="https://github.com/Winetricks/winetricks" +pkgurl="https://winetricks.org" + +# TODO Do not require wine as a hard dependency since +# it may break things. Wine is practically required, though. +# +pkgdeps_runtime=('cabextract' 'unzip' 'x11-utils') # 'wine' + +######################################################## + +WORKDIR="${PWD}" + +########################### + +# DO NOT CHANGE THIS if you intend to use this shell +# script as a part updatewine.sh shell script! + +BUILD_MAINDIR="${WORKDIR}/debian/winetricks-git" + +######################################################## + +echo -e "\n${SCRIPT_TITLE}\n" + +######################################################## + +# If the script is interrupted (Ctrl+C/SIGINT), do the following + +function Winetricks_intCleanup() { + rm -rf ${BUILD_MAINDIR} + exit 0 +} + +# Allow interruption of the script at any time (Ctrl + C) +trap "Winetricks_intCleanup" INT + +########################################################### + +COMMANDS=( + apt + dpkg + git + grep + sudo + wc +) + +function checkCommands() { + + if [[ $(which --help 2>/dev/null) ]] && [[ $(echo --help 2>/dev/null) ]]; then + + local a=0 + for command in ${@}; do + if [[ ! $(which $command 2>/dev/null) ]]; then + local COMMANDS_NOTFOUND[$a]=${command} + let a++ + fi + done + + if [[ -n $COMMANDS_NOTFOUND ]]; then + echo -e "\nError! The following commands could not be found: ${COMMANDS_NOTFOUND[*]}\nAborting\n" + exit 1 + fi + else + exit 1 + fi +} + +checkCommands "${COMMANDS[*]}" + +######################################################## + +function runtimeCheck() { + + # Runtime package names to check on Debian + local known_pkgs=${1} + +########################## + + # This array applies only if wine is defined + # as a runtime dependency for Winetricks + # + # 'dpkg -s' check is quite primitive, + # do this additional check for Wine + local known_wines=( + 'wine' + 'wine-stable' + 'wine32' + 'wine64' + 'libwine:amd64' + 'libwine:i386' + 'wine-git' + 'wine-staging-git' + ) + +########################## + + # Check if these packages are present on the system + i=0 + for pkg in ${known_pkgs[@]}; do + if [[ $(echo $(dpkg -s ${pkg} &>/dev/null)$?) -ne 0 ]]; then + local pkglist[$i]=${pkg} + let i++ + fi + done + + # This loop applies only if wine is defined + # as a runtime dependency for Winetricks + # + # If known wine is found, drop 'wine' from pkglist array + for winepkg in ${known_wines[@]}; do + if [[ $(echo $(dpkg -s ${winepkg} &>/dev/null)$?) -eq 0 ]]; then + pkglist=( "${pkglist[@]/wine}" ) + fi + done + + if [[ -n ${pkglist[*]} ]]; then + echo -e "\e[1mWARNING:\e[0m Not installing Winetricks because the following runtime dependencies are missing:\n\n$(for l in ${pkglist[*]}; do echo ${l}; done)\n\n\ +These should be installed in order to use Winetricks. Just compiling Winetricks for later use.\n" + + # Force --no-install switch + NO_INSTALL= + fi + +} + +######################################################## + +function winetricks_prepare() { + + # Define package folder path and create it + # Clone package source from 'pkgurl' + pkgdir="${BUILD_MAINDIR}/${pkgname}" + mkdir -p ${pkgdir} && \ + git clone ${pkgsrc} "${pkgdir}" + + if [[ $? -ne 0 ]]; then + echo -e "Error while downloading source of ${pkgname} package. Aborting\n" + exit 1 + fi + + # Parse package version field + function pkgver() { + cd "${pkgdir}" + git describe --long | sed 's/\-[^0-9].*//; s/\-/\./g' + if [[ $? -ne 0 ]]; then + echo -e "Error while parsing ${pkgname} version field. Aborting\n" + exit 1 + fi + } + + # Define package version field variable 'pkgver' + pkgver=$(pkgver) + + # Rename the source folder to meet the standards of Debian builder + cd "${BUILD_MAINDIR}" && \ + mv "${pkgname}" "${pkgname}-${pkgver}" + + # Source folder which is used now, just added version string suffix + pkgdir="${BUILD_MAINDIR}/${pkgname}-${pkgver}" + +} + +######################################################## + +function coredeps_check() { + + # Universal core build time dependencies for package compilation + _coredeps=('dh-make' 'make' 'gcc' 'build-essential' 'fakeroot') + + local i=0 + for coredep in ${_coredeps[@]}; do + + if [[ $(echo $(dpkg -s ${coredep} &>/dev/null)$?) -ne 0 ]]; then + echo -e "Installing core dependency ${coredep}.\n" + buildpkglist[$i]=${coredep} + sudo apt install -y ${coredep} + if [[ $? -ne 0 ]]; then + echo -e "Could not install ${coredep}. Aborting.\n" + exit 1 + fi + let i++ + fi + done + +} + +######################################################## + +function feed_debiancontrol() { + +cat << CONTROLFILE > "${pkgdir}/debian/control" +Source: ${pkgname} +Section: unknown +Priority: optional +Maintainer: ${USER} <${USER}@unknown> +Build-Depends: debhelper (>= 9) +Standards-Version: 3.9.8 +Homepage: ${pkgurl} + +Package: ${pkgname} +Architecture: all +Depends: $(echo "${pkgdeps_runtime[*]}" | sed 's/\s/, /g') +Suggests: wine +Description: Script to install various redistributable runtime libraries in Wine. + +CONTROLFILE + +} + +######################################################## + +function winetricks_debianbuild() { + + cd "${pkgdir}" + + # Delete existing debian folder + rm -rf debian + + # Create debian subdirectory + dh_make --createorig -s -y -c lgpl + + # Update debian/control file + feed_debiancontrol + + # Skip tests while executing deb builder + printf 'override_dh_auto_test:' | tee -a debian/rules + + # Remove irrelevant sample files + rm -rf debian/*.{ex,EX} + + # Start deb builder. Do not build either debug symbols or doc files + DEB_BUILD_OPTIONS="strip nodocs noddebs" dpkg-buildpackage -rfakeroot -b -us -uc + + if [[ $? -ne 0 ]]; then + echo -e "Error while compiling ${pkgname}. Check messages above. Aborting\n" + exit 1 + fi + + # Once compiled, possibly install and store the compiled deb archive + if [[ $? -eq 0 ]]; then + + if [[ ! -v NO_INSTALL ]]; then + sudo dpkg -i ../${pkgname}*.deb + fi + + mv ../${pkgname}*.deb "${WORKDIR}"/ && \ + cd "${WORKDIR}" + rm -rf "${BUILD_MAINDIR}" + else + exit 1 + fi + +} + +######################################################## + +runtimeCheck "${pkgdeps_runtime[*]}" + +winetricks_prepare + +# If we run this script via debian/updatewine_debian.sh, this check is already done there +coredeps_check + +winetricks_debianbuild + +######################################################## + +# Build time dependencies which were installed but no longer needed +if [[ -v buildpkglist ]]; then + echo -e "The following build time dependencies were installed and no longer needed:\n\n$(for l in ${buildpkglist[*]}; do echo ${l}; done)\n" +fi diff --git a/updatewine.sh b/updatewine.sh index c8356b5..cf7b1a9 100755 --- a/updatewine.sh +++ b/updatewine.sh @@ -37,6 +37,26 @@ fi SCRIPT_TITLE="\e[1mWine/Wine Staging & DXVK package builder & auto-installer\e[0m" SCRIPT_AUTHOR="Pekka Helenius (~Fincer), 2018" +######################################################## + +# Should we freeze Git versions of these packages? +# This is handy in some cases, if breakages occur +# (although we actually compile an older version of a package) +# +# Define a commit hash to freeze to +# Use keyword 'HEAD' if you want to use the latest git +# version available +# Do NOT leave these variable empty! + +git_commithash_dxvk=1af96347e1c6f1f2eb11aeb11009f380fd5761ec + +git_commithash_wine=HEAD + +# These apply only on Debian/Ubuntu/Mint +git_commithash_meson=5d6dcf8850fcc5d552f55943b6aa3582754dedf8 + +git_commithash_glslang=HEAD + ########################################################### # Allow interruption of the script at any time (Ctrl + C) trap "exit" INT @@ -112,9 +132,9 @@ fi # and pass them to the subscripts if supported i=0 -for arch_arg in ${@}; do +for arg in ${@}; do - case ${arch_arg} in + case ${arg} in --no-staging) # Do not build Wine staging version, just Wine ;; @@ -133,28 +153,71 @@ for arch_arg in ${@}; do --no-pol) # Skip PlayOnLinux Wine prefixes update process ;; + --no-winetricks) + # Do not build Winetricks, do not install DXVK + # Debian only + ;; *) echo -e "\n\ \ ${SCRIPT_TITLE} by ${SCRIPT_AUTHOR}\n\n\ Usage:\n\nbash updatewine.sh\n\nArguments:\n\n\ ---no-staging\tCompile Wine instead of Wine Staging\n\ ---no-install\tDo not install Wine or DXVK, just compile them. Wine, meson & glslang must be installed for DXVK compilation.\n\ ---no-wine\tDo not compile or install Wine/Wine Staging\n\ +--no-install\tDo not install Wine, Winetricks or DXVK, just compile them. Wine, meson & glslang must be installed for DXVK compilation.\n\ --no-dxvk\tDo not compile or install DXVK\n\ --no-pol\tDo not update PlayOnLinux Wine prefixes\n\n\ +--no-staging\tCompile Wine instead of Wine Staging\n\ +--no-wine\tDo not compile or install Wine/Wine Staging\n\ +--no-winetricks\t[Debian only] Do not compile or install Winetricks.\n\ +\t\tNo DXVK installation unless Winetricks already installed.\n\n\ Compiled packages are installed by default, unless '--no-install' argument is given.\n\ If '--no-install' argument is given, the script doesn't check or update your PlayOnLinux Wine prefixes.\n" exit 0 ;; esac - args[$i]="${arch_arg}" + args[$i]="${arg}" let i++ done ########################################################### +# Date timestamp and random number identifier for compiled +# DXVK & Wine Staging builds +# This variable is known as 'datedir' in other script files + +datesuffix=$(echo $(date '+%Y-%m-%d-%H%M%S')) + +########################################################### + +# Add git commit hash overrides to argument list +# Pass them to subscripts, as well. + +githash_overrides=( +"${git_commithash_dxvk}" +"${git_commithash_glslang}" +"${git_commithash_meson}" +"${git_commithash_wine}" +) + +############################# + +# Commit syntax validity check + +for githash in ${githash_overrides[@]}; do + + if [[ ! $(printf ${githash} | wc -c) -eq 40 ]] && \ + [[ ! ${githash} == HEAD ]]; then + echo -e "\nError: badly formatted commit hash '${githash}' in the script file 'updatewine.sh'. Aborting\n" + exit 1 + fi +done + +############################# + +params=(${datesuffix} ${githash_overrides[@]} ${args[@]}) + +########################################################### + function sudoQuestion() { sudo -k echo -e "\e[1mINFO:\e[0m sudo password required\n\nThis script requires elevated permissions for package updates & installations. Please provide your sudo password for these script commands. Sudo permissions are not used for any other purposes.\n" @@ -192,14 +255,6 @@ function checkInternet() { checkInternet -########################################################### - -# Date timestamp and random number identifier for compiled -# DXVK & Wine Staging builds -# This variable is known as 'datedir' in other script files - -datesuffix=$(echo $(date '+%Y-%m-%d-%H%M%S')) - ########################################################### # Only Debian & Arch based Linux distributions are currently supported @@ -251,4 +306,4 @@ if [[ ! -v NO_WINE ]] || [[ ! -v NO_DXVK ]]; then echo "" fi -bash -c "cd ${distro} && bash ./updatewine_${distro}.sh \"${datesuffix}\" ${args[*]}" +bash -c "cd ${distro} && bash ./updatewine_${distro}.sh ${params[*]}"