Files
poky/meta/classes/patch.bbclass
Richard Purdie 500206534f patch: Extend to native/nativesdk and depend upon
There is a bug in patch 2.7.3 and earlier where index lines
in patches can change file modes when they shouldn't:
http://git.savannah.gnu.org/cgit/patch.git/patch/?id=82b800c9552a088a241457948219d25ce0a407a4

This leaks into debug sources in particular (e.g. tcp-wrappers where
source files are read-only). Add the dependency to target recipes
to avoid this problem until we can rely on 2.7.4 or later.

We could try and remove all index lines from patch files but it will be a
losing battle. We could try and identify all the recipes which change
modes on files in patches but again, its a losing battle.

Instead, compromise and have patch-native as a dependency
for target recipes. We use patch-replacement-native since patch-native
is in ASSUME_PROVIDED.

Also add nativesdk-patch to buildtools-tarball.

[YOCTO #13777]

(From OE-Core rev: 5ed0840c93804488cd1c1aba6cb382b2434714a5)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2020-02-06 12:16:34 +00:00

168 lines
5.7 KiB
Plaintext

# Copyright (C) 2006 OpenedHand LTD
# Point to an empty file so any user's custom settings don't break things
QUILTRCFILE ?= "${STAGING_ETCDIR_NATIVE}/quiltrc"
PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_sysroot"
# There is a bug in patch 2.7.3 and earlier where index lines
# in patches can change file modes when they shouldn't:
# http://git.savannah.gnu.org/cgit/patch.git/patch/?id=82b800c9552a088a241457948219d25ce0a407a4
# This leaks into debug sources in particular. Add the dependency
# to target recipes to avoid this problem until we can rely on 2.7.4 or later.
PATCHDEPENDENCY_append_class-target = " patch-replacement-native:do_populate_sysroot"
PATCH_GIT_USER_NAME ?= "OpenEmbedded"
PATCH_GIT_USER_EMAIL ?= "oe.patch@oe"
inherit terminal
python () {
if d.getVar('PATCHTOOL') == 'git' and d.getVar('PATCH_COMMIT_FUNCTIONS') == '1':
extratasks = bb.build.tasksbetween('do_unpack', 'do_patch', d)
try:
extratasks.remove('do_unpack')
except ValueError:
# For some recipes do_unpack doesn't exist, ignore it
pass
d.appendVarFlag('do_patch', 'prefuncs', ' patch_task_patch_prefunc')
for task in extratasks:
d.appendVarFlag(task, 'postfuncs', ' patch_task_postfunc')
}
python patch_task_patch_prefunc() {
# Prefunc for do_patch
srcsubdir = d.getVar('S')
workdir = os.path.abspath(d.getVar('WORKDIR'))
testsrcdir = os.path.abspath(srcsubdir)
if (testsrcdir + os.sep).startswith(workdir + os.sep):
# Double-check that either workdir or S or some directory in-between is a git repository
found = False
while testsrcdir != workdir:
if os.path.exists(os.path.join(testsrcdir, '.git')):
found = True
break
if testsrcdir == workdir:
break
testsrcdir = os.path.dirname(testsrcdir)
if not found:
bb.fatal('PATCHTOOL = "git" set for source tree that is not a git repository. Refusing to continue as that may result in commits being made in your metadata repository.')
patchdir = os.path.join(srcsubdir, 'patches')
if os.path.exists(patchdir):
if os.listdir(patchdir):
d.setVar('PATCH_HAS_PATCHES_DIR', '1')
else:
os.rmdir(patchdir)
}
python patch_task_postfunc() {
# Prefunc for task functions between do_unpack and do_patch
import oe.patch
import shutil
func = d.getVar('BB_RUNTASK')
srcsubdir = d.getVar('S')
if os.path.exists(srcsubdir):
if func == 'do_patch':
haspatches = (d.getVar('PATCH_HAS_PATCHES_DIR') == '1')
patchdir = os.path.join(srcsubdir, 'patches')
if os.path.exists(patchdir):
shutil.rmtree(patchdir)
if haspatches:
stdout, _ = bb.process.run('git status --porcelain patches', cwd=srcsubdir)
if stdout:
bb.process.run('git checkout patches', cwd=srcsubdir)
stdout, _ = bb.process.run('git status --porcelain .', cwd=srcsubdir)
if stdout:
useroptions = []
oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=d)
bb.process.run('git add .; git %s commit -a -m "Committing changes from %s\n\n%s"' % (' '.join(useroptions), func, oe.patch.GitApplyTree.ignore_commit_prefix + ' - from %s' % func), cwd=srcsubdir)
}
def src_patches(d, all=False, expand=True):
import oe.patch
return oe.patch.src_patches(d, all, expand)
def should_apply(parm, d):
"""Determine if we should apply the given patch"""
import oe.patch
return oe.patch.should_apply(parm, d)
should_apply[vardepsexclude] = "DATE SRCDATE"
python patch_do_patch() {
import oe.patch
patchsetmap = {
"patch": oe.patch.PatchTree,
"quilt": oe.patch.QuiltTree,
"git": oe.patch.GitApplyTree,
}
cls = patchsetmap[d.getVar('PATCHTOOL') or 'quilt']
resolvermap = {
"noop": oe.patch.NOOPResolver,
"user": oe.patch.UserResolver,
}
rcls = resolvermap[d.getVar('PATCHRESOLVE') or 'user']
classes = {}
s = d.getVar('S')
os.putenv('PATH', d.getVar('PATH'))
# We must use one TMPDIR per process so that the "patch" processes
# don't generate the same temp file name.
import tempfile
process_tmpdir = tempfile.mkdtemp()
os.environ['TMPDIR'] = process_tmpdir
for patch in src_patches(d):
_, _, local, _, _, parm = bb.fetch.decodeurl(patch)
if "patchdir" in parm:
patchdir = parm["patchdir"]
if not os.path.isabs(patchdir):
patchdir = os.path.join(s, patchdir)
else:
patchdir = s
if not patchdir in classes:
patchset = cls(patchdir, d)
resolver = rcls(patchset, oe_terminal)
classes[patchdir] = (patchset, resolver)
patchset.Clean()
else:
patchset, resolver = classes[patchdir]
bb.note("Applying patch '%s' (%s)" % (parm['patchname'], oe.path.format_display(local, d)))
try:
patchset.Import({"file":local, "strippath": parm['striplevel']}, True)
except Exception as exc:
bb.utils.remove(process_tmpdir, True)
bb.fatal(str(exc))
try:
resolver.Resolve()
except bb.BBHandledException as e:
bb.utils.remove(process_tmpdir, True)
bb.fatal(str(e))
bb.utils.remove(process_tmpdir, True)
del os.environ['TMPDIR']
}
patch_do_patch[vardepsexclude] = "PATCHRESOLVE"
addtask patch after do_unpack
do_patch[umask] = "022"
do_patch[dirs] = "${WORKDIR}"
do_patch[depends] = "${PATCHDEPENDENCY}"
EXPORT_FUNCTIONS do_patch