<div dir="ltr">Hi,<div><br></div><div>is anyone else seeing this unhelpful fatal exception?</div><div><br></div><div><pre class="" style="white-space:pre-wrap;word-wrap:break-word;margin-top:0px;margin-bottom:0px;color:rgb(51,51,51);font-size:13px">ERROR: Failure expanding variable __anon_648__home_jenkins_oe_world_shr_core_openembedded_core_meta_classes_base_bbclass, expression was def __anon_648__home_jenkins_oe_world_shr_core_openembedded_core_meta_classes_base_bbclass(d):
    import string, re

    # Handle PACKAGECONFIG
    #
    # These take the form:
    #
    # PACKAGECONFIG ??= &quot;&lt;default options&gt;&quot;
    # PACKAGECONFIG[foo] = &quot;--enable-foo,--disable-foo,foo_depends,foo_runtime_depends&quot;
    pkgconfigflags = d.getVarFlags(&quot;PACKAGECONFIG&quot;) or {}
    if pkgconfigflags:
        pkgconfig = (d.getVar(&#39;PACKAGECONFIG&#39;, True) or &quot;&quot;).split()
        pn = d.getVar(&quot;PN&quot;, True)

        mlprefix = d.getVar(&quot;MLPREFIX&quot;, True)

        def expandFilter(appends, extension, prefix):
            appends = bb.utils.explode_deps(d.expand(&quot; &quot;.join(appends)))
            newappends = []
            for a in appends:
                if a.endswith(&quot;-native&quot;) or (&quot;-cross-&quot; in a):
                    newappends.append(a)
                elif a.startswith(&quot;virtual/&quot;):
                    subs = a.split(&quot;/&quot;, 1)[1]
                    if subs.startswith(prefix):
                        newappends.append(a + extension)
                    else:
                        newappends.append(&quot;virtual/&quot; + prefix + subs + extension)
                else:
                    if a.startswith(prefix):
                        newappends.append(a + extension)
                    else:
                        newappends.append(prefix + a + extension)
            return newappends

        def appendVar(varname, appends):
            if not appends:
                return
            if varname.find(&quot;DEPENDS&quot;) != -1:
                if pn.startswith(&quot;nativesdk-&quot;):
                    appends = expandFilter(appends, &quot;&quot;, &quot;nativesdk-&quot;)
                if pn.endswith(&quot;-native&quot;):
                    appends = expandFilter(appends, &quot;-native&quot;, &quot;&quot;)
                if mlprefix:
                    appends = expandFilter(appends, &quot;&quot;, mlprefix)
            varname = d.expand(varname)
            d.appendVar(varname, &quot; &quot; + &quot; &quot;.join(appends))

        extradeps = []
        extrardeps = []
        extraconf = []
        for flag, flagval in sorted(pkgconfigflags.items()):
            items = flagval.split(&quot;,&quot;)
            num = len(items)
            if num &gt; 4:
                bb.error(&quot;%s: PACKAGECONFIG[%s] Only enable,disable,depend,rdepend can be specified!&quot;
                    % (d.getVar(&#39;PN&#39;, True), flag))

            if flag in pkgconfig:
                if num &gt;= 3 and items[2]:
                    extradeps.append(items[2])
                if num &gt;= 4 and items[3]:
                    extrardeps.append(items[3])
                if num &gt;= 1 and items[0]:
                    extraconf.append(items[0])
            elif num &gt;= 2 and items[1]:
                    extraconf.append(items[1])
        appendVar(&#39;DEPENDS&#39;, extradeps)
        appendVar(&#39;RDEPENDS_defaultpkgname&#39;, extrardeps)
        if bb.data.inherits_class(&#39;cmake&#39;, d):
            appendVar(&#39;EXTRA_OECMAKE&#39;, extraconf)
        else:
            appendVar(&#39;EXTRA_OECONF&#39;, extraconf)

    pn = d.getVar(&#39;PN&#39;, True)
    license = d.getVar(&#39;LICENSE&#39;, True)
    if license == &quot;INVALID&quot;:
        bb.fatal(&#39;This recipe does not have the LICENSE field set (%s)&#39; % pn)

    if bb.data.inherits_class(&#39;license&#39;, d):
        check_license_format(d)
        unmatched_license_flag = check_license_flags(d)
        if unmatched_license_flag:
            bb.debug(1, &quot;Skipping %s because it has a restricted license not&quot;
                 &quot; whitelisted in LICENSE_FLAGS_WHITELIST&quot; % pn)
            raise bb.parse.SkipPackage(&quot;because it has a restricted license not&quot;
                 &quot; whitelisted in LICENSE_FLAGS_WHITELIST&quot;)

    # If we&#39;re building a target package we need to use fakeroot (pseudo)
    # in order to capture permissions, owners, groups and special files
    if not bb.data.inherits_class(&#39;native&#39;, d) and not bb.data.inherits_class(&#39;cross&#39;, d):
        d.setVarFlag(&#39;do_unpack&#39;, &#39;umask&#39;, &#39;022&#39;)
        d.setVarFlag(&#39;do_configure&#39;, &#39;umask&#39;, &#39;022&#39;)
        d.setVarFlag(&#39;do_compile&#39;, &#39;umask&#39;, &#39;022&#39;)
        d.appendVarFlag(&#39;do_install&#39;, &#39;depends&#39;, &#39; virtual/fakeroot-native:do_populate_sysroot&#39;)
        d.setVarFlag(&#39;do_install&#39;, &#39;fakeroot&#39;, &#39;1&#39;)
        d.setVarFlag(&#39;do_install&#39;, &#39;umask&#39;, &#39;022&#39;)
        d.appendVarFlag(&#39;do_package&#39;, &#39;depends&#39;, &#39; virtual/fakeroot-native:do_populate_sysroot&#39;)
        d.setVarFlag(&#39;do_package&#39;, &#39;fakeroot&#39;, &#39;1&#39;)
        d.setVarFlag(&#39;do_package&#39;, &#39;umask&#39;, &#39;022&#39;)
        d.setVarFlag(&#39;do_package_setscene&#39;, &#39;fakeroot&#39;, &#39;1&#39;)
        d.appendVarFlag(&#39;do_package_setscene&#39;, &#39;depends&#39;, &#39; virtual/fakeroot-native:do_populate_sysroot&#39;)
        d.setVarFlag(&#39;do_devshell&#39;, &#39;fakeroot&#39;, &#39;1&#39;)
        d.appendVarFlag(&#39;do_devshell&#39;, &#39;depends&#39;, &#39; virtual/fakeroot-native:do_populate_sysroot&#39;)

    need_machine = d.getVar(&#39;COMPATIBLE_MACHINE&#39;, True)
    if need_machine:
        import re
        compat_machines = (d.getVar(&#39;MACHINEOVERRIDES&#39;, True) or &quot;&quot;).split(&quot;:&quot;)
        for m in compat_machines:
            if re.match(need_machine, m):
                break
        else:
            raise bb.parse.SkipPackage(&quot;incompatible with machine %s (not in COMPATIBLE_MACHINE)&quot; % d.getVar(&#39;MACHINE&#39;, True))

    source_mirror_fetch = d.getVar(&#39;SOURCE_MIRROR_FETCH&#39;, 0)
    if not source_mirror_fetch:
        need_host = d.getVar(&#39;COMPATIBLE_HOST&#39;, True)
        if need_host:
            import re
            this_host = d.getVar(&#39;HOST_SYS&#39;, True)
            if not re.match(need_host, this_host):
                raise bb.parse.SkipPackage(&quot;incompatible with host %s (not in COMPATIBLE_HOST)&quot; % this_host)

        bad_licenses = (d.getVar(&#39;INCOMPATIBLE_LICENSE&#39;, True) or &quot;&quot;).split()

        check_license = False if pn.startswith(&quot;nativesdk-&quot;) else True
        for t in [&quot;-native&quot;, &quot;-cross-arm&quot;, &quot;-cross-initial-arm&quot;,
              &quot;-crosssdk-x86_64&quot;, &quot;-crosssdk-initial-x86_64&quot;,
              &quot;-cross-canadian-arm&quot;]:
            if pn.endswith(d.expand(t)):
                check_license = False
        if pn.startswith(&quot;gcc-source-&quot;):
            check_license = False

        if check_license and bad_licenses:
            bad_licenses = expand_wildcard_licenses(d, bad_licenses)

            whitelist = []
            incompatwl = []
            htincompatwl = []
            for lic in bad_licenses:
                spdx_license = return_spdx(d, lic)
                for w in [&quot;HOSTTOOLS_WHITELIST_&quot;, &quot;LGPLv2_WHITELIST_&quot;, &quot;WHITELIST_&quot;]:
                    whitelist.extend((d.getVar(w + lic, True) or &quot;&quot;).split())
                    if spdx_license:
                        whitelist.extend((d.getVar(w + spdx_license, True) or &quot;&quot;).split())
                    &#39;&#39;&#39;
                    We need to track what we are whitelisting and why. If pn is
                    incompatible and is not HOSTTOOLS_WHITELIST_ we need to be
                    able to note that the image that is created may infact
                    contain incompatible licenses despite INCOMPATIBLE_LICENSE
                    being set.
                    &#39;&#39;&#39;
                    if &quot;HOSTTOOLS&quot; in w:
                        htincompatwl.extend((d.getVar(w + lic, True) or &quot;&quot;).split())
                        if spdx_license:
                            htincompatwl.extend((d.getVar(w + spdx_license, True) or &quot;&quot;).split())
                    else:
                        incompatwl.extend((d.getVar(w + lic, True) or &quot;&quot;).split())
                        if spdx_license:
                            incompatwl.extend((d.getVar(w + spdx_license, True) or &quot;&quot;).split())

            if not pn in whitelist:
                recipe_license = d.getVar(&#39;LICENSE&#39;, True)
                pkgs = d.getVar(&#39;PACKAGES&#39;, True).split()
                skipped_pkgs = []
                unskipped_pkgs = []
                for pkg in pkgs:
                    if incompatible_license(d, bad_licenses, pkg):
                        skipped_pkgs.append(pkg)
                    else:
                        unskipped_pkgs.append(pkg)
                all_skipped = skipped_pkgs and not unskipped_pkgs
                if unskipped_pkgs:
                    for pkg in skipped_pkgs:
                        bb.debug(1, &quot;SKIPPING the package &quot; + pkg + &quot; at do_rootfs because it&#39;s &quot; + recipe_license)
                        mlprefix = d.getVar(&#39;MLPREFIX&#39;, True)
                        d.setVar(&#39;LICENSE_EXCLUSION-&#39; + mlprefix + pkg, 1)
                    for pkg in unskipped_pkgs:
                        bb.debug(1, &quot;INCLUDING the package &quot; + pkg)
                elif all_skipped or incompatible_license(d, bad_licenses):
                    bb.debug(1, &quot;SKIPPING recipe %s because it&#39;s %s&quot; % (pn, recipe_license))
                    raise bb.parse.SkipPackage(&quot;incompatible with license %s&quot; % recipe_license)
            elif pn in whitelist:
                if pn in incompatwl:
                    bb.note(&quot;INCLUDING &quot; + pn + &quot; as buildable despite INCOMPATIBLE_LICENSE because it has been whitelisted&quot;)
                elif pn in htincompatwl:
                    bb.note(&quot;INCLUDING &quot; + pn + &quot; as buildable despite INCOMPATIBLE_LICENSE because it has been whitelisted for HOSTTOOLS&quot;)

    needsrcrev = False
    srcuri = d.getVar(&#39;SRC_URI&#39;, True)
    for uri in srcuri.split():
        (scheme, _ , path) = bb.fetch.decodeurl(uri)[:3]

        # HTTP/FTP use the wget fetcher
        if scheme in (&quot;http&quot;, &quot;https&quot;, &quot;ftp&quot;):
            d.appendVarFlag(&#39;do_fetch&#39;, &#39;depends&#39;, &#39; wget-native:do_populate_sysroot&#39;)

        # Svn packages should DEPEND on subversion-native
        if scheme == &quot;svn&quot;:
            needsrcrev = True
            d.appendVarFlag(&#39;do_fetch&#39;, &#39;depends&#39;, &#39; subversion-native:do_populate_sysroot&#39;)

        # Git packages should DEPEND on git-native
        elif scheme == &quot;git&quot;:
            needsrcrev = True
            d.appendVarFlag(&#39;do_fetch&#39;, &#39;depends&#39;, &#39; git-native:do_populate_sysroot&#39;)

        # Mercurial packages should DEPEND on mercurial-native
        elif scheme == &quot;hg&quot;:
            needsrcrev = True
            d.appendVarFlag(&#39;do_fetch&#39;, &#39;depends&#39;, &#39; mercurial-native:do_populate_sysroot&#39;)

        # OSC packages should DEPEND on osc-native
        elif scheme == &quot;osc&quot;:
            d.appendVarFlag(&#39;do_fetch&#39;, &#39;depends&#39;, &#39; osc-native:do_populate_sysroot&#39;)

        # *.lz4 should DEPEND on lz4-native for unpacking
        if path.endswith(&#39;.lz4&#39;):
            d.appendVarFlag(&#39;do_unpack&#39;, &#39;depends&#39;, &#39; lz4-native:do_populate_sysroot&#39;)

        # *.lz should DEPEND on lzip-native for unpacking
        elif path.endswith(&#39;.lz&#39;):
            d.appendVarFlag(&#39;do_unpack&#39;, &#39;depends&#39;, &#39; lzip-native:do_populate_sysroot&#39;)

        # *.xz should DEPEND on xz-native for unpacking
        elif path.endswith(&#39;.xz&#39;):
            d.appendVarFlag(&#39;do_unpack&#39;, &#39;depends&#39;, &#39; xz-native:do_populate_sysroot&#39;)

        # .zip should DEPEND on unzip-native for unpacking
        elif path.endswith(&#39;.zip&#39;):
            d.appendVarFlag(&#39;do_unpack&#39;, &#39;depends&#39;, &#39; unzip-native:do_populate_sysroot&#39;)

        # file is needed by rpm2cpio.sh
        elif path.endswith(&#39;.src.rpm&#39;):
            d.appendVarFlag(&#39;do_unpack&#39;, &#39;depends&#39;, &#39; file-native:do_populate_sysroot&#39;)

    if needsrcrev:
        d.setVar(&quot;SRCPV&quot;, &quot;${@bb.fetch2.get_srcrev(d)}&quot;)

    set_packagetriplet(d)

    # &#39;multimachine&#39; handling
    mach_arch = d.getVar(&#39;MACHINE_ARCH&#39;, True)
    pkg_arch = d.getVar(&#39;PACKAGE_ARCH&#39;, True)

    if (pkg_arch == mach_arch):
        # Already machine specific - nothing further to do
        return

    #
    # We always try to scan SRC_URI for urls with machine overrides
    # unless the package sets SRC_URI_OVERRIDES_PACKAGE_ARCH=0
    #
    override = d.getVar(&#39;SRC_URI_OVERRIDES_PACKAGE_ARCH&#39;, True)
    if override != &#39;0&#39;:
        paths = []
        fpaths = (d.getVar(&#39;FILESPATH&#39;, True) or &#39;&#39;).split(&#39;:&#39;)
        machine = d.getVar(&#39;MACHINE&#39;, True)
        for p in fpaths:
            if os.path.basename(p) == machine and os.path.isdir(p):
                paths.append(p)

        if len(paths) != 0:
            for s in srcuri.split():
                if not s.startswith(&quot;file://&quot;):
                    continue
                fetcher = bb.fetch2.Fetch([s], d)
                local = fetcher.localpath(s)
                for mp in paths:
                    if local.startswith(mp):
                        #bb.note(&quot;overriding PACKAGE_ARCH from %s to %s for %s&quot; % (pkg_arch, mach_arch, pn))
                        d.setVar(&#39;PACKAGE_ARCH&#39;, &quot;qemuarm&quot;)
                        return

    packages = d.getVar(&#39;PACKAGES&#39;, True).split()
    for pkg in packages:
        pkgarch = d.getVar(&quot;PACKAGE_ARCH_%s&quot; % pkg, True)

        # We could look for != PACKAGE_ARCH here but how to choose
        # if multiple differences are present?
        # Look through PACKAGE_ARCHS for the priority order?
        if pkgarch and pkgarch == mach_arch:
            d.setVar(&#39;PACKAGE_ARCH&#39;, &quot;qemuarm&quot;)
            bb.warn(&quot;Recipe %s is marked as only being architecture specific but seems to have machine specific packages?! The recipe may as well mark itself as machine specific directly.&quot; % d.getVar(&quot;PN&quot;, True))
 which triggered exception FetchError: Fetcher failure: SRCREV was used yet no valid SCM was found in SRC_URI
</pre></div><div><br></div></div>