diff options
-rw-r--r-- | mk/buildhlp.mk | 4 | ||||
-rw-r--r-- | mk/vars.mk | 4 | ||||
-rw-r--r-- | scripts/patch_git.sh | 105 | ||||
-rw-r--r-- | scripts/update-patches-git | 31 | ||||
-rw-r--r-- | target/config/Config.in.adk | 12 |
5 files changed, 156 insertions, 0 deletions
diff --git a/mk/buildhlp.mk b/mk/buildhlp.mk index 0b6979ab2..c2aeb3800 100644 --- a/mk/buildhlp.mk +++ b/mk/buildhlp.mk @@ -97,6 +97,9 @@ ${WRKDIST}/.prepared: ${WRKDIST}/.extract_done endif update-patches host-update-patches: +ifneq (${ADK_UPDATE_PATCHES_GIT},) + PATH='${HOST_PATH}' ${BASH} $(SCRIPT_DIR)/update-patches-git "${WRKDIST}" +else @test ! -d ${WRKDIR}.orig || rm -rf ${WRKDIR}.orig @test ! -d ${WRKDIR}.orig ifeq ($(strip ${_IN_PACKAGE})$(strip ${_IN_CVTC}),1) @@ -115,5 +118,6 @@ endif PATH=$(call shellescape,${HOST_PATH}) \ $(call shellexport,DIFF_IGNOREFILES) \ mksh ${ADK_TOPDIR}/scripts/update-patches2 +endif .PHONY: update-patches host-update-patches diff --git a/mk/vars.mk b/mk/vars.mk index 91587382e..20f7698d9 100644 --- a/mk/vars.mk +++ b/mk/vars.mk @@ -282,7 +282,11 @@ endif HOST_CPPFLAGS:= -I$(STAGING_HOST_DIR)/usr/include HOST_LDFLAGS:= -L$(STAGING_HOST_DIR)/usr/lib -Wl,-rpath -Wl,${STAGING_HOST_DIR}/usr/lib +ifneq (${ADK_UPDATE_PATCHES_GIT},) +PATCH= PATH='${HOST_PATH}' ${BASH} $(SCRIPT_DIR)/patch_git.sh +else PATCH= PATH='${HOST_PATH}' ${BASH} $(SCRIPT_DIR)/patch.sh +endif PATCHP0= PATH='${HOST_PATH}' patch -p0 ifeq ($(ADK_STATIC_TOOLCHAIN),y) diff --git a/scripts/patch_git.sh b/scripts/patch_git.sh new file mode 100644 index 000000000..36a2d6af8 --- /dev/null +++ b/scripts/patch_git.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash +# +# Patch sources using git-am, aligning things to use git-format-patch for +# update-patches. +# +# (c) 2016 Phil Sutter <phil@nwl.cc> +# +# Based on the classic patch.sh, written by: +# +# (c) 2006, 2007 Thorsten Glaser <tg@freewrt.org> +# (c) 2002 Erik Andersen <andersen@codepoet.org> + +[[ -n $BASH_VERSION ]] && shopt -s extglob + +# Set directories from arguments, or use defaults. +targetdir=${1-.} +patchdir=${2-../patches} +patchpattern=${3-*} + +if [ ! -d "${targetdir}" ] ; then + echo "Aborting. '${targetdir}' is not a directory." + exit 1 +fi +if [ ! -d "${patchdir}" ] ; then + echo "Aborting. '${patchdir}' is not a directory." + exit 0 +fi + +wd=$(pwd) + +cd "${targetdir}" +if [ ! -d .git ]; then + # drop leftover .gitignores in non-git sources, they + # might prevent us from patching 'temporary' files + # which are still present in the tarball. + find . -name .gitignore -delete + git init + git add . + git commit -a --allow-empty \ + --author="OpenADK <wbx@openadk.org>" \ + -m "OpenADK patch marker: 0000" +fi +[ -e .git/rebase-apply ] && \ + git am --abort + +i=1 +patch_tmp=$(printf ".git/patch_tmp/%04d" $i) +while [ -d $patch_tmp ]; do + let "i++" + patch_tmp=$(printf ".git/patch_tmp/%04d" $i) +done +mkdir -p $patch_tmp +patch_series=$(printf "%04d" $i) + +cd $wd +cd $patchdir +for i in $(eval echo ${patchpattern}); do + test -e "$i" || continue + i=$patchdir/$i + cd $wd + case $i in + *.gz) + type="gzip"; uncomp="gunzip -dc"; ;; + *.bz) + type="bzip"; uncomp="bunzip -dc"; ;; + *.bz2) + type="bzip2"; uncomp="bunzip2 -dc"; ;; + *.zip) + type="zip"; uncomp="unzip -d"; ;; + *.Z) + type="compress"; uncomp="uncompress -c"; ;; + *) + type="plaintext"; uncomp="cat"; ;; + esac + [ -d "${i}" ] && echo "Ignoring subdirectory ${i}" && continue + echo "$(basename $i)" >>${targetdir}/${patch_tmp}/__patchfiles__ + fake_hdr="" + patchname="$(basename -s .gz -s .bz -s .bz2 -s .zip -s .Z -s .patch $i)" + if ! grep -q '^Subject: ' ${i}; then + fake_hdr="From: OpenADK <wbx@openadk.org>\nSubject: [PATCH] ${patchname#[0-9]*-}\n\n" + fi + { echo -en $fake_hdr; ${uncomp} ${i}; } >${targetdir}/${patch_tmp}/${patchname}.patch + cd $patchdir +done + +# no patches to apply? bail out +[ -e ${targetdir}/${patch_tmp}/__patchfiles__ ] || { + rmdir ${targetdir}/${patch_tmp} + exit 0 +} + +# provide backwards compatibility to old style using 'patch' program +# XXX: this is unsafe and should be dropped at some point +am_opts="-C1" + +realpath $patchdir >${targetdir}/${patch_tmp}/__patchdir__ +cd ${targetdir} +git am $am_opts ${patch_tmp}/*.patch +if [ $? != 0 ] ; then + echo "git-am failed! Please fix patches!" + exit 1 +fi +git commit -a --allow-empty \ + --author="OpenADK <wbx@openadk.org>" \ + -m "OpenADK patch marker: $patch_series" diff --git a/scripts/update-patches-git b/scripts/update-patches-git new file mode 100644 index 000000000..8337fa847 --- /dev/null +++ b/scripts/update-patches-git @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# +# Update patches using git-format-patch from a source tree prepared by +# patch_git.sh. +# +# (c) 2016 Phil Sutter <phil@nwl.cc> + +wrkdist=$1 +wd=$(pwd) + +cd "$wrkdist" +top="" +top_series="" +git log --grep="^OpenADK patch marker:" --oneline | while read hash subject; do + [ -n "$top" ] || { + top=$hash + top_series="${subject#OpenADK patch marker: }" + continue + } + bottom=$hash + bottom_series="${subject#OpenADK patch marker: }" + + patchdir=$(<.git/patch_tmp/${top_series}/__patchdir__) + while read patchfile; do + rm ${patchdir}/$patchfile + done < .git/patch_tmp/${top_series}/__patchfiles__ + git format-patch -N -o "$patchdir" ${bottom}..${top} + + top=$bottom + top_series=$bottom_series +done diff --git a/target/config/Config.in.adk b/target/config/Config.in.adk index a70752bab..ec6d2b0fa 100644 --- a/target/config/Config.in.adk +++ b/target/config/Config.in.adk @@ -43,6 +43,18 @@ config ADK_DISABLE_CHECKSUM help Disable checksum checks of downloads. +choice +prompt "Backend for patching and update-patches" +default ADK_UPDATE_PATCHES_CLASSIC + +config ADK_UPDATE_PATCHES_CLASSIC + bool "Classic" + +config ADK_UPDATE_PATCHES_GIT + bool "Git" + +endchoice + config ADK_DISABLE_KERNEL_PATCHES bool "Disable global kernel patches" depends on ADK_TARGET_OS_LINUX |