Browse Source

[Debian] Restructure Wine addons install script. Partial re-implementation

master
Pekka Helenius 2 years ago
parent
commit
9aec924b26
1 changed files with 284 additions and 93 deletions
  1. +284
    -93
      debian/wine_addons_root/wine_addons_build.sh

+ 284
- 93
debian/wine_addons_root/wine_addons_build.sh View File

@ -1,7 +1,7 @@
#!/bin/env bash
# Compile DXVK git on Debian/Ubuntu/Mint and variants
# Copyright (C) 2019 Pekka Helenius
# Copyright (C) 2019, 2022 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
@ -57,9 +57,9 @@ git_branch_dxvk=${params[8]}
git_branch_glslang=${params[9]}
git_branch_meson=${params[10]}
git_source_dxvknvapi=${params[12]}
git_source_vkd3dproton=${params[13]}
git_source_dxvk=${params[14]}
git_source_dxvknvapi_debian=${params[19]}
git_source_vkd3dproton_debian=${params[20]}
git_source_dxvk_debian=${params[21]}
git_source_glslang_debian=${params[15]}
git_source_meson_debian=${params[16]}
@ -119,7 +119,7 @@ known_wines=(
'wine-staging-git'
)
# Alternative remote dependency packages for Debian distributions which offer too old packages for DXVK
# Alternative remote dependency packages for Debian distributions which offer too old packages for Wine addons
#
# Left side: <package name in repositories>,<version_number>
# Right side: package alternative source URL
@ -127,27 +127,24 @@ known_wines=(
# NOTE: Determine these packages in corresponding debdata files as runtime or buildtime dependencies
#
# As this seems to be a dependency for binutils-mingw packages
function binutils_common_ver() {
if [[ $(dpkg -s binutils-common &>/dev/null)$? -ne 0 ]]; then
sudo apt -y install binutils-common
fi
if [[ $? -eq 0 ]]; then
binutils_ver=$(dpkg -s binutils-common | sed -rn 's/^Version: ([0-9\.]+).*$/\1/p')
fi
}
if [[ $(dpkg -s "binutils-common" &>/dev/null)$? -ne 0 ]]; then
sudo apt -y install "binutils-common"
fi
binutils_common_ver
binutils_ver=$(dpkg -s "binutils-common" | sed -rn 's/^Version: ([0-9\.]+).*$/\1/p')
remotePackagesUrls=(
"http://mirrors.edge.kernel.org/ubuntu/pool/universe/b/binutils-mingw-w64"
"http://mirrors.edge.kernel.org/ubuntu/pool/universe/g/gcc-mingw-w64"
"http://mirrors.edge.kernel.org/ubuntu/pool/universe/m/mingw-w64"
remote_package_repositories=(
"https://mirrors.edge.kernel.org/ubuntu/pool/universe/d/directx-headers"
"https://mirrors.edge.kernel.org/ubuntu/pool/main/i/isl"
"https://mirrors.edge.kernel.org/ubuntu/pool/universe/b/binutils-mingw-w64"
"https://mirrors.edge.kernel.org/ubuntu/pool/universe/g/gcc-mingw-w64"
"https://mirrors.edge.kernel.org/ubuntu/pool/universe/m/mingw-w64"
)
remotePackagesPool=(
remote_packages_pool=(
"directx-headers-dev"
"libisl22"
"gcc-mingw-w64-base"
"mingw-w64-common"
"binutils-mingw-w64-x86-64"
@ -160,60 +157,178 @@ remotePackagesPool=(
"g++-mingw-w64-i686"
)
typeset -A remotePackagesAlt
for rpp in ${remotePackagesPool[@]}; do
# NOTE: Package versions defined here *must* exist in some of the repositories!
typeset -A remote_packages_version_locks
remote_packages_version_locks=(
[directx-headers-dev]="1.606.4"
)
pkg_multi_data_binutils=()
typeset -A rpp_alternatives
typeset -A remote_packages_selected
typeset -A remote_packages_alt_available
for URL in "${remotePackagesUrls[@]}"; do
for rpp in "${remote_packages_pool[@]}"; do
# Fetch exact package name and associated date
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}")
version_len=100
new_rpp_url=
new_rpp_token=
version_lock=
version_lock_set=0
rpp_alternative_time=-1
alt_remote_epoch_time=-1
alt_remote_flat_version=-1
if [[ ${pkg_data} = "" ]]; then
continue
rpp_alternatives=()
remote_packages_alt_available=()
for package_version_lock in ${!remote_packages_version_locks[@]}; do
if [[ ${rpp} == ${package_version_lock} ]]; then
version_lock=${remote_packages_version_locks[${package_version_lock}]}
version_lock_set=1
break 1
fi
# Associate Unix-formatted date with the exact package name
IFS=$'\n'
for ps in ${pkg_data[@]}; do
ps_pkg=$(printf "%s" "${ps}" | awk '{print $1}')
ps_date=$(date --date=$(printf "%s" "${ps}" | awk '{print $NF}') +%s)
remotePackagesAltDate+=("${ps_date}|${ps_pkg}")
done
IFS=" "
done
for source_url in "${remote_package_repositories[@]}"; do
# Fetch exact package name and associated date.
# rpp_rx is just for regex escaping purposes.
rpp_rx=$(echo ${rpp} | sed 's/\+/\\\+/g')
pkg_multi_data=(
$(curl -s "${source_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 -E "${rpp_rx}_[0-9]" | xargs echo
)
)
# Sort exact package names by date
remotePackagesAltDateSorted=($(sort <<<"${remotePackagesAltDate[*]}"))
[[ ${#pkg_multi_data[@]} -eq 0 ]] && continue
# binutils packages depend on system binutils-common. Versions must match, even if not the newest package available.
if [[ ${ps_pkg} =~ binutils ]] && [[ ${binutils_ver} != "" ]]; then
for b in ${remotePackagesAltDateSorted[@]}; do
# binutils packages depend on system binutils-common.
# Versions must match, even if the newest package is not available.
if [[ ${rpp} =~ binutils ]] && [[ ${binutils_ver} != "" ]]; then
for b in "${pkg_multi_data[@]}"; do
if [[ ${b} =~ ${binutils_ver} ]]; then
remotePackagesAltBinUtils+=(${b})
pkg_multi_data_binutils+=("${b}")
fi
done
unset remotePackagesAltDateSorted
remotePackagesAltDateSorted=(${remotePackagesAltBinUtils[@]})
unset remotePackagesAltBinUtils
pkg_multi_data=( ${pkg_multi_data_binutils[@]} )
unset pkg_multi_data_binutils
fi
# Get the newest exact package name
pkg=$(printf "%s" ${remotePackagesAltDateSorted[-1]} | sed -r 's/^[0-9]+\|(.*)/\1/')
unset remotePackagesAltDate
unset remotePackagesAltDateSorted
# TODO: Remove duplicate functionality
# Check relevant version parts while collecting
# different versions of a package.
# version_len is count of relevant parts.
#
# For instance
# - In a case of versions 2.23.1, 2.28 and 2.34.6.1
# count of relevant parts is 2 as determined by
# version 2.28.
# In this fair comparison, we therefore consider
# normalized version 2.23, 2.28 and 2.34
#
for pkg_data in "${pkg_multi_data[@]}"; do
rpp_pkg=$(printf '%s' "${pkg_data}" | awk -F '|' '{print $1}')
rpp_version_raw=$(printf '%s' $(echo "${rpp_pkg}" | sed -r 's/.*_(.*[0-9]+)\-.*_(all|amd64).*/\1/g;'))
version_parts=( $(echo ${rpp_version_raw} | sed 's/\./ /g') )
new_version_len=$(printf '%d' ${#version_parts[@]})
if [[ ${new_version_len} -lt ${version_len} ]]; then
version_len=${new_version_len}
fi
# Prepare and set a well-formatted value into remotePackagesAlt associative array
if [ ! "${pkg}" == "" ]; then
rpp_url=$(printf "%s/%s" "${URL}" "${pkg}")
rpp_shortver=$(printf "%s" "${pkg}" | sed -r 's/.*_(.*[0-9]+)\-.*_(all|amd64).*/\1/g; s/[^0-9]//g')
done
rpp_token=$(printf "%s,%d" "${rpp}" "${rpp_shortver}")
remotePackagesAlt+=(["${rpp_token}"]="${rpp_url}")
# Add each version of a package into associated array remote_packages_alt_available
# We collect the next information here for each entry:
# - package normalized version number
# - package release date in epoch format
# - package source root url and .deb name
#
# This information is collected so that we can determine which
# package version to use, and which URL is associated to it.
#
for pkg_data in "${pkg_multi_data[@]}"; do
rpp_pkg=$(printf '%s' "${pkg_data}" | awk -F '|' '{print $1}')
rpp_epoch_time=$(date --date=$(printf '%s' "${ps}" | awk -F '|' '{print $2}') +%s)
rpp_version_raw=$(printf '%s' $(echo "${rpp_pkg}" | sed -r 's/.*_(.*[0-9]+)\-.*_(all|amd64).*/\1/g;'))
version_parts=( $(echo ${rpp_version_raw} | sed 's/\./ /g') )
relevant_version_parts=( ${version_parts[@]:0:${version_len}} )
rpp_flat_version=$(printf '%d' $(echo ${relevant_version_parts[@]} | sed 's/ //g'))
rpp_dot_version=$(echo ${relevant_version_parts[@]} | sed 's/ /./g')
rpp_token=$(printf '%s,%d,%d,%s' "${rpp}" "${rpp_epoch_time}" "${rpp_flat_version}" "${rpp_dot_version}")
rpp_url=$(printf '%s/%s' "${source_url}" "${rpp_pkg}")
remote_packages_alt_available+=(["${rpp_token}"]="${rpp_url}")
done
done
# For collected package versions, get the highest available
#
for alt_remote_package in "${!remote_packages_alt_available[@]}"; do
new_alt_remote_epoch_time=$(echo ${alt_remote_package} | awk -F ',' '{print $2}')
new_alt_remote_flat_version=$(echo ${alt_remote_package} | awk -F ',' '{print $3}')
new_alt_remote_dot_version=$(echo ${alt_remote_package} | awk -F ',' '{print $4}')
# TODO: Remove duplicate functionality
if [[ ${version_lock} =~ ${new_alt_remote_dot_version} ]]; then
alt_remote_epoch_time=${new_alt_remote_epoch_time}
alt_remote_flat_version=${new_alt_remote_flat_version}
alt_remote_dot_version=${new_alt_remote_dot_version}
new_rpp_token=${alt_remote_package}
new_rpp_url=${remote_packages_alt_available[${alt_remote_package}]}
rpp_alternatives+=(["${new_rpp_token}"]="${new_rpp_url}|${alt_remote_epoch_time}|${alt_remote_flat_version}")
break 1
fi
if [[ ${new_alt_remote_flat_version} -ge ${alt_remote_flat_version} ]] && [[ ${version_lock_set} -eq 0 ]]; then
alt_remote_epoch_time=${new_alt_remote_epoch_time}
alt_remote_flat_version=${new_alt_remote_flat_version}
alt_remote_dot_version=${new_alt_remote_dot_version}
new_rpp_token=${alt_remote_package}
new_rpp_url=${remote_packages_alt_available[${alt_remote_package}]}
rpp_alternatives+=(["${new_rpp_token}"]="${new_rpp_url}|${alt_remote_epoch_time}|${alt_remote_flat_version}")
fi
done
# Do epoch time comparison for collected package versions
#
for rpp_alternative in ${!rpp_alternatives[@]}; do
new_rpp_alternative=${rpp_alternative}
new_rpp_alternative_time=$(printf '%d' $(echo ${rpp_alternative} | awk -F '|' '{print $2}') )
if [[ ${new_rpp_alternative_time} -gt ${rpp_alternative_time} ]]; then
rpp_alternative_time=${new_rpp_alternative_time}
fi
rpp_alternative=${new_rpp_alternative}
done
remote_packages_selected+=( ["${rpp}"]=$(echo "${rpp_alternatives[$rpp_alternative]}|${version_lock_set}") )
done
# Posix-compliant MingW alternative executables
@ -238,7 +353,7 @@ tempLinks=(
########################################################
function runtimeCheck() {
function runtime_check() {
local pkgreq_name
local known_pkgs
@ -272,14 +387,14 @@ ${pkgreq_name} should be installed in order to use DXVK, DXVK NVAPI and VKD3D Pr
# If the script is interrupted (Ctrl+C/SIGINT), do the following
function wineAddonsIntCleanup() {
function wine_addons_int_cleanup() {
rm -rf ${WINE_ADDONS_ROOT}/{dxvk-git,meson,glslang,*.deb}
rm -rf ${WINE_ADDONS_ROOT}/../compiled_deb/"${datedir}"
exit 0
}
# Allow interruption of the script at any time (Ctrl + C)
trap "wineAddonsIntCleanup" INT
trap "wine_addons_int_cleanup" INT
########################################################
@ -301,7 +416,7 @@ fi
# Check do we need to compile the package
# given as input for this function
function pkgcompilecheck() {
function pkg_compile_check() {
local install_function
local pkg
@ -360,12 +475,12 @@ function addon_install_custom() {
# ADDON - CUSTOM PATCHES
# Add and apply custom addon patches
function addon_custompatches() {
function addon_custom_patches() {
local CURDIR
local dxvk_builddir_name
local dxvk_builddir_path
# Get our current directory, since we will change it during patching process below
# We want to go back here after having applied the patches
CURDIR="${PWD}"
@ -378,7 +493,7 @@ function addon_install_custom() {
# TODO Expecting just one folder here. This method doesn't work with multiple dirs present
if [[ $(echo ${dxvk_builddir_name} | wc -l) -gt 1 ]]; then
echo -e "\e[1mERROR:\e[0m Multiple entries in dxvk build directory detected. Can't decide which one to use. Aborting\n"
echo -e "\e[1mERROR:\e[0m Multiple entries in addon build directory detected. Can't decide which one to use. Aborting\n"
exit 1
fi
@ -387,12 +502,12 @@ function addon_install_custom() {
cd "${dxvk_builddir_path}"
for pfile in ../*.{patch,diff}; do
if [[ -f ${pfile} ]]; then
echo -e "Applying DXVK patch: ${pfile}\n"
echo -e "Applying addon's patch: ${pfile}\n"
patch -Np1 < ${pfile}
fi
if [[ $? -ne 0 ]]; then
echo -e "\e[1mERROR:\e[0m Error occured while applying DXVK patch '${pfile}'. Aborting\n"
echo -e "\e[1mERROR:\e[0m Error occured while applying addon's patch '${pfile}'. Aborting\n"
cd ${CURDIR}
exit 1
fi
@ -408,7 +523,7 @@ function addon_install_custom() {
############################
# ADDON - CUSTOM HOOKS EXECUTION
addon_custompatches && \
addon_custom_patches && \
addon_posixpkgs
}
@ -421,12 +536,12 @@ function fetch_extra_pkg_files() {
local pkgname
local pkgdir
local extra_files_dir
pkgname=${1}
pkgdir=${2}
extra_files_dir=${3}
cp -r ${extra_files_dir}/ ${pkgdir}/
find ${extra_files_dir} -mindepth 1 -type f -exec cp -f {} ${pkgdir}/ \;
}
@ -461,10 +576,11 @@ function compile_and_install_deb() {
local _pkg_debbuilder="${15}"
local _pkg_debcompat="${16}"
local _pkg_compatfile="${17}"
local extra_files_dir=$(find "../../extra_files/" -type d -iname "${_pkg_name%-git}")
if [[ -d ${extra_files_dir} ]]; then
[[ ! -d "debian/source" ]] && mkdir -p "debian/source"
fetch_extra_pkg_files ${_pkg_name} "debian/source" ${extra_files_dir}
fi
@ -481,7 +597,7 @@ function compile_and_install_deb() {
local s
local IFS
local y
arrays=(
'_pkg_deps_build'
'_pkg_deps_runtime'
@ -507,13 +623,47 @@ function compile_and_install_deb() {
############################
function pkg_installcheck() {
return $(echo $(dpkg -s "${1}" &>/dev/null)$?)
local full_pkg_name_found
full_pkg_name_found_return_code=$(echo $(dpkg -s "${1}" &>/dev/null)$?)
# Bad and error-prone fallback
if [[ ${full_pkg_name_found_return_code} -ne 0 ]]; then
full_pkg_name_matches=$(dpkg --get-selections | awk '{print $1}' | grep ^${1} | wc -l)
if [[ ${full_pkg_name_matches} -ne 0 ]]; then
full_pkg_name_found_return_code=0
fi
fi
return ${full_pkg_name_found_return_code}
}
############################
echo -e "Starting compilation$(if [[ ! -v NO_INSTALL ]] || [[ ${_pkg_name} =~ ^meson|glslang$ ]]; then printf " & installation"; fi) of ${_pkg_name}\n"
############################
function get_locked_packages() {
local _lock_pkgs
# Generate a list of version-locked-dependencies
if [[ ${#remote_packages_selected[@]} -gt 0 ]]; then
for alt_remote_pkg in ${!remote_packages_selected[@]}; do
alt_remote_version_lock_set=$(echo ${remote_packages_selected[${alt_remote_pkg}]} | awk -F '|' '{print $4}')
if [[ ${alt_remote_version_lock_set} -eq 1 ]]; then
_lock_pkgs+=(${alt_remote_pkg})
fi
done
fi
echo "${_lock_pkgs[*]}"
}
############################
# COMMON - PACKAGE DEPENDENCIES CHECK
@ -527,11 +677,15 @@ function compile_and_install_deb() {
local a
local b
local _validlist
local _lock_pkgs
local is_locked
local IFS
_pkg_list=("${1}")
_pkg_type="${2}"
_lock_pkgs=($(get_locked_packages))
IFS=$'\n'
_pkg_list=$(echo "${_pkg_list}" | sed 's/([^)]*)//g')
unset IFS
@ -549,10 +703,20 @@ function compile_and_install_deb() {
return 0
fi
# Generate a list of missing dependencies
a=0
# Generate a list of missing dependencies
for p in ${_pkg_list[@]}; do
if [[ $(pkg_installcheck ${p%% *})$? -ne 0 ]]; then
is_locked=0
for lock_pkg in "${_lock_pkgs[@]}"; do
if [[ ${p%% *} == ${lock_pkg} ]]; then
is_locked=1
break 1
fi
done
if [[ $(pkg_installcheck ${p%% *})$? -ne 0 ]] || [[ ${is_locked} -eq 1 ]]; then
_validlist[$a]=${p%% *}
let a++
@ -588,30 +752,53 @@ function compile_and_install_deb() {
for _pkg_dep in ${_validlist[@]}; do
echo -e "$(( $b + 1 ))/$(( ${#_validlist[*]} )) - Installing ${_pkg_name} ${_pkg_type_str} dependency ${_pkg_dep}"
if [[ ${#remotePackagesAlt[@]} -gt 0 ]]; then
for altRemote in ${!remotePackagesAlt[@]}; do
altRemotepkg=$(echo ${altRemote} | awk -F ',' '{print $1}')
altRemotever=$(echo ${altRemote} | awk -F ',' '{print $2}')
if [[ "${_pkg_dep}" == "${altRemotepkg}" ]]; then
if [[ $(pkg_installcheck ${altRemotepkg})$? -ne 0 ]]; then
if [[ ${#remote_packages_selected[@]} -gt 0 ]]; then
for alt_remote_pkg in ${!remote_packages_selected[@]}; do
if [[ "${_pkg_dep}" == "${alt_remote_pkg}" ]]; then
alt_remote_url=$(echo ${remote_packages_selected[${alt_remote_pkg}]} | awk -F '|' '{print $1}')
alt_remote_version=$(echo ${remote_packages_selected[${alt_remote_pkg}]} | awk -F '|' '{print $3}')
alt_remote_version_lock_set=$(echo ${remote_packages_selected[${alt_remote_pkg}]} | awk -F '|' '{print $4}')
# If remote pkg is not installed
if [[ $(pkg_installcheck ${alt_remote_pkg})$? -ne 0 ]]; then
# TODO remove duplicate functionality
if [[ $(apt-cache show "${altRemotepkg}" | grep -m1 -oP "(?<=^Version: )[0-9|\.]*" | sed 's/\.//g') < ${altRemotever} ]]; then
pkg_localinstall ${remotePackagesAlt["${altRemote}"]} "${altRemotepkg}"
pkg_configure "${altRemotepkg}" ${remotePackagesAlt["${altRemote}"]}
repository_version=$(apt-cache show "${alt_remote_pkg}" 2>/dev/null | grep -m1 -oP "(?<=^Version: )[0-9|\.]*" | sed 's/\.//g')
[[ ! -z ${repository_version} ]] && repository_version=0
if [[ ${repository_version} -eq ${alt_remote_version} ]]; then
echo -e "Already updated. Skipping"
continue 1
fi
if [[ ${repository_version} -lt ${alt_remote_version} ]] || [[ ${alt_remote_version_lock_set} -eq 1 ]]; then
pkg_localinstall "${alt_remote_url}" "${alt_remote_pkg}"
pkg_configure "${alt_remote_pkg}" "${alt_remote_url}"
else
pkg_remoteinstall "${altRemotepkg}"
pkg_configure "${altRemotepkg}"
pkg_remoteinstall "${alt_remote_pkg}"
pkg_configure "${alt_remote_pkg}"
fi
# If remote pkg is installed
else
if [[ $(dpkg -s "${altRemotepkg}" | grep -m1 -oP "(?<=^Version: )[0-9|\.]*" | sed 's/\.//g') < ${altRemotever} ]]; then
pkg_localinstall ${remotePackagesAlt["${altRemote}"]} "${altRemotepkg}"
pkg_configure "${altRemotepkg}" ${remotePackagesAlt["${altRemote}"]}
else
pkg_remoteinstall "${altRemotepkg}"
pkg_configure "${altRemotepkg}"
local_version=$(dpkg -s "${alt_remote_pkg}" | grep -m1 -oP "(?<=^Version: )[0-9|\.]*" | sed 's/\.//g')
[[ ! -z ${local_version} ]] && local_version=0
if [[ ${local_version} -eq ${alt_remote_version} ]]; then
echo -e "Already updated. Skipping"
continue 1
fi
if [[ ${local_version} -lt ${alt_remote_version} ]] || [[ ${alt_remote_version_lock_set} -eq 1 ]]; then
pkg_localinstall "${alt_remote_url}" "${alt_remote_pkg}"
pkg_configure "${alt_remote_pkg}" "${alt_remote_url}"
else
pkg_remoteinstall "${alt_remote_pkg}"
pkg_configure "${alt_remote_pkg}"
fi
fi
fi
done
@ -702,10 +889,14 @@ function compile_and_install_deb() {
# Access the folder after which package specific debianbuild function will be run
# That function is defined inside package specific install_main function below
if [[ $? -eq 0 ]]; then
pkg_gitversion && \
mv ${_pkg_name} ${_pkg_name}-${_pkg_gitver}
cd ${_pkg_name}-${_pkg_gitver}
# Get all required submodules
git submodule update --init --recursive
dh_make --createorig -s -y -c ${_pkg_license} && \
pkg_override_debianfile "${_pkg_debinstall}" "${_pkg_installfile}"
pkg_override_debianfile "${_pkg_debcontrol}" "${_pkg_controlfile}"
@ -883,13 +1074,13 @@ function pkg_install_main() {
########################################################
# Check existence of known Wine packages
runtimeCheck Wine "${known_wines[*]}"
runtime_check Wine "${known_wines[*]}"
# Meson - compile (& install)
pkgcompilecheck pkg_install_main meson "${WINE_ADDONS_ROOT}/../debdata/meson.debdata"
pkg_compile_check pkg_install_main meson "${WINE_ADDONS_ROOT}/../debdata/meson.debdata"
# Glslang - compile (& install)
pkgcompilecheck pkg_install_main glslang "${WINE_ADDONS_ROOT}/../debdata/glslang.debdata"
pkg_compile_check pkg_install_main glslang "${WINE_ADDONS_ROOT}/../debdata/glslang.debdata"
if [[ ! -v NO_DXVK ]]; then
# DXVK - compile (& install)


Loading…
Cancel
Save