From 1781f9f3c893c76656f0bd5879a0cdb5cbe158fe Mon Sep 17 00:00:00 2001 From: Ola x Nilsson Date: Mon, 28 Aug 2017 16:58:16 +0200 Subject: externalsrc.bbclass: Avoid symlink clashes for virtclasses There was a race condifion in externalsrc_configure_prefuncs when the same source folder is used for several variants of the same recipe, like this: EXTERNALSRC_pn-foo = "..." EXTERNALSRC_pn-foo-native = "..." The symlinks were created once for each variant of the recipe, and where they led in the end depended on which do_configure task executed last. Create one set of symlinks for each variant by adding an EXTSRC_SUFFIX variable to the end of the link names. Tries to handle all known virtclasses and multilib variants. Use a lockfile for externalsrc_configure_prefuncs to protect the .git/info/exclude file. Signed-off-by: Ola x Nilsson Signed-off-by: Ross Burton --- meta/classes/externalsrc.bbclass | 16 ++++++++++- meta/lib/oeqa/selftest/cases/devtool.py | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/meta/classes/externalsrc.bbclass b/meta/classes/externalsrc.bbclass index 8141f25e04..980e339cdc 100644 --- a/meta/classes/externalsrc.bbclass +++ b/meta/classes/externalsrc.bbclass @@ -24,8 +24,21 @@ # EXTERNALSRC_BUILD_pn-myrecipe = "/path/to/my/source/tree" # +def get_symlink_suffix(var, suffixes, d): + # Like oe.utils.prune_suffix but return the suffix instead + for suffix in suffixes: + if var.endswith(suffix): + return suffix + if var.startswith('nativesdk-'): + return '-nativesdk' + prefix = d.getVar("MLPREFIX") + if prefix and var.startswith(prefix): + return '-' + prefix[:-1] + return '' + SRCTREECOVEREDTASKS ?= "do_patch do_unpack do_fetch" -EXTERNALSRC_SYMLINKS ?= "oe-workdir:${WORKDIR} oe-logs:${T}" +EXTSRC_SUFFIX = "${@get_symlink_suffix(d.getVar('PN'), d.getVar('SPECIAL_PKGSUFFIX').split(), d)}" +EXTERNALSRC_SYMLINKS ?= "oe-workdir${EXTSRC_SUFFIX}:${WORKDIR} oe-logs${EXTSRC_SUFFIX}:${T}" python () { externalsrc = d.getVar('EXTERNALSRC') @@ -128,6 +141,7 @@ python () { d.setVar('STAMPCLEAN', '${STAMPS_DIR}/work-shared/${PN}/*-*') } +externalsrc_configure_prefunc[lockfiles] += " ${S}/conf_prefunc.lock" python externalsrc_configure_prefunc() { s_dir = d.getVar('S') # Create desired symlinks diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 1dfef599e6..69b7d5a651 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -500,6 +500,54 @@ class DevtoolTests(DevtoolBase): result = runCmd('devtool status') self.assertNotIn('mdadm', result.output) + def test_devtool_modify_configure_prefunc(self): + self.write_config(""" +MACHINE = "qemux86-64" +require conf/multilib.conf +MULTILIBS = "multilib:lib32" +DEFAULTTUNE_virtclass-multilib-lib32 = "x86" +""") + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') + self.write_recipeinc('emptytest', ''' +BBCLASSEXTEND = "native nativesdk" +do_patch[noexec] = "1" +INHIBIT_DEFAULT_DEPS = "1" +''') + self.track_for_cleanup(self.recipeinc('emptytest')) + targets = 'emptytest emptytest-native nativesdk-emptytest lib32-emptytest' + self.add_command_to_tearDown('bitbake -c clean ' + targets) + tempdir = tempfile.mkdtemp(prefix='devtoolqa') + self.track_for_cleanup(tempdir) + runCmd('devtool modify emptytest -x %s' % tempdir) + self.track_for_cleanup(self.workspacedir) + self.append_recipeinc('emptytest', 'EXTERNALSRC_pn-emptytest-native = "%s"\n' % tempdir) + self.append_recipeinc('emptytest', 'EXTERNALSRC_pn-nativesdk-emptytest = "%s"\n' % tempdir) + self.append_recipeinc('emptytest', 'EXTERNALSRC_pn-lib32-emptytest = "%s"\n' % tempdir) + bitbake('-c cleansstate ' + targets) + bitbake('-c configure ' + targets) + + def assert_link(linkname, destdir): + linkname = os.path.join(tempdir, linkname) + self.assertExists(linkname) + self.assertTrue(os.path.islink(linkname)) + dst = os.readlink(linkname) + self.assertEqual(dst, destdir) + + bbvars = {'': get_bb_vars(['WORKDIR', 'T'], 'emptytest'), + '-native': get_bb_vars(['WORKDIR', 'T'], 'emptytest-native'), + '-lib32': get_bb_vars(['WORKDIR', 'T'], 'lib32-emptytest'), + '-nativesdk': get_bb_vars(['WORKDIR', 'T'], 'nativesdk-emptytest')} + for variant in bbvars: + assert_link('oe-logs' + variant, bbvars[variant]['T']) + assert_link('oe-workdir' + variant, bbvars[variant]['WORKDIR']) + + with open(os.path.join(tempdir, '.git/info/exclude')) as efile: + lines = set(efile.readlines()) + expected = {'/%s%s\n' % (base, sfx) + for base in ['oe-logs', 'oe-workdir'] + for sfx in bbvars} + self.assertTrue(expected <= lines) + @OETestID(1620) def test_devtool_buildclean(self): def assertFile(path, *paths): -- cgit 1.2.3-korg