mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
507 lines
12 KiB
Bash
507 lines
12 KiB
Bash
#!/bin/sh
|
|
#
|
|
# Script to automatically install all Wine Staging patches
|
|
#
|
|
# Copyright (C) 2015-2017 Sebastian Lackner
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 2.1 of the License, or (at your option) any later version.
|
|
#
|
|
# This library 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
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
#
|
|
|
|
# Show usage information
|
|
usage()
|
|
{{
|
|
echo ""
|
|
echo "Usage: ./patchinstall.sh [DESTDIR=path] [--all] [-W patchset] [patchset ...]"
|
|
echo ""
|
|
echo "Autogenerated script to apply all Wine Staging patches on your Wine"
|
|
echo "source tree."
|
|
echo ""
|
|
echo "Configuration:"
|
|
echo " DESTDIR=path Specify the path to the wine source tree"
|
|
echo " --all Select all patches"
|
|
echo " --force-autoconf Run autoreconf and tools/make_requests after each patch"
|
|
echo " --help Display this help and exit"
|
|
echo " --no-autoconf Do not run autoreconf and tools/make_requests"
|
|
echo " --no-patchlist Do not apply patchlist (needed for 'wine --patches')"
|
|
echo " --upstream-commit Print the upstream Wine commit SHA1 and exit"
|
|
echo " --version Show version information and exit"
|
|
echo " -W patchset Exclude a specific patchset"
|
|
echo ""
|
|
echo "Backends:"
|
|
echo " --backend=patch Use regular 'patch' utility to apply patches (default)"
|
|
echo " --backend=eapply Use 'eapply' to apply patches (Gentoo only)"
|
|
echo " --backend=epatch Use 'epatch' to apply patches (Gentoo only, deprecated)"
|
|
echo " --backend=git-am Use 'git am' to apply patches"
|
|
echo " --backend=git-apply Use 'git apply' to apply patches"
|
|
echo " --backend=stg Import the patches using stacked git"
|
|
echo ""
|
|
}}
|
|
|
|
# Get the upstream commit sha
|
|
upstream_commit()
|
|
{{
|
|
echo "{upstream_commit}"
|
|
}}
|
|
|
|
# Show version information
|
|
version()
|
|
{{
|
|
echo "{staging_version}"
|
|
echo "Copyright (C) 2014-2017 the Wine Staging project authors."
|
|
echo ""
|
|
echo "Patchset to be applied on upstream Wine:"
|
|
echo " commit $(upstream_commit)"
|
|
echo ""
|
|
}}
|
|
|
|
# Critical error, abort
|
|
abort()
|
|
{{
|
|
printf '%s\n' "ERROR: $1" >&2
|
|
exit 1
|
|
}}
|
|
|
|
# Show a warning
|
|
warning()
|
|
{{
|
|
printf '%s\n' "WARNING: $1" >&2
|
|
}}
|
|
|
|
{patch_helpers}
|
|
|
|
# Default settings
|
|
patch_enable_all 0
|
|
enable_patchlist=1
|
|
enable_autoconf=1
|
|
patchlist="/dev/null"
|
|
backend="patch"
|
|
|
|
# Find location of patches
|
|
patchdir="$(dirname "$(readlink -f "$0")")"
|
|
if test ! -f "$patchdir/patchinstall.sh"; then
|
|
if test -f ./patchinstall.sh; then
|
|
patchdir="$(pwd)"
|
|
else
|
|
abort "Failed to find patch directory."
|
|
fi
|
|
fi
|
|
|
|
# Parse commandline arguments
|
|
if test "$#" -eq 0; then
|
|
abort "No commandline arguments given, don't know what to do."
|
|
fi
|
|
|
|
while test "$#" -gt 0; do
|
|
case "$1" in
|
|
DESTDIR=*)
|
|
DESTDIR="${{1#*=}}"
|
|
shift
|
|
;;
|
|
|
|
--all)
|
|
patch_enable_all 1
|
|
shift
|
|
;;
|
|
|
|
--backend=*)
|
|
backend="${{1#*=}}"
|
|
shift
|
|
;;
|
|
|
|
--force-autoconf)
|
|
enable_autoconf=2
|
|
shift
|
|
;;
|
|
|
|
--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
|
|
--no-patchlist)
|
|
enable_patchlist=0
|
|
shift
|
|
;;
|
|
|
|
--no-autoconf)
|
|
enable_autoconf=0
|
|
shift
|
|
;;
|
|
|
|
--upstream-commit)
|
|
upstream_commit
|
|
exit 0
|
|
;;
|
|
|
|
--version)
|
|
version
|
|
exit 0
|
|
;;
|
|
|
|
-W)
|
|
# Disable patchset
|
|
if ! patch_enable "$2" 2; then
|
|
abort "Wrong usage of -W commandline argument, expected patchname."
|
|
fi
|
|
shift
|
|
shift
|
|
;;
|
|
|
|
*)
|
|
# Enable patchset
|
|
if ! patch_enable "$1" 1; then
|
|
abort "Unknown commandline argument $1."
|
|
fi
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Determine DESTDIR if not explicitly specified
|
|
if test -z "$DESTDIR" -a -f ./tools/make_requests; then
|
|
DESTDIR="$(pwd)"
|
|
|
|
elif test ! -f "$DESTDIR/tools/make_requests"; then
|
|
abort "DESTDIR does not point to the Wine source tree."
|
|
fi
|
|
|
|
# Change directory to DESTDIR, eapply/epatch depends on that
|
|
if ! cd "$DESTDIR"; then
|
|
abort "Unable to change directory to $DESTDIR."
|
|
fi
|
|
|
|
# Helper to update configure / the wineserver protocol if required
|
|
if ! command -v diff >/dev/null 2>&1 ||
|
|
! command -v grep >/dev/null 2>&1 ||
|
|
! command -v cmp >/dev/null 2>&1; then
|
|
|
|
update_configure()
|
|
{{
|
|
autoreconf -f
|
|
}}
|
|
|
|
update_protocol()
|
|
{{
|
|
./tools/make_requests
|
|
}}
|
|
|
|
else
|
|
|
|
update_configure()
|
|
{{
|
|
_file="./configure"
|
|
|
|
if ! cp -a "$_file" "$_file.old"; then
|
|
abort "failed to create $_file.old"
|
|
fi
|
|
|
|
if ! autoreconf -f; then
|
|
rm "$_file.old"
|
|
unset _file
|
|
return 1
|
|
fi
|
|
|
|
# Shifting by 62 bits is undefined behaviour when off_t is 32-bit, see also
|
|
# https://launchpad.net/ubuntu/+source/autoconf/2.69-6 - the bug is still
|
|
# present in some other distros (including Archlinux).
|
|
_large_off_old="^#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))\$"
|
|
_large_off_new="#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))"
|
|
sed -i'' -e "s|$_large_off_old|$_large_off_new|g" "$_file"
|
|
unset _large_off_old _large_off_new
|
|
|
|
# Restore original timestamp when nothing changed
|
|
if ! cmp "$_file.old" "$_file" >/dev/null; then
|
|
rm "$_file.old"
|
|
else
|
|
mv "$_file.old" "$_file"
|
|
fi
|
|
|
|
unset _file
|
|
return 0
|
|
}}
|
|
|
|
update_protocol()
|
|
{{
|
|
_file="./include/wine/server_protocol.h"
|
|
|
|
if ! cp -a "$_file" "$_file.old"; then
|
|
abort "failed to create $_file.old"
|
|
fi
|
|
|
|
if ! ./tools/make_requests; then
|
|
rm "$_file.old"
|
|
unset _file
|
|
return 1
|
|
fi
|
|
|
|
# Restore original timestamp when nothing changed
|
|
if diff -u "$_file.old" "$_file" |
|
|
grep -v "^[+-]#define SERVER_PROTOCOL_VERSION" |
|
|
grep -v "^\(+++\|---\)" | grep -q "^[+-]"; then
|
|
rm "$_file.old"
|
|
else
|
|
mv "$_file.old" "$_file"
|
|
fi
|
|
|
|
unset _file
|
|
return 0
|
|
}}
|
|
fi
|
|
|
|
|
|
# Most backends will try to use git, either directly or indirectly.
|
|
# Unfortunately this does not work when "$DESTDIR" points to a
|
|
# subdirectory of a git tree, which has the effect that no patches
|
|
# are applied, but the exitcode is zero. To avoid broken builds we
|
|
# will workaround this issue or abort.
|
|
test ! -d ".git" && git rev-parse --git-dir >/dev/null 2>&1
|
|
workaround_git_bug="$?"
|
|
|
|
# Apply the patches using gitapply.sh, a small wrapper around 'patch'
|
|
if test "$backend" = "patch"; then
|
|
|
|
if test "$workaround_git_bug" -eq 0; then
|
|
gitapply_args="--nogit"
|
|
else
|
|
gitapply_args=""
|
|
fi
|
|
|
|
if test "$enable_autoconf" -gt 1; then
|
|
warning "Ignoring commandline argument --force-autoconf."
|
|
enable_autoconf=1
|
|
fi
|
|
|
|
patch_apply_file()
|
|
{{
|
|
printf '%s\n' "Applying $1"
|
|
if ! "$patchdir/gitapply.sh" $gitapply_args < "$1"; then
|
|
abort "Failed to apply patch, aborting!"
|
|
fi
|
|
}}
|
|
|
|
# 'eapply/epatch' backend - used on Gentoo
|
|
elif test "$backend" = "eapply" -o "$backend" = "epatch"; then
|
|
|
|
if test "$workaround_git_bug" -eq 0; then
|
|
gitapply_args="--nogit"
|
|
else
|
|
gitapply_args=""
|
|
fi
|
|
|
|
if ! command -v "$backend" >/dev/null 2>&1 || \
|
|
! command -v ebegin >/dev/null 2>&1 || \
|
|
! command -v eend >/dev/null 2>&1 || \
|
|
! command -v nonfatal >/dev/null 2>&1; then
|
|
abort "Shell functions $backend/ebegin/eend/nonfatal not found. You have to source this script from your ebuild."
|
|
fi
|
|
|
|
if test "$enable_autoconf" -gt 1; then
|
|
warning "Ignoring commandline argument --force-autoconf."
|
|
enable_autoconf=1
|
|
fi
|
|
|
|
patch_apply_file()
|
|
{{
|
|
_shortname="$(basename "$1")"
|
|
if grep -q "^GIT binary patch" "$1"; then
|
|
ebegin "Applying $_shortname"
|
|
"$patchdir/gitapply.sh" $gitapply_args < "$1"
|
|
if ! eend $?; then
|
|
exit 1
|
|
fi
|
|
else
|
|
# we are run from a subshell, so we can't call die
|
|
if ! nonfatal "$backend" "$1"; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
unset _shortname
|
|
}}
|
|
|
|
# GIT backend - apply patches using 'git am'
|
|
elif test "$backend" = "git" -o "$backend" = "git-am"; then
|
|
|
|
if test "$workaround_git_bug" -eq 0; then
|
|
abort "Backend 'git-am' not possible when DESTDIR points to a git subdirectory."
|
|
fi
|
|
|
|
patch_apply_file()
|
|
{{
|
|
printf '%s\n' "Applying $1"
|
|
if ! git am "$1"; then
|
|
abort "Failed to apply patch, aborting!"
|
|
fi
|
|
if test "$enable_autoconf" -gt 1; then
|
|
_do_commit=0
|
|
|
|
# Run 'autoreconf -f' if required
|
|
if git show --pretty=format: --name-only | grep -q "^\(configure.ac\|aclocal.m4\)$"; then
|
|
if ! update_configure; then
|
|
abort "'autoreconf -f' failed."
|
|
fi
|
|
git add ./configure
|
|
git add ./include/config.h.in
|
|
_do_commit=1
|
|
fi
|
|
|
|
# Run './tools/make_requests' if required
|
|
if git show --pretty=format: --name-only | grep -q "^server/"; then
|
|
if ! update_protocol; then
|
|
abort "'./tools/make_requests' failed."
|
|
fi
|
|
git add ./include/wine/server_protocol.h
|
|
git add ./server/trace.c
|
|
git add ./server/request.h
|
|
_do_commit=1
|
|
fi
|
|
|
|
if test "$_do_commit" -ne 0; then
|
|
if ! git commit --amend --reuse-message HEAD; then
|
|
abort "Failed to include autogenerated changes in commit."
|
|
fi
|
|
fi
|
|
|
|
unset _do_commit
|
|
fi
|
|
}}
|
|
|
|
# Git apply backend
|
|
elif test "$backend" = "git-apply"; then
|
|
|
|
if test "$workaround_git_bug" -eq 0; then
|
|
abort "Backend 'git-apply' not possible when DESTDIR points to a git subdirectory."
|
|
fi
|
|
|
|
if test "$enable_autoconf" -gt 1; then
|
|
warning "Ignoring commandline argument --force-autoconf."
|
|
enable_autoconf=1
|
|
fi
|
|
|
|
patch_apply_file()
|
|
{{
|
|
printf '%s\n' "Applying $1"
|
|
if ! git apply "$1"; then
|
|
abort "Failed to apply patch, aborting!"
|
|
fi
|
|
}}
|
|
|
|
# Stacked GIT backend - import the patches (mainly for developers)
|
|
elif test "$backend" = "stg"; then
|
|
|
|
if test "$workaround_git_bug" -eq 0; then
|
|
abort "Backend 'stg' not possible when DESTDIR points to a git subdirectory."
|
|
fi
|
|
|
|
# Only import the regular patches, no autogenerated ones -
|
|
# moreover, don't run autoreconf or ./tools/make_requests.
|
|
enable_patchlist=0
|
|
enable_autoconf=0
|
|
|
|
patch_apply_file()
|
|
{{
|
|
printf '%s\n' "Applying $1"
|
|
_shortname="$(basename "$1")"
|
|
if ! printf '%s\n' "staging/$_shortname" | cat - "$1" | stg import; then
|
|
abort "Failed to apply patch, aborting!"
|
|
fi
|
|
unset _shortname
|
|
}}
|
|
|
|
else
|
|
abort "Selected backend $backend not supported."
|
|
fi
|
|
|
|
patch_apply()
|
|
{{
|
|
patch_apply_file "$patchdir/$1"
|
|
}}
|
|
|
|
|
|
{patch_resolver}
|
|
|
|
|
|
# If autoupdate is enabled then create a tempfile to keep track of all patches
|
|
if test "$enable_patchlist" -eq 1; then
|
|
if test "$enable_Staging" -eq 1; then
|
|
patchlist=$(mktemp)
|
|
if test ! -f "$patchlist"; then
|
|
abort "Unable to create temporary file for patchlist."
|
|
fi
|
|
else
|
|
warning "Skipping generation of patchlist because 'Staging' patchset is disabled."
|
|
enable_patchlist=0
|
|
fi
|
|
fi
|
|
|
|
|
|
{patch_apply}
|
|
|
|
|
|
if test "$enable_patchlist" -eq 1; then
|
|
|
|
# Generate a temporary patch containing the patchlist and apply it
|
|
patch_data=$(cat "$patchlist" | sort)
|
|
if test ! -z "$patch_data"; then
|
|
patch_lines=$(printf '%s\n' "$patch_data" | wc -l)
|
|
patch_lines=$((${{patch_lines}}+21))
|
|
cat > "$patchlist" <<EOF
|
|
From: Wine Staging Team <webmaster@fds-team.de>
|
|
Subject: Autogenerated patch list.
|
|
|
|
diff --git a/libs/wine/config.c b/libs/wine/config.c
|
|
index 5262c76..0a3182f 100644
|
|
--- a/libs/wine/config.c
|
|
+++ b/libs/wine/config.c
|
|
@@ -478,10 +478,${{patch_lines}} @@ const char *wine_get_version(void)
|
|
return PACKAGE_VERSION;
|
|
}}
|
|
|
|
+static const struct
|
|
+{{
|
|
+ const char *author;
|
|
+ const char *subject;
|
|
+ int revision;
|
|
+}}
|
|
+wine_patch_data[] =
|
|
+{{
|
|
${{patch_data}}
|
|
+ {{ NULL, NULL, 0 }}
|
|
+}};
|
|
+
|
|
/* return the applied non-standard patches */
|
|
const void *wine_get_patches(void)
|
|
{{
|
|
- return NULL;
|
|
+ return &wine_patch_data[0];
|
|
}}
|
|
|
|
/* return the build id string */
|
|
EOF
|
|
patch_apply_file "$patchlist"
|
|
fi
|
|
rm "$patchlist"
|
|
fi
|
|
|
|
if test "$enable_autoconf" -eq 1; then
|
|
if ! update_configure; then
|
|
abort "'autoreconf -f' failed."
|
|
fi
|
|
if ! update_protocol; then
|
|
abort "'./tools/make_requests' failed."
|
|
fi
|
|
fi
|
|
# Success
|
|
exit 0
|