View previous topic :: View next topic |
Author |
Message |
Dolda2000 n00b
Joined: 05 Mar 2004 Posts: 37 Location: Täby, Sweden
|
Posted: Thu May 19, 2005 1:36 am Post subject: Portage and automatic patching |
|
|
I have a few packages that I always patch when I emerge them. They include Xorg (for the IsolateDevice patch), gaim and screen, but there are some others as well.
Thie thing is, right now I always have to keep a look out for these packages whenever I run `emerge -Duva world', cancel, emerge them manually, stop emerge with Ctrl+S, go into /var/tmp/portage/..., apply the patch manually and then resume emerge with Ctrl+Q.
This is quite a procedure that I feel that I'd manage better without. Is there a way to make portage apply these patches automatically (like /etc/portage/package.patches or something like that)? |
|
Back to top |
|
|
platojones Veteran
Joined: 23 Oct 2002 Posts: 1602 Location: Just over the horizon
|
Posted: Thu May 19, 2005 1:53 am Post subject: |
|
|
I'm afraid not |
|
Back to top |
|
|
TrueDFX Retired Dev
Joined: 02 Jun 2004 Posts: 1348
|
Posted: Thu May 19, 2005 6:39 am Post subject: |
|
|
Keep in mind that this is in no way supported by anyone, not even by myself.
This is what I use: Code: | if [[ " ${FEATURES} " == *" autopatch "* ]]; then
case "$1" in
unpack)
if [[ -f "${BUILDDIR}/.autopatched" ]]; then
/usr/bin/rm "${BUILDDIR}/.autopatched"
fi
;;
compile)
if [[ ! -f "${BUILDDIR}/.autopatched" ]]; then
if [[ -d "/etc/portage/autopatch/${CATEGORY}/${PN}" ]]; then
IFS=$'\n'
for patch in $(/usr/bin/find "/etc/portage/autopatch/${CATEGORY}/${PN}/." ! -name . -prune ! -type d); do
for strip in 0 1 2 3 4; do
PATCHOPTS=(-N -d "${S}" -f -g 0 -i "${patch}" -p "${strip}" '--no-backup-if-mismatch')
if /usr/bin/patch --dry-run --quiet "${PATCHOPTS[@]}" >/dev/null; then
echo " * Applying ${patch##*/}"
/usr/bin/patch "${PATCHOPTS[@]}" || die "wtf?"
unset PATCHOPTS
continue 2
fi
done
echo " * Couldn't apply patch ${patch}"
die "autopatch failed"
done
IFS=$' \t\n'
fi
/bin/touch "${BUILDDIR}/.autopatched"
fi
esac
fi | Stick that in your /etc/portage/bashrc, create /etc/portage/autopatch/x11-base/xorg-x11/ etc., put your patches in there, edit your /etc/make.conf, put "autopatch" in your FEATURES, and just emerge.
I can't find who originally came up with the idea of using bashrc for this, by the way, so I apologise in advance for not giving proper credit for that.
Again, keep in mind that this is in no way supported by anyone, not even by myself.
Last edited by TrueDFX on Sat May 21, 2005 3:36 pm; edited 1 time in total |
|
Back to top |
|
|
elvisthedj Guru
Joined: 21 Jun 2004 Posts: 483 Location: Nampa, ID
|
Posted: Thu May 19, 2005 6:49 am Post subject: |
|
|
Thx TrueDFX I'll email you if I have any questions (..kidding). Thx to whomever wrote that too!
Dolda2000: If you try that out, let me know how that works for you. The only thing I really apply a lot of patches to are various pieces of Asterisk which I typically leave out of my world file for that very reason. _________________ Kris Edwards
kris edwards at g mail dot c0m
PGP
WWW |
|
Back to top |
|
|
rhill Retired Dev
Joined: 22 Oct 2004 Posts: 1629 Location: sk.ca
|
Posted: Thu May 19, 2005 7:32 am Post subject: |
|
|
TrueDFX wrote: | I can't find who originally came up with the idea of using bashrc for this, by the way, so I apologise in advance for not giving proper credit for that. |
methinks it was solar, but i might be mistaken. that's the first i ever saw of it anyways.
http://dev.gentoo.org/~solar/portage_misc/bashrc.autopatch _________________ by design, by neglect
for a fact or just for effect |
|
Back to top |
|
|
TrueDFX Retired Dev
Joined: 02 Jun 2004 Posts: 1348
|
Posted: Thu May 19, 2005 7:37 am Post subject: |
|
|
Thanks, yeah, that's the one. |
|
Back to top |
|
|
Dolda2000 n00b
Joined: 05 Mar 2004 Posts: 37 Location: Täby, Sweden
|
Posted: Thu May 19, 2005 2:49 pm Post subject: |
|
|
That's really interesting, TrueDFX. I was planning to start modifying emerge itself (and make it patch itself on future reemerges), but I had no idea it sourced external definitions like that.
That's certainly better, not to say more modular. I'll try it out at once. |
|
Back to top |
|
|
UncleOwen Veteran
Joined: 27 Feb 2003 Posts: 1493 Location: Germany, Hamburg
|
Posted: Thu May 19, 2005 3:34 pm Post subject: |
|
|
TrueDFX wrote: | Code: | if [[ " ${FEATURES} " == *" autopatch "* ]]; then |
|
Does this work if autopatch is the first or last entry in ${FEATURES}? |
|
Back to top |
|
|
TrueDFX Retired Dev
Joined: 02 Jun 2004 Posts: 1348
|
Posted: Thu May 19, 2005 3:46 pm Post subject: |
|
|
UncleOwen wrote: | TrueDFX wrote: | Code: | if [[ " ${FEATURES} " == *" autopatch "* ]]; then |
|
Does this work if autopatch is the first or last entry in ${FEATURES}? | Yes, it does. It checks " ${FEATURES} " instead of "${FEATURES}" for this. * matches even an empty string, so if your FEATURES is "autopatch notitles", " ${FEATURES} " can be split into "", " autopatch ", and "notitles ", where * and * match the first and third string. |
|
Back to top |
|
|
UncleOwen Veteran
Joined: 27 Feb 2003 Posts: 1493 Location: Germany, Hamburg
|
Posted: Thu May 19, 2005 3:52 pm Post subject: |
|
|
TrueDFX wrote: | UncleOwen wrote: | TrueDFX wrote: | Code: | if [[ " ${FEATURES} " == *" autopatch "* ]]; then |
|
Does this work if autopatch is the first or last entry in ${FEATURES}? | Yes, it does. It checks " ${FEATURES} " instead of "${FEATURES}" for this. |
Thanks, that's exactly what I missed. |
|
Back to top |
|
|
Dolda2000 n00b
Joined: 05 Mar 2004 Posts: 37 Location: Täby, Sweden
|
Posted: Fri May 20, 2005 12:11 am Post subject: |
|
|
I wrote my own version (not that anything was really wrong with yours, of course, but this just matches my thinking better), and it seems to be working just fine so far.
Code: | if [ "$EBUILD_PHASE" = unpack ]; then
/bin/rm -f "${BUILDDIR}/.autopatched"
elif [ "$EBUILD_PHASE" = compile ]; then
if [ ! -e "${BUILDDIR}/.autopatched" ]; then
for patch in /etc/portage/package.patches/${CATEGORY}/${PN}/*.patch.[0-9]; do
if [ -r "$patch" ]; then
strip="${patch##*.}"
einfo "Applying autopatch ${patch##*/}"
/usr/bin/patch "-d${S}" "-p${strip}" -N -f <"${patch}" >/dev/null
retcode=$?
eend "${retcode}"
if [ "${retcode}" -ne 0 ]; then
die "Autopatch application failed"
fi
fi
done
>"${BUILDDIR}/.autopatched"
fi
fi
|
Thanks for your help! |
|
Back to top |
|
|
Erlend Guru
Joined: 26 Dec 2004 Posts: 493
|
Posted: Mon Mar 27, 2006 4:57 pm Post subject: |
|
|
I just get:
Code: | ACCESS DENIED unlink: /.autopatched |
probably something to do with sandbox?[/profile] |
|
Back to top |
|
|
Erlend Guru
Joined: 26 Dec 2004 Posts: 493
|
Posted: Mon Mar 27, 2006 6:50 pm Post subject: |
|
|
I've tried to change it a bit:
Code: | if [ "$EBUILD_PHASE" = unpack ]; then
/bin/rm -f "/tmp/portage/${CATEGORY}/${PN}/.autopatched"
if [ ! -e "/tmp/portage/${CATEGORY}/${PN}/.autopatched" ]; then
for patch in /etc/portage/package.patches/${CATEGORY}/${PN}/*.patch; do
if [ -r "$patch" ]; then
strip="${patch##*.}"
ewarn "Unsupported patch: this is not guaranteed to work. Do not post bugs!"
#einfo "Applying autopatch ${patch##*/}"
#/usr/bin/patch "-d${S}" "-p${strip}" -N -f <"${patch}" >/dev/null
#echo $patch
epatch $patch
retcode=$?
eend "${retcode}"
if [ "${retcode}" -ne 0 ]; then
die "Autopatch application failed"
fi
fi
done
>"/tmp/portage/${CATEGORY}/${PN}/.autopatched"
fi
fi |
so that it uses epatch. Can anybody tell me please why I get errors:
Code: | ***** gtk+-2-smoothscroll-r6.patch *****
========================================
PATCH COMMAND: patch -p0 -g0 -E --no-backup-if-mismatch < /etc/portage/package.
patches/x11-libs/gtk+/gtk+-2-smoothscroll-r6.patch
========================================
/var/tmp/portage/gtk+-2.8.12/temp/environment: line 2273: cat: command not found
/var/tmp/portage/gtk+-2.8.12/temp/environment: line 2273: patch: command not fou
nd
|
|
|
Back to top |
|
|
millimille n00b
Joined: 30 Apr 2006 Posts: 6
|
Posted: Mon May 22, 2006 1:42 pm Post subject: |
|
|
The bashrc version didn't seem to be working for me so I wrote my own, using epatch. There's a nasty hack to avoid some error messages though. This one patches ebuild.sh directly. Anyway, here it is:
Code: |
--- bin/ebuild.sh.orig 2006-05-10 15:28:12.000000000 +1000
+++ bin/ebuild.sh 2006-05-22 23:28:15.512177750 +1000
@@ -661,6 +661,22 @@
[ "$(type -t post_pkg_setup)" == "function" ] && post_pkg_setup
}
+dyn_unpack_autopatch() {
+ vecho ">>> Applying custom patches"
+
+ OVERLAY='/etc/portage/patches'
+ PATCH_DIR="${OVERLAY}/${CATEGORY}"
+
+ if [ -d $PATCH_DIR ]; then
+ files=`ls -1 ${PATCH_DIR}/${PN}-*.patch 2>/dev/null`
+ cd ${S}
+
+ for file in ${files}; do
+ epatch ${file}
+ done
+ fi
+}
+
dyn_unpack() {
trap "abort_unpack" SIGINT SIGQUIT
[ "$(type -t pre_src_unpack)" == "function" ] && pre_src_unpack
@@ -702,6 +718,7 @@
vecho ">>> Unpacking source..."
src_unpack
touch "${PORTAGE_BUILDDIR}/.unpacked" || die "IO Failure -- Failed 'touch .unpacked' in ${PORTAGE_BUILDDIR}"
+ dyn_unpack_autopatch # DW: Patch Dir
vecho ">>> Source unpacked."
cd "${PORTAGE_BUILDDIR}"
@@ -1438,6 +1455,12 @@
unset PORTAGE_RESTRICT
fi
+# DW: UGLY hack
+if ! hasq "eutils" $INHERITED; then
+ INHERITED="$INHERITED eutils multilib portability"
+ inherit eutils
+fi
+
# Expand KEYWORDS
# We need to turn off pathname expansion for -* in KEYWORDS and
# we need to escape ~ to avoid tilde expansion
|
Patches go into /etc/portage/patches/CATEGORY/NAME-desc.patch (ie, just inside the category directory).
Tested on portage-2.1_rc1-r4 (just then)[/code]. |
|
Back to top |
|
|
ecatmur Advocate
Joined: 20 Oct 2003 Posts: 3595 Location: Edinburgh
|
Posted: Wed May 24, 2006 6:03 am Post subject: |
|
|
This is what I use: Code: | function edautoreconf() {
aclocal $(for x in m4 macros; do [[ -d $x ]] && echo "-I $x"; done) || die "aclocal failed"
autoconf || die "autoconf failed"
autoheader || die "autoheader failed"
libtoolize --copy --force || die "libtoolize failed"
}
function edpatch_maybe_autotool() {
ran_automake_at=()
for am in $makefile_ams; do
am="${path#$WORKDIR/}$(echo $am | sed 's:^\([^/]*/\+\)\{'$j'\}::')"
ewarn "$am changed, trying to run automake"
acpath="${am%/*}"; amade=""
while true; do
acfull="$WORKDIR/$acpath/"
ewarn "trying: ${acfull}configure.{in,ac}"
if [[ -f "$acfull"configure.in || -f "$acfull"configure.ac ]]; then
if has "$acpath" "${ran_automake_at[@]}"; then
echo -n "already run here, skipping"
eend 0; amade="yes"; break
fi
ebegin "running automake in $acfull"
if ! (cd "$acfull"; automake --no-force); then
eend $?; die "automake failed"
fi
ran_automake_at=("${ran_automake_at[@]}" "$acpath")
eend 0; amade="yes"; break
fi
[[ "$acpath" == */* ]] || break
acpath="${acpath%/*}"
done
if ! [[ "$amade" ]]; then
eerror "could not run automake"
die "patch failed"
fi
done
for ac in $configure_acs; do
ac="${path#$WORKDIR/}$(echo $ac | sed 's:^\([^/]*/\+\)\{'$j'\}::')"
ebegin "$ac changed, running autoreconf"
if ! (cd $WORKDIR/${ac%/configure.*}; edautoreconf); then
eend $?; die "autoreconf failed"
fi
eend 0
done
}
function edpatch_apply() {
local patch="$1" target=() tname="" path="" applied=""
if grep "^RCS file: " "$patch"; then
targets=("$(sed -e 's/^RCS file: \(.*\),v/\1/;ta;d;:a;q' "$patch")")
else
targets[0]="$(sed -e 's/--- \([^[:space:]]*\).*/\1/;ta;d;:a;q' "$patch")"
targets[0]="${targets[0]%.orig}"
targets[1]="$(sed -e 's/+++ \([^[:space:]]*\).*/\1/;ta;d;:a;q' "$patch")"
targets[1]="${targets[1]%.orig}"
[[ "${targets[0]}" == "${targets[1]}" ]] && targets=("$targets")
fi
makefile_ams=$(sed -e 's:^\(---\|+++\) \(\(.*/\)\?Makefile\.am\)\t.*:\2:;t;d' "$patch" | sort -u)
configure_acs=$(sed -e 's:^\(---\|+++\) \(\(.*/\)\?configure\.\(ac\|in\)\)\t.*:\2:;t;d' "$patch" | sort -u)
for target in "${targets[@]}"; do
tname="$(basename "$target")"
ewarn "Trying to apply $patch to $tname"
i=0
while true; do
ewarn "target $target"
for path in $(find "$WORKDIR" -name "$tname"); do
[[ "$path" == */"$target" ]] || continue
ewarn "trying: $path"
path="${path%$target}"
for j in $(seq 0 $i); do
patch --dry-run -p$j -d "$path" <"$patch" \
|| continue
ebegin "applying in $path"
if ! patch -p$j -d "$path" <"$patch"; then
eend $?
die "patch failed, argh"
fi
eend 0
edpatch_maybe_autotool
applied="yes"; break
done; [[ "$applied" ]] && break
done; [[ "$applied" ]] && break
[[ "$target" == */* ]] || break
target="${target#*/}"
(( ++i ))
done
[[ "$applied" ]] && break
done
if ! [[ "$applied" ]]; then
eerror "could not apply $patch"
die "patch failed"
fi
}
function edpatch() {
for d in /etc/portage/patches/$CATEGORY/$PN*; do
dn="${d##*/}"
[[ "$dn" == "$PN" || "$dn" == "$P" || "$dn" == "$P-$PR" || "$dn" == "$PN[$SLOT]" || "$PVR" == ${dn#$PN-} ]] || continue
for x in "$d"/*; do
[[ -f "$x" ]] && edpatch_apply "$x"
done
done
}
if [[ ! -f "${PORTAGE_BUILDDIR}/.patched" ]]; then
echo ">>> Not marked as patched; patching..."
edpatch
touch "${PORTAGE_BUILDDIR}/.patched"
elif [[ "${PORTAGE_BUILDDIR}/.unpacked" -nt "${PORTAGE_BUILDDIR}/.patched" ]]; then
echo ">>> WORKDIR has been re-unpacked; patching..."
edpatch
touch "${PORTAGE_BUILDDIR}/.patched"
else
echo ">>> WORKDIR is up-to-date and patched, keeping..."
fi
|
The important thing it does is to check whether configure.{ac,in} or Makefile.am has been patched, and run autoconf/automake accordingly. _________________ No more cruft
dep: Revdeps that work
Using command-line ACCEPT_KEYWORDS? |
|
Back to top |
|
|
Dolda2000 n00b
Joined: 05 Mar 2004 Posts: 37 Location: Täby, Sweden
|
Posted: Wed Jul 12, 2006 1:00 am Post subject: |
|
|
Portage changed the name of a couple of env variables in the some recent upgrades, so the version I posted before doesn't work anymore; in case anyone wants it, here's the new version:
Code: | if [ -n "$BUILDDIR" ]; then
builddir="$BUILDDIR"
elif [ -n "$PORTAGE_BUILDDIR" ]; then
builddir="$PORTAGE_BUILDDIR"
else
dir "cannot find build dir"
fi
if [ "$EBUILD_PHASE" = unpack ]; then
/bin/rm -f "${builddir}/.autopatched"
elif [ "$EBUILD_PHASE" = compile ]; then
if [ ! -e "${builddir}/.autopatched" ]; then
for patch in /etc/portage/package.patches/${CATEGORY}/${PN}/*.patch.[0-9]; do
if [ -r "$patch" ]; then
strip="${patch##*.}"
einfo "Applying autopatch ${patch##*/}"
/usr/bin/patch "-d${S}" "-p${strip}" -N -f <"${patch}" >/dev/null
retcode=$?
eend "${retcode}"
if [ "${retcode}" -ne 0 ]; then
die "Autopatch application failed (S=${S}, strip=${strip})"
fi
fi
done
if [ -e "/etc/portage/package.patches/${CATEGORY}/${PN}/bashrc" ]; then
einfo "Running bashrc for ${CATEGORY}/${PN}"
. "/etc/portage/package.patches/${CATEGORY}/${PN}/bashrc"
fi
>"${builddir}/.autopatched"
fi
fi
|
|
|
Back to top |
|
|
wdsci Tux's lil' helper
Joined: 02 Oct 2007 Posts: 149 Location: US
|
Posted: Fri Oct 26, 2007 2:48 am Post subject: |
|
|
I apologize in advance if it's against the rules to rekindle old threads like this, or if you've all had enough of custom patching and consider this post inane and irrelevant . . .
Anyway, I just wrote my own custom-patch patch (much like millimille's patch to ebuild.sh above). I thought it might be useful to be able to separate patches out by version, i.e. to have a patch apply only to Portage 2.1.3 but not to 2.1.4, and I figured I'd share my ebuild.sh patch, if anyone's interested:
Code: | *** portage-2.1.3/bin/ebuild.sh 2007-07-27 14:34:58.000000000 -0400
--- portage-2.1.3/bin/ebuild.sh 2007-10-25 21:12:52.000000000 -0400
***************
*** 766,771 ****
--- 766,788 ----
cd "${WORKDIR}" || die "Directory change failed: \`cd '${WORKDIR}'\`"
vecho ">>> Unpacking source..."
qa_call src_unpack
+ if [ -n "${PORTAGE_PATCHDIR}" -a -d "${PORTAGE_PATCHDIR}/${CATEGORY}/${PN}" ]; then
+ vecho ">>> Applying custom patches..."
+ _runcustompatches() {
+ [ "$(type -t epatch)" == "function" ] || qa_source ${PORTDIR}/eclass/eutils.eclass
+ PATCHDIR=${PORTAGE_PATCHDIR}/${CATEGORY}/${PN}/${PV//.//}
+ PATCHLIST=
+ [ -d $PATCHDIR ] && PATCHLIST=" $PATCHDIR/* $PATCHLIST"
+ while [[ $PATCHDIR != ${PORTAGE_PATCHDIR}/${CATEGORY}/${PN} ]]; do
+ PATCHDIR=${PATCHDIR%/*}
+ [ -d $PATCHDIR ] && PATCHLIST="$PATCHDIR/* $PATCHLIST"
+ done
+ for x in $PATCHLIST; do
+ if [ -f $x ]; then epatch $x || die "Failed to apply patch $x"; fi
+ done
+ }
+ (_runcustompatches)
+ fi
touch "${PORTAGE_BUILDDIR}/.unpacked" || die "IO Failure -- Failed 'touch .unpacked' in ${PORTAGE_BUILDDIR}"
vecho ">>> Source unpacked."
cd "${PORTAGE_BUILDDIR}" |
This also requires adding a PORTAGE_PATCHDIR variable to make.conf. When emerging, say, Portage 2.1.3.9, it will apply all patches in ${PORTAGE_PATCHDIR}/sys-apps/portage, ${PORTAGE_PATCHDIR}/sys-apps/portage/2, ${PORTAGE_PATCHDIR}/sys-apps/portage/2/1, ${PORTAGE_PATCHDIR}/sys-apps/portage/2/1/3, and ${PORTAGE_PATCHDIR}/sys-apps/portage/2/1/3/9.
David |
|
Back to top |
|
|
|