#!/bin/sh # # Script to automatically install all Wine Staging patches # # Copyright (C) 2015 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. This script replaces and enhances the old method of" echo "using a Makefile." echo "" echo "Configuration:" echo " DESTDIR=path Specify the path to the wine source tree" echo " --all Select all patches" echo " --help Display this help and exit" echo " --no-patchlist Do not apply patchlist (needed for 'wine --patches')" echo " --no-autoconf Do not run autoreconf and tools/make_requests" echo " -W patchset Exclude a specific patchset" echo "" echo "Backends:" echo " --backend=patch Use regular 'patch' utility to apply patches (default)" echo " --backend=epatch Use 'epatch' to apply patches (Gentoo only)" 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 "" }} # Critical error, abort abort() {{ echo "ERROR: $1" >&2 exit 1 }} {patch_helpers} # Default settings patch_enable_all 0 enable_patchlist=1 enable_autoconf=1 patchlist="/dev/null" backend="patch" enable=1 if test "$#" -eq 0; then abort "No commandline arguments given, don't know what to do." fi # Parse commandline arguments while test "$#" -gt 0; do if patch_enable "$1" "$enable"; then shift enable=1 continue fi if test "$enable" -ne 1; then abort "Wrong use of -W commandline argument, expected patchname." fi case "$1" in DESTDIR=*) DESTDIR="${{1#*=}}" shift ;; --all) patch_enable_all 1 shift ;; --backend=*) backend="${{1#*=}}" shift ;; --help) usage exit 0 ;; --no-patchlist) enable_patchlist=0 shift ;; --no-autoconf) enable_autoconf=0 shift ;; -W) enable=2 shift ;; *) abort "Unknown commandline argument $1" exit 1 esac done if test "$enable" -ne 1; then abort "Missing argument for -W, expected patchname." fi # 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 # 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. For more information see # https://github.com/wine-compholio/wine-staging/issues/7 test ! -d "$DESTDIR/.git" && (cd "$DESTDIR"; git rev-parse --git-dir) &> /dev/null 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 patch_apply () {{ echo "Applying $1" if ! ../debian/tools/gitapply.sh $gitapply_args -d "$DESTDIR" < "$1"; then abort "Failed to apply patch, aborting!" fi }} # 'epatch' backend - used on Gentoo elif test "$backend" = "epatch"; then if test "$workaround_git_bug" -eq 0; then gitapply_args="--nogit" else gitapply_args="" fi patch_apply () {{ if grep -q "^GIT binary patch" "$1"; then if ! ../debian/tools/gitapply.sh $gitapply_args -d "$DESTDIR" < "$1"; then abort "Failed to apply patch, aborting!" fi else current_patch="$(readlink -f "$1")" if ! (cd "$DESTDIR" && epatch "$current_patch"); then abort "Failed to apply patch, aborting!" fi fi }} # 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 () {{ echo "Applying $1" if ! cat "$1" | (cd "$DESTDIR" && git am); then abort "Failed to apply patch, aborting!" 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 patch_apply () {{ echo "Applying $1" if ! cat "$1" | (cd "$DESTDIR" && git apply); 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 () {{ echo "Applying $1" if ! echo "staging/$1" | cat - "$1" | (cd "$DESTDIR" && stg import); then abort "Failed to apply patch, aborting!" fi }} else abort "Selected backend $backend not supported." fi {patch_resolver} # To make sure we find all the patches and tools switch to the patches directory now script="$(readlink -f "$0")" curdir="$(dirname "$script")" if test -f "$curdir/patchinstall.sh"; then if ! cd "$curdir"; then abort "Failed to change working directory to $curdir." fi elif test ! -f ./patchinstall.sh; then abort "Failed to find patch directory." fi # If autoupdate is enabled then create a tempfile to keep track of all patches if test "$enable_patchlist" -eq 1; then patchlist=$(mktemp) if test ! -f "$patchlist"; then abort "Unable to create temporary file for patchlist." 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) patch_lines=$(echo "$patch_data" | wc -l) if test ! -z "$patch_data"; then patch_lines=$((${{patch_lines}}+23)) cat > "$patchlist" < Subject: Autogenerated patch list. diff --git a/include/wine/library.h b/include/wine/library.h --- a/include/wine/library.h +++ b/include/wine/library.h @@ -43,6 +43,7 @@ extern const char *wine_get_data_dir(void); extern const char *wine_get_server_dir(void); extern const char *wine_get_user_name(void); extern const char *wine_get_version(void); +extern const void *wine_get_patches(void); extern const char *wine_get_build_id(void); extern void wine_init_argv0_path( const char *argv0 ); extern void wine_exec_wine_binary( const char *name, char **argv, const char *env_var ); diff --git a/libs/wine/config.c b/libs/wine/config.c index a273502..0a3182f 100644 --- a/libs/wine/config.c +++ b/libs/wine/config.c @@ -478,6 +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 &wine_patch_data[0]; +}} + /* return the build id string */ const char *wine_get_build_id(void) {{ diff --git a/libs/wine/wine.def b/libs/wine/wine.def index ed315bd..5b42029 100644 --- a/libs/wine/wine.def +++ b/libs/wine/wine.def @@ -83,6 +83,7 @@ EXPORTS wine_get_sortkey wine_get_user_name wine_get_version + wine_get_patches wine_init wine_init_argv0_path wine_is_dbcs_leadbyte diff --git a/libs/wine/wine.map b/libs/wine/wine.map index 2159fac..7cb2918 100644 --- a/libs/wine/wine.map +++ b/libs/wine/wine.map @@ -90,6 +90,7 @@ WINE_1.0 wine_get_ss; wine_get_user_name; wine_get_version; + wine_get_patches; wine_init; wine_init_argv0_path; wine_is_dbcs_leadbyte; EOF patch_apply "$patchlist" fi rm "$patchlist" fi if test "$enable_autoconf" -eq 1; then if ! (cd "$DESTDIR" && autoreconf -f); then abort "'autoreconf -f' failed." fi if ! (cd "$DESTDIR" && ./tools/make_requests); then abort "'./tools/make_requests' failed." fi fi # Success exit 0